Merge binary repos
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..766d224
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,27 @@
+#
+# NOTE! Please use 'git ls-files -i --exclude-standard'
+# command after changing this file, to see if there are
+# any tracked files which get ignored after the change.
+#
+
+# Standard ignores
+*.a
+*.la
+*.lo
+*.o
+*.pyc
+*.so
+*.cmd
+*.swp
+*.tgz
+*.ko
+*.mod.c
+*~
+
+# Ignore DEPS
+build
+wlan_src/.tmp_versions
+wlan_src/Module.markers
+wlan_src/Module.symvers
+wlan_src/modules.order
+io/sdio/syskt/modules.order
diff --git a/FwImage/sd8787.bin b/FwImage/sd8787.bin
new file mode 100644
index 0000000..4041ece
--- /dev/null
+++ b/FwImage/sd8787.bin
Binary files differ
diff --git a/README.chromium b/README.chromium
index 1dd5f1f..ac39238 100644
--- a/README.chromium
+++ b/README.chromium
@@ -1,5 +1,4 @@
 URL: http://www.marvell.com
-
 Version: SD8787 v14.64.2.p47
 License: Marvell International Ltd.
 License File: sd8787_license.txt
diff --git a/bt_src/Makefile b/bt_src/Makefile
new file mode 100755
index 0000000..5f8f7d5
--- /dev/null
+++ b/bt_src/Makefile
@@ -0,0 +1,144 @@
+# File: Makefile
+# Copyright (C) 2007-2008, Marvell International Ltd.
+#
+
+CC=		$(CROSS_COMPILE)gcc
+LD=		$(CROSS_COMPILE)ld
+
+BACKUP=		/root/backup
+YMD=		`date +%Y%m%d%H%M`
+
+#############################################################################
+# Configuration Options
+#############################################################################
+
+# Debug Option
+# DEBUG LEVEL n/1:
+# n: NO DEBUG
+# 1: PRINTM(MSG,...), PRINTM(FATAL,...), PRINTM(WARN,...) and PRINTM(INFO,...)
+CONFIG_DEBUG=1
+
+CONFIG_PXA3XX_DMA_ALIGN=y
+
+#############################################################################
+# Select Platform Tools
+#############################################################################
+
+MODEXT = ko
+
+# KERNELDIR point to the installed kernel directory
+# for PXA3XX BSP. 
+# KERNELDIR can be set on the command line 
+# make KERNELDIR=/usr/src/arm/<arch-bsp-path>
+# Alternatively KERNELDIR can be set in the environment.
+# Default value for KERNELDIR is set below.
+KERNELDIR ?= /usr/src/arm/linux-2.6.25-pxa9xx
+
+# CROSS_COMPILE specify the prefix used for all executables used
+# during compilation. Only gcc and related bin-utils executables
+# CROSS_COMPILE can be set on the command line 
+# make CROSS_COMPILE=</usr/local/arm/4.1.1/bin/>arm-linux-
+# Alternatively CROSS_COMPILE can be set in the environment.
+# Default value for CROSS_COMPILE is set below.
+CROSS_COMPILE ?= /usr/local/arm/4.1.1/bin/arm-linux-
+
+# INSTALLDIR specify the path to install the kernel module after
+# succesful compilation.
+# INSTALLDIR can be set on the command line 
+# make INSTALLDIR=/tftpboot/<rootfs>
+# Alternatively INSTALLDIR can be set in the environment.
+# Default value for INSTALL is set below.
+INSTALLDIR ?= /tftpboot/pxa3xx/root
+
+# ARCH specifies the architecture of the target processor, this kernel
+# module will run.
+# ARCH can be set on the command line
+# make ARCH=<arm/i386>
+# Alternatively ARCH can be set in the environment
+# Default values of ARCH for specific platform are set below.
+ARCH ?= arm
+
+
+
+EXTRA_CFLAGS += -I$(KERNELDIR)/include
+EXTRA_CFLAGS += -I$(PWD)/bt
+LD += -S
+
+BINDIR = ../bin_sd8787_bt
+
+#############################################################################
+# Compiler Flags
+#############################################################################
+	EXTRA_CFLAGS += -DFPNUM='"64"'
+
+ifeq ($(CONFIG_DEBUG),1)
+	EXTRA_CFLAGS += -DDEBUG_LEVEL1
+endif
+
+ifeq ($(CONFIG_PXA3XX_DMA_ALIGN),y)
+	EXTRA_CFLAGS += -DPXA3XX_DMA_ALIGN
+endif
+
+#############################################################################
+# Make Targets
+#############################################################################
+
+ifneq ($(KERNELRELEASE),)
+
+BTOBJS = bt/bt_main.o bt/bt_sdiommc.o bt/bt_proc.o
+
+obj-m := bt8xxx.o
+bt8xxx-objs := $(BTOBJS)
+
+
+
+# Otherwise we were called directly from the command line; invoke the kernel build system.
+else
+default:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
+endif
+
+###############################################################
+
+export		CC LD EXTRA_CFLAGS KERNELDIR
+
+echo:
+
+build:		echo default
+
+	@if [ ! -d $(BINDIR) ]; then \
+		mkdir $(BINDIR); \
+	fi
+	cp -f bt8xxx.$(MODEXT) $(BINDIR)/bt8787.$(MODEXT)
+
+
+	cp -f README $(BINDIR)
+
+clean:
+	-find . -name "*.o" -exec rm {} \;
+	-find . -name "*.ko" -exec rm {} \;
+	-find . -name ".*.cmd" -exec rm {} \;
+	-find . -name "*.mod.c" -exec rm {} \;
+	-find . -name "*.symvers" -exec rm {} \;
+	-find . -name "modules.order" -exec rm {} \;
+	-rm -rf .tmp_versions
+
+
+
+install: default
+
+distclean:
+	-find . -name "*.o" -exec rm {} \;
+	-find . -name "*.orig" -exec rm {} \;
+	-find . -name "*.swp" -exec rm {} \;
+	-find . -name "*.*~" -exec rm {} \;
+	-find . -name "*~" -exec rm {} \;
+	-find . -name "*.d" -exec rm {} \;
+	-find . -name "*.a" -exec rm {} \;
+	-find . -name "tags" -exec rm {} \;
+	-find . -name ".*" -exec rm -rf 2> /dev/null \;
+	-find . -name "*.ko" -exec rm {} \;
+	-find . -name ".*.cmd" -exec rm {} \;
+	-find . -name "*.mod.c" -exec rm {} \;
+	-rm -rf .tmp_versions
+# End of file;
diff --git a/bt_src/README b/bt_src/README
new file mode 100755
index 0000000..203faaf
--- /dev/null
+++ b/bt_src/README
@@ -0,0 +1,104 @@
+===============================================================================

+			U S E R  M A N U A L

+

+ Copyright (C) 2003-2008, Marvell International Ltd. 

+

+ This software file (the "File") is distributed by Marvell International 

+ Ltd. under the terms of the GNU General Public License Version 2, June 1991 

+ (the "License").  You may use, redistribute and/or modify this File in 

+ accordance with the terms and conditions of the License, a copy of which 

+ is available along with the File in the gpl.txt file or by writing to 

+ the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 

+ 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.

+

+ THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 

+ IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 

+ ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 

+ this warranty disclaimer.

+

+===============================================================================

+

+1) FOR DRIVER BUILD

+

+	Goto source code directory src_xxxx.

+		make [clean] build

+	The driver binaries can be found in ../bin_xxxx_bt directory.

+

+2) FOR DRIVER INSTALL

+

+	a) Copy sd8790.bin | sd8787.bin | ... to /lib/firmware/mrvl/ directory, 

+	   create the directory if it doesn't exist.

+	b) Install bluetooth driver,

+		insmod bt8688.ko | bt8790.ko | ...

+	c) Uninstall bluetooth driver and sdio bus driver,

+		hciconfig hciX down

+		rmmod bt8xxx

+

+3) cat /proc/mbt/hcix/config

+   This command is used to get the current driver settings. 

+

+4) cat /proc/mbt/hcix/status

+   This command is used to get driver status

+

+5) proc commands to config bluetooth parameters. 

+

+drvdbg=[n]

+   This command is used to set the bit masks of driver debug message control.

+

+   	bit 0:  MSG  		PRINTM(MSG,...)

+	bit 1:  FATAL		PRINTM(FATAL,...)

+	bit 2:  ERROR		PRINTM(ERROR,...)

+	bit 3:  CMD  		PRINTM(CMD,...)

+	bit 27: DATA 		DBG_HEXDUMP(DBG_DATA,...)

+	bit 28: ENTRY		PRINTM(ENTRY,...), ENTER(), LEAVE()

+	bit 29: WARN 		PRINTM(WARN,...)

+	bit 30: INFO 		PRINTM(INFO,...)

+

+	Usage:

+		echo "drvdbg=0x7" > /proc/mbt/hcix/config		#enable MSG,FATAL,ERROR messages

+

+gpio_gap=[n]

+   This command is used to configure the host sleep parameters.

+	bit 8:0  -- Gap

+	bit 16:8 -- GPIO

+

+	where GPIO is the pin number of GPIO used to wakeup the host. It could be any valid

+		GPIO pin# (e.g. 0-7) or 0xff (Interface, e.g. SDIO will be used instead).

+		

+	where Gap is the gap in milli seconds between wakeup signal and wakeup event 

+		or 0xff for special setting.

+	Usage:

+		echo "gpio_gap=0xff80" > /proc/mbt/hcix/config   	# use Interface (e.g. SDIO)

+		echo "hscfgcmd=1" > /proc/mbt/hcix/config		# gap = 0x80

+

+		echo "gpio_gap=0x03ff" > /proc/mbt/hcix/config   	# use gpio 3

+		echo "hscfgcmd=1" > /proc/mbt/hcix/config		# and special host sleep mode

+

+psmode=[n]

+    This command is used to enable/disable auto sleep mode

+	

+	where the option is:

+			1 	-- Enable auto sleep mode

+			0 	-- Disable auto sleep mode

+	Usage:

+		echo "psmode=1" > /proc/mbt/hcix/config			#enable power save mode

+		echo "pscmd=1" > /proc/mbt/hcix/config

+

+		echo "psmode=0" > /proc/mbt/hcix/config			#disable power save mode

+		echo "pscmd=1" > /proc/mbt/hcix/config

+		

+						

+

+6)Use hcitool to issue raw hci command, refer to hcitool manual

+

+	Usage: Hcitool cmd <ogf> <ocf> [Parameters]

+

+	1.Interface Control Command

+	  hcitool cmd 0x3f 0x5b 0xf5 0x01 0x00    --Enable All interface

+	  hcitool cmd 0x3f 0x5b 0xf5 0x01 0x01    --Enable Wlan interface

+	  hcitool cmd 0x3f 0x5b 0xf5 0x01 0x02    --Enable BT interface

+	  hcitool cmd 0x3f 0x5b 0xf5 0x00 0x00    --Disable All interface

+	  hcitool cmd 0x3f 0x5b 0xf5 0x00 0x01    --Disable Wlan interface

+	  hcitool cmd 0x3f 0x5b 0xf5 0x00 0x02    --Disable BT interface		

+

+==============================================================================

diff --git a/bt_src/bt/bt_drv.h b/bt_src/bt/bt_drv.h
new file mode 100755
index 0000000..825a1a0
--- /dev/null
+++ b/bt_src/bt/bt_drv.h
@@ -0,0 +1,435 @@
+/** @file bt_drv.h
+ *  @brief This header file contains global constant/enum definitions,
+ *  global variable declaration.
+ *       
+ *  Copyright (C) 2007-2008, Marvell International Ltd.
+ *
+ *  This software file (the "File") is distributed by Marvell International 
+ *  Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ *  (the "License").  You may use, redistribute and/or modify this File in 
+ *  accordance with the terms and conditions of the License, a copy of which 
+ *  is available along with the File in the gpl.txt file or by writing to 
+ *  the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
+ *  02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+ *
+ *  THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ *  ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ *  this warranty disclaimer.
+ *
+ */
+
+#ifndef _BT_DRV_H_
+#define _BT_DRV_H_
+
+#ifndef BIT
+/** BIT definition */
+#define BIT(x) (1UL << (x))
+#endif
+
+/** Debug level : Message */
+#define	DBG_MSG			BIT(0)
+/** Debug level : Fatal */
+#define DBG_FATAL		BIT(1)
+/** Debug level : Error */
+#define DBG_ERROR		BIT(2)
+/** Debug level : Command */
+#define DBG_CMD			BIT(3)
+/** Debug level : Data */
+#define DBG_DATA		BIT(27)
+/** Debug level : Entry */
+#define DBG_ENTRY		BIT(28)
+/** Debug level : Warning */
+#define DBG_WARN		BIT(29)
+/** Debug level : Informative */
+#define DBG_INFO		BIT(30)
+
+#ifdef	DEBUG_LEVEL1
+extern u32 drvdbg;
+
+/** Print informative message */
+#define	PRINTM_INFO(msg...)  do {if (drvdbg & DBG_INFO)  printk(KERN_DEBUG msg);} while(0)
+/** Print warning message */
+#define	PRINTM_WARN(msg...)  do {if (drvdbg & DBG_WARN)  printk(KERN_DEBUG msg);} while(0)
+/** Print entry message */
+#define	PRINTM_ENTRY(msg...) do {if (drvdbg & DBG_ENTRY) printk(KERN_DEBUG msg);} while(0)
+/** Print command message */
+#define	PRINTM_CMD(msg...)   do {if (drvdbg & DBG_CMD)   printk(KERN_DEBUG msg);} while(0)
+/** Print erro message */
+#define	PRINTM_ERROR(msg...) do {if (drvdbg & DBG_ERROR) printk(KERN_DEBUG msg);} while(0)
+/** Print fatal message */
+#define	PRINTM_FATAL(msg...) do {if (drvdbg & DBG_FATAL) printk(KERN_DEBUG msg);} while(0)
+/** Print message */
+#define	PRINTM_MSG(msg...)   do {if (drvdbg & DBG_MSG)   printk(KERN_ALERT msg);} while(0)
+
+/** Print message with required level */
+#define	PRINTM(level,msg...) PRINTM_##level(msg)
+
+/** Debug dump buffer length */
+#define DBG_DUMP_BUF_LEN 	64
+/** Maximum number of dump per line */
+#define MAX_DUMP_PER_LINE	16
+/** Maximum data dump length */
+#define MAX_DATA_DUMP_LEN	48
+
+static inline void
+hexdump(char *prompt, u8 * buf, int len)
+{
+    int i;
+    char dbgdumpbuf[DBG_DUMP_BUF_LEN];
+    char *ptr = dbgdumpbuf;
+
+    printk(KERN_DEBUG "%s: len=%d\n", prompt, len);
+    for (i = 1; i <= len; i++) {
+        ptr += sprintf(ptr, "%02x ", *buf);
+        buf++;
+        if (i % MAX_DUMP_PER_LINE == 0) {
+            *ptr = 0;
+            printk(KERN_DEBUG "%s\n", dbgdumpbuf);
+            ptr = dbgdumpbuf;
+        }
+    }
+    if (len % MAX_DUMP_PER_LINE) {
+        *ptr = 0;
+        printk(KERN_DEBUG "%s\n", dbgdumpbuf);
+    }
+}
+
+/** Debug hexdump of debug data */
+#define DBG_HEXDUMP_DBG_DATA(x,y,z)     do {if (drvdbg & DBG_DATA) hexdump(x,y,z);} while(0)
+
+/** Debug hexdump */
+#define	DBG_HEXDUMP(level,x,y,z)    DBG_HEXDUMP_##level(x,y,z)
+
+/** Mark entry point */
+#define	ENTER()			PRINTM(ENTRY, "Enter: %s, %s:%i\n", __FUNCTION__, \
+							__FILE__, __LINE__)
+/** Mark exit point */
+#define	LEAVE()			PRINTM(ENTRY, "Leave: %s, %s:%i\n", __FUNCTION__, \
+							__FILE__, __LINE__)
+#else
+/** Do nothing */
+#define	PRINTM(level,msg...) do {} while (0);
+/** Do nothing */
+#define DBG_HEXDUMP(level,x,y,z)    do {} while (0);
+/** Do nothing */
+#define	ENTER()  do {} while (0);
+/** Do nothing */
+#define	LEAVE()  do {} while (0);
+#endif /* DEBUG_LEVEL1 */
+
+/** Length of device name */
+#define DEV_NAME_LEN				32
+/** Bluetooth upload size */
+#define	BT_UPLD_SIZE				2312
+/** Bluetooth status success */
+#define BT_STATUS_SUCCESS			(0)
+/** Bluetooth status failure */
+#define BT_STATUS_FAILURE			(-1)
+
+#ifndef	TRUE
+/** True value */
+#define TRUE			1
+#endif
+#ifndef	FALSE
+/** False value */
+#define	FALSE			0
+#endif
+
+/** Set thread state */
+#define OS_SET_THREAD_STATE(x)		set_current_state(x)
+/** Time to wait until Host Sleep state change in millisecond */
+#define WAIT_UNTIL_HS_STATE_CHANGED 5000
+/** Time to wait cmd resp in millisecond */
+#define WAIT_UNTIL_CMD_RESP	    5000
+
+/** Sleep until a condition gets true or a timeout elapses */
+#define os_wait_interruptible_timeout(waitq, cond, timeout) \
+	wait_event_interruptible_timeout(waitq, cond, ((timeout) * HZ / 1000))
+
+typedef struct
+{
+    /** Task */
+    struct task_struct *task;
+    /** Queue */
+    wait_queue_head_t waitQ;
+    /** PID */
+    pid_t pid;
+    /** Private structure */
+    void *priv;
+} bt_thread;
+
+static inline void
+bt_activate_thread(bt_thread * thr)
+{
+        /** Record the thread pid */
+    thr->pid = current->pid;
+
+        /** Initialize the wait queue */
+    init_waitqueue_head(&thr->waitQ);
+}
+
+static inline void
+bt_deactivate_thread(bt_thread * thr)
+{
+    thr->pid = 0;
+    return;
+}
+
+static inline void
+bt_create_thread(int (*btfunc) (void *), bt_thread * thr, char *name)
+{
+    thr->task = kthread_run(btfunc, thr, "%s", name);
+}
+
+static inline int
+bt_terminate_thread(bt_thread * thr)
+{
+    /* Check if the thread is active or not */
+    if (!thr->pid)
+        return -1;
+
+    kthread_stop(thr->task);
+    return 0;
+}
+
+static inline void
+os_sched_timeout(u32 millisec)
+{
+    set_current_state(TASK_INTERRUPTIBLE);
+
+    schedule_timeout((millisec * HZ) / 1000);
+}
+
+#ifndef __ATTRIB_ALIGN__
+#define __ATTRIB_ALIGN__ __attribute__((aligned(4)))
+#endif
+
+#ifndef __ATTRIB_PACK__
+#define __ATTRIB_PACK__ __attribute__ ((packed))
+#endif
+/** Data structure for the Marvell Bluetooth device */
+typedef struct _bt_dev
+{
+        /** device name */
+    char name[DEV_NAME_LEN];
+        /** card pointer */
+    void *card;
+        /** IO port */
+    u32 ioport;
+    /** HCI device */
+    struct hci_dev *hcidev;
+
+    /** Tx download ready flag */
+    u8 tx_dnld_rdy;
+    /** Function */
+    u8 fn;
+    /** Rx unit */
+    u8 rx_unit;
+    /** Power Save mode */
+    u8 psmode;
+    /** Power Save command */
+    u8 pscmd;
+    /** Host Sleep mode */
+    u8 hsmode;
+    /** Host Sleep command */
+    u8 hscmd;
+    /** Low byte is gap, high byte is GPIO */
+    u16 gpio_gap;
+    /** Host Sleep configuration command */
+    u8 hscfgcmd;
+    /** Host Send Cmd Flag		 */
+    u8 sendcmdflag;
+    /** Device Type			*/
+    u8 devType;
+} bt_dev_t, *pbt_dev_t;
+
+typedef struct _bt_adapter
+{
+    /** Chip revision ID */
+    u8 chip_rev;
+    /** Surprise removed flag */
+    u8 SurpriseRemoved;
+    /** IRQ number */
+    int irq;
+    /** Interrupt counter */
+    u32 IntCounter;
+    /** Tx packet queue */
+    struct sk_buff_head tx_queue;
+    /** Power Save mode */
+    u8 psmode;
+    /** Power Save state */
+    u8 ps_state;
+    /** Host Sleep state */
+    u8 hs_state;
+    /** Number of wakeup tries */
+    u8 WakeupTries;
+    /** Host Sleep wait queue */
+    wait_queue_head_t cmd_wait_q __ATTRIB_ALIGN__;
+    /** Host Cmd complet state */
+    u8 cmd_complete;
+    /** last irq recv */
+    u8 irq_recv;
+    /** last irq processed */
+    u8 irq_done;
+    /** tx pending */
+    u32 skb_pending;
+} bt_adapter, *pbt_adapter;
+
+/** Private structure for the MV device */
+typedef struct _bt_private
+{
+    /** Bluetooth device */
+    bt_dev_t bt_dev;
+    /** Adapter */
+    bt_adapter *adapter;
+    /** Firmware helper */
+    const struct firmware *fw_helper;
+    /** Firmware */
+    const struct firmware *firmware;
+    /** Hotplug device */
+    struct device *hotplug_device;
+        /** thread to service interrupts */
+    bt_thread MainThread;
+    /** Proc directory entry */
+    struct proc_dir_entry *proc_entry;
+    /** Proc mbt directory entry */
+    struct proc_dir_entry *proc_mbt;
+    /** Driver lock */
+    spinlock_t driver_lock;
+    /** Driver lock flags */
+    ulong driver_flags;
+} bt_private, *pbt_private;
+
+/** Disable interrupt */
+#define OS_INT_DISABLE	spin_lock_irqsave(&priv->driver_lock, priv->driver_flags)
+/** Enable interrupt */
+#define	OS_INT_RESTORE	spin_unlock_irqrestore(&priv->driver_lock, priv->driver_flags); \
+			priv->driver_lock = SPIN_LOCK_UNLOCKED
+
+/** BT_AMP flag for device type */
+#define  HCI_BT_AMP			0x80
+/** Device type of AMP */
+#define DEV_TYPE_AMP			0x01
+/** Marvell vendor packet */
+#define MRVL_VENDOR_PKT			0xFE
+/** Bluetooth command : Sleep mode */
+#define BT_CMD_AUTO_SLEEP_MODE		0x23
+/** Bluetooth command : Host Sleep configuration */
+#define BT_CMD_HOST_SLEEP_CONFIG	0x59
+/** Bluetooth command : Host Sleep enable */
+#define BT_CMD_HOST_SLEEP_ENABLE	0x5A
+/** Bluetooth command : Module Configuration request */
+#define BT_CMD_MODULE_CFG_REQ		0x5B
+/** Sub Command: Module Bring Up Request */
+#define MODULE_BRINGUP_REQ		0xF1
+/** Sub Command: Module Shut Down Request */
+#define MODULE_SHUTDOWN_REQ		0xF2
+/** Module already up */
+#define MODULE_CFG_RESP_ALREADY_UP      0x0c
+/** Sub Command: Host Interface Control Request */
+#define MODULE_INTERFACE_CTRL_REQ	0xF5
+
+/** Bluetooth event : Power State */
+#define BT_EVENT_POWER_STATE		0x20
+
+/** Bluetooth Power State : Enable */
+#define BT_PS_ENABLE			0x02
+/** Bluetooth Power State : Disable */
+#define BT_PS_DISABLE			0x03
+/** Bluetooth Power State : Sleep */
+#define BT_PS_SLEEP			0x01
+/** Bluetooth Power State : Awake */
+#define BT_PS_AWAKE			0x02
+
+/** OGF */
+#define OGF				0x3F
+
+/** Host Sleep activated */
+#define HS_ACTIVATED			0x01
+/** Host Sleep deactivated */
+#define HS_DEACTIVATED			0x00
+
+/** Power Save sleep */
+#define PS_SLEEP			0x01
+/** Power Save awake */
+#define PS_AWAKE			0x00
+
+/** bt header length */
+#define BT_HEADER_LEN			4
+
+#ifndef MAX
+/** Return maximum of two */
+#define MAX(a,b)		((a) > (b) ? (a) : (b))
+#endif
+
+/** This is for firmware specific length */
+#define EXTRA_LEN	36
+
+/** Command buffer size for Marvell driver */
+#define MRVDRV_SIZE_OF_CMD_BUFFER       (2 * 1024)
+
+/** Bluetooth Rx packet buffer size for Marvell driver */
+#define MRVDRV_BT_RX_PACKET_BUFFER_SIZE \
+	(HCI_MAX_FRAME_SIZE + EXTRA_LEN)
+
+/** Buffer size to allocate */
+#define ALLOC_BUF_SIZE		(((MAX(MRVDRV_BT_RX_PACKET_BUFFER_SIZE, \
+					MRVDRV_SIZE_OF_CMD_BUFFER) + SDIO_HEADER_LEN \
+					+ SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE) * SD_BLOCK_SIZE)
+
+/** The number of times to try when polling for status bits */
+#define MAX_POLL_TRIES			100
+
+/** The number of times to try when waiting for downloaded firmware to 
+    become active when multiple interface is present */
+#define MAX_MULTI_INTERFACE_POLL_TRIES  1000
+
+/** The number of times to try when waiting for downloaded firmware to 
+     become active. (polling the scratch register). */
+#define MAX_FIRMWARE_POLL_TRIES		100
+
+typedef struct _BT_CMD
+{
+    /** OCF OGF */
+    u16 ocf_ogf;
+    /** Length */
+    u8 length;
+    /** Data */
+    u8 data[4];
+} __ATTRIB_PACK__ BT_CMD;
+
+typedef struct _BT_EVENT
+{
+    /** Event Counter */
+    u8 EC;
+    /** Length */
+    u8 length;
+    /** Data */
+    u8 data[4];
+} BT_EVENT;
+
+void check_evtpkt(bt_private * priv, struct sk_buff *skb);
+
+/* Prototype of global function */
+bt_private *bt_add_card(void *card);
+int bt_remove_card(void *card);
+void bt_interrupt(struct hci_dev *hdev);
+
+int bt_proc_init(bt_private * priv);
+void bt_proc_remove(bt_private * priv);
+int bt_process_event(bt_private * priv, struct sk_buff *skb);
+int bt_enable_hs(bt_private * priv);
+int bt_prepare_command(bt_private * priv);
+
+int *sbi_register(void);
+void sbi_unregister(void);
+int sbi_register_dev(bt_private * priv);
+int sbi_unregister_dev(bt_private * priv);
+int sbi_host_to_card(bt_private * priv, u8 * payload, u16 nb);
+int sbi_enable_host_int(bt_private * priv);
+int sbi_disable_host_int(bt_private * priv);
+int sbi_dowload_fw(bt_private * priv);
+int sbi_get_int_status(bt_private * priv, u8 * ireg);
+int sbi_wakeup_firmware(bt_private * priv);
+#endif /* _BT_DRV_H_ */
diff --git a/bt_src/bt/bt_main.c b/bt_src/bt/bt_main.c
new file mode 100755
index 0000000..64253f5
--- /dev/null
+++ b/bt_src/bt/bt_main.c
@@ -0,0 +1,868 @@
+/** @file bt_main.c
+  *  
+  * @brief This file contains the major functions in BlueTooth
+  * driver. It includes init, exit, open, close and main
+  * thread etc..
+  * 
+  * Copyright (C) 2007-2008, Marvell International Ltd. 
+  *   
+  * This software file (the "File") is distributed by Marvell International 
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+  * (the "License").  You may use, redistribute and/or modify this File in 
+  * accordance with the terms and conditions of the License, a copy of which 
+  * is available along with the File in the gpl.txt file or by writing to 
+  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
+  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+  * this warranty disclaimer.
+  *
+  */
+/**
+  * @mainpage M-BT Linux Driver
+  *
+  * @section overview_sec Overview
+  *
+  * The M-BT is a Linux reference driver for Marvell SDIO Bluetooth chipset.
+  * 
+  * @section copyright_sec Copyright
+  *
+  * Copyright (C) 2007-2008, Marvell International Ltd.
+  *
+  */
+#include "include.h"
+
+/** Version */
+#define VERSION "1.42"
+
+/** Driver version */
+char driver_version[] = "sd8787-" VERSION "-(" "FP" FPNUM ")" " ";
+
+/** Bluetooth device private structure */
+bt_private *btpriv = NULL;
+/** Firmware flag */
+int fw = 1;
+
+#ifdef	DEBUG_LEVEL1
+u32 drvdbg = DBG_MSG | DBG_FATAL | DBG_ERROR;
+#endif
+
+/** 
+ *  @brief This function verify the received event pkt
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param skb     A pointer to rx skb 
+ *  @return 	   N/A
+ */
+void
+check_evtpkt(bt_private * priv, struct sk_buff *skb)
+{
+    struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
+    struct hci_ev_cmd_complete *ec;
+    u16 opcode, ocf;
+    ENTER();
+    if (hdr->evt == HCI_EV_CMD_COMPLETE) {
+        ec = (struct hci_ev_cmd_complete *) (skb->data + HCI_EVENT_HDR_SIZE);
+        opcode = __le16_to_cpu(ec->opcode);
+        ocf = hci_opcode_ocf(opcode);
+        if ((ocf == BT_CMD_MODULE_CFG_REQ) &&
+            (priv->bt_dev.sendcmdflag == TRUE)) {
+            priv->bt_dev.sendcmdflag = FALSE;
+            priv->adapter->cmd_complete = TRUE;
+            wake_up_interruptible(&priv->adapter->cmd_wait_q);
+        }
+    }
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function verify the received acl loopback pkt
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param skb     A pointer to rx skb 
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+bt_process_event(bt_private * priv, struct sk_buff *skb)
+{
+    u8 ret = BT_STATUS_SUCCESS;
+    BT_EVENT *pEvent;
+    ENTER();
+    pEvent = (BT_EVENT *) skb->data;
+    if (pEvent->EC != 0xff) {
+        PRINTM(CMD, "Not Marvell Event=%x\n", pEvent->EC);
+        ret = BT_STATUS_FAILURE;
+        goto exit;
+    }
+    switch (pEvent->data[0]) {
+    case BT_CMD_AUTO_SLEEP_MODE:
+        if (pEvent->data[2] == BT_STATUS_SUCCESS) {
+            if (pEvent->data[1] == BT_PS_ENABLE)
+                priv->adapter->psmode = 1;
+            else
+                priv->adapter->psmode = 0;
+            PRINTM(CMD, "PS Mode:%s\n",
+                   (priv->adapter->psmode) ? "Enable" : "Disable");
+        } else
+            PRINTM(CMD, "PS Mode Command Fail\n");
+        break;
+    case BT_CMD_HOST_SLEEP_CONFIG:
+        if (pEvent->data[3] == BT_STATUS_SUCCESS) {
+            PRINTM(CMD, "gpio=%x,gap=%x\n", pEvent->data[1], pEvent->data[2]);
+        } else
+            PRINTM(CMD, "HSCFG Command Fail\n");
+        break;
+    case BT_CMD_HOST_SLEEP_ENABLE:
+        if (pEvent->data[1] == BT_STATUS_SUCCESS) {
+            priv->adapter->hs_state = HS_ACTIVATED;
+            if (priv->adapter->psmode)
+                priv->adapter->ps_state = PS_SLEEP;
+            wake_up_interruptible(&priv->adapter->cmd_wait_q);
+            PRINTM(CMD, "HS ACTIVATED!\n");
+        } else
+            PRINTM(CMD, "HS Enable Fail\n");
+        break;
+    case BT_CMD_MODULE_CFG_REQ:
+        if ((priv->bt_dev.sendcmdflag == TRUE) &&
+            ((pEvent->data[1] == MODULE_BRINGUP_REQ)
+             || (pEvent->data[1] == MODULE_SHUTDOWN_REQ))) {
+            if (pEvent->data[1] == MODULE_BRINGUP_REQ) {
+                PRINTM(CMD, "EVENT:%s\n",
+                       (pEvent->data[2] &&
+                        (pEvent->data[2] !=
+                         MODULE_CFG_RESP_ALREADY_UP)) ? "Bring up Fail" :
+                       "Bring up success");
+                priv->bt_dev.devType = pEvent->data[3];
+                PRINTM(CMD, "devType:%s\n",
+                       (pEvent->data[3] ==
+                        1) ? "AMP controller" : "BR/EDR controller");
+
+            }
+            if (pEvent->data[1] == MODULE_SHUTDOWN_REQ) {
+                PRINTM(CMD, "EVENT:%s\n",
+                       (pEvent->
+                        data[2]) ? "Shut down Fail" : "Shut down success");
+            }
+            if (pEvent->data[2]) {
+                priv->bt_dev.sendcmdflag = FALSE;
+                priv->adapter->cmd_complete = TRUE;
+                wake_up_interruptible(&priv->adapter->cmd_wait_q);
+            }
+        } else {
+            PRINTM(CMD, "BT_CMD_MODULE_CFG_REQ resp for APP\n");
+            ret = BT_STATUS_FAILURE;
+        }
+        break;
+    case BT_EVENT_POWER_STATE:
+        if (pEvent->data[1] == BT_PS_SLEEP)
+            priv->adapter->ps_state = PS_SLEEP;
+        PRINTM(CMD, "EVENT:%s\n",
+               (priv->adapter->ps_state) ? "PS_SLEEP" : "PS_AWAKE");
+        break;
+    default:
+        PRINTM(CMD, "Unknown Event=%d\n", pEvent->data[0]);
+        ret = BT_STATUS_FAILURE;
+        break;
+    }
+  exit:
+    if (ret == BT_STATUS_SUCCESS)
+        kfree_skb(skb);
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function send module cfg cmd to firmware
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param subcmd  sub command 
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+bt_send_module_cfg_cmd(bt_private * priv, int subcmd)
+{
+    struct sk_buff *skb = NULL;
+    u8 ret = BT_STATUS_SUCCESS;
+    BT_CMD *pCmd;
+    ENTER();
+    skb = bt_skb_alloc(sizeof(BT_CMD), GFP_ATOMIC);
+    if (skb == NULL) {
+        PRINTM(WARN, "No free skb\n");
+        ret = BT_STATUS_FAILURE;
+        goto exit;
+    }
+    pCmd = (BT_CMD *) skb->tail;
+    pCmd->ocf_ogf = (OGF << 10) | BT_CMD_MODULE_CFG_REQ;
+    pCmd->length = 1;
+    pCmd->data[0] = subcmd;
+    bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+    skb_put(skb, sizeof(BT_CMD));
+    skb->dev = (void *) priv->bt_dev.hcidev;
+    skb_queue_head(&priv->adapter->tx_queue, skb);
+    priv->bt_dev.sendcmdflag = TRUE;
+    priv->adapter->cmd_complete = FALSE;
+    PRINTM(CMD, "Queue module cfg Command\n");
+    wake_up_interruptible(&priv->MainThread.waitQ);
+    /* 
+       On some Adroind platforms certain delay is needed for HCI daemon to
+       remove this module and close itself gracefully. Otherwise it hangs. This 
+       10ms delay is a workaround for such platforms as the root cause has not
+       been found yet. */
+    mdelay(10);
+    if (!os_wait_interruptible_timeout
+        (priv->adapter->cmd_wait_q, priv->adapter->cmd_complete,
+         WAIT_UNTIL_CMD_RESP)) {
+        ret = BT_STATUS_FAILURE;
+        PRINTM(MSG, "module_cfg_cmd(%x): timeout sendcmdflag=%d\n", subcmd,
+               priv->bt_dev.sendcmdflag);
+    }
+    PRINTM(CMD, "module cfg Command done\n");
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function enable host sleep 
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+bt_enable_hs(bt_private * priv)
+{
+    struct sk_buff *skb = NULL;
+    u8 ret = BT_STATUS_SUCCESS;
+    BT_CMD *pCmd;
+    ENTER();
+    skb = bt_skb_alloc(sizeof(BT_CMD), GFP_ATOMIC);
+    if (skb == NULL) {
+        PRINTM(WARN, "No free skb\n");
+        ret = BT_STATUS_FAILURE;
+        goto exit;
+    }
+    pCmd = (BT_CMD *) skb->tail;
+    pCmd->ocf_ogf = (OGF << 10) | BT_CMD_HOST_SLEEP_ENABLE;
+    pCmd->length = 0;
+    bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+    skb_put(skb, sizeof(BT_CMD));
+    skb->dev = (void *) priv->bt_dev.hcidev;
+    skb_queue_head(&priv->adapter->tx_queue, skb);
+    PRINTM(CMD, "Queue hs enable Command\n");
+    wake_up_interruptible(&priv->MainThread.waitQ);
+    if (!os_wait_interruptible_timeout
+        (priv->adapter->cmd_wait_q, priv->adapter->hs_state,
+         WAIT_UNTIL_HS_STATE_CHANGED)) {
+        ret = BT_STATUS_FAILURE;
+        PRINTM(MSG, "bt_enable_hs: timeout: %d, %d,%d\n",
+               priv->adapter->hs_state, priv->adapter->ps_state,
+               priv->adapter->WakeupTries);
+    }
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function used to send command to firmware
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return        BT_STATUS_SUCCESS
+ */
+int
+bt_prepare_command(bt_private * priv)
+{
+    struct sk_buff *skb = NULL;
+    u8 ret = BT_STATUS_SUCCESS;
+    BT_CMD *pCmd;
+    ENTER();
+    if (priv->bt_dev.hscfgcmd) {
+        priv->bt_dev.hscfgcmd = 0;
+        skb = bt_skb_alloc(sizeof(BT_CMD), GFP_ATOMIC);
+        if (skb == NULL) {
+            PRINTM(WARN, "No free skb\n");
+            ret = BT_STATUS_FAILURE;
+            goto exit;
+        }
+        pCmd = (BT_CMD *) skb->tail;
+        pCmd->ocf_ogf = (OGF << 10) | BT_CMD_HOST_SLEEP_CONFIG;
+        pCmd->length = 2;
+        pCmd->data[0] = (priv->bt_dev.gpio_gap & 0xff00) >> 8;
+        pCmd->data[1] = (u8) (priv->bt_dev.gpio_gap & 0x00ff);
+        bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+        skb_put(skb, sizeof(BT_CMD));
+        skb->dev = (void *) priv->bt_dev.hcidev;
+        skb_queue_head(&priv->adapter->tx_queue, skb);
+        PRINTM(CMD, "Queue HSCFG Command,gpio=%x,gap=%x\n", pCmd->data[0],
+               pCmd->data[1]);
+    }
+    if (priv->bt_dev.pscmd) {
+        priv->bt_dev.pscmd = 0;
+        skb = bt_skb_alloc(sizeof(BT_CMD), GFP_ATOMIC);
+        if (skb == NULL) {
+            PRINTM(WARN, "No free skb\n");
+            ret = BT_STATUS_FAILURE;
+            goto exit;
+        }
+        pCmd = (BT_CMD *) skb->tail;
+        pCmd->ocf_ogf = (OGF << 10) | BT_CMD_AUTO_SLEEP_MODE;
+        pCmd->length = 1;
+        if (priv->bt_dev.psmode)
+            pCmd->data[0] = BT_PS_ENABLE;
+        else
+            pCmd->data[0] = BT_PS_DISABLE;
+        bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+        skb_put(skb, sizeof(BT_CMD));
+        skb->dev = (void *) priv->bt_dev.hcidev;
+        skb_queue_head(&priv->adapter->tx_queue, skb);
+        PRINTM(CMD, "Queue PSMODE Command:%d\n", pCmd->data[0]);
+    }
+    if (priv->bt_dev.hscmd) {
+        priv->bt_dev.hscmd = 0;
+        if (priv->bt_dev.hsmode)
+            ret = bt_enable_hs(priv);
+        else {
+            ret = sbi_wakeup_firmware(priv);
+            priv->adapter->hs_state = HS_DEACTIVATED;
+        }
+    }
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/**  @brief This function processes a single packet 
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param skb     A pointer to skb which includes TX packet
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static int
+SendSinglePacket(bt_private * priv, struct sk_buff *skb)
+{
+    u8 ret;
+    ENTER();
+    if (!skb || !skb->data)
+        return BT_STATUS_FAILURE;
+    if (!skb->len || ((skb->len + BT_HEADER_LEN) > BT_UPLD_SIZE)) {
+        PRINTM(ERROR, "Tx Error: Bad skb length %d : %d\n", skb->len,
+               BT_UPLD_SIZE);
+        return BT_STATUS_FAILURE;
+    }
+    /* This is SDIO specific header length: byte[3][2][1], type: byte[0]
+       (HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor) */
+    skb_push(skb, BT_HEADER_LEN);
+    skb->data[0] = (skb->len & 0x0000ff);
+    skb->data[1] = (skb->len & 0x00ff00) >> 8;
+    skb->data[2] = (skb->len & 0xff0000) >> 16;
+    skb->data[3] = bt_cb(skb)->pkt_type;
+    ret = sbi_host_to_card(priv, skb->data, skb->len);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function initializes the adapter structure
+ *  and set default value to the member of adapter.
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   n/a
+ */
+static void
+bt_init_adapter(bt_private * priv)
+{
+    ENTER();
+    skb_queue_head_init(&priv->adapter->tx_queue);
+    priv->adapter->ps_state = PS_AWAKE;
+    init_waitqueue_head(&priv->adapter->cmd_wait_q);
+    LEAVE();
+}
+
+/** 
+ *  @brief This function initializes firmware
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static int
+bt_init_fw(bt_private * priv)
+{
+    int ret = BT_STATUS_SUCCESS;
+    ENTER();
+    if (fw == 0) {
+        sbi_enable_host_int(priv);
+        goto done;
+    }
+    sbi_disable_host_int(priv);
+    if (sbi_dowload_fw(priv)) {
+        PRINTM(ERROR, "FW failed to be download!\n");
+        ret = BT_STATUS_FAILURE;
+        goto done;
+    }
+    mdelay(100);
+    sbi_enable_host_int(priv);
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function frees the structure of adapter
+ *    
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   n/a
+ */
+static void
+bt_free_adapter(bt_private * priv)
+{
+    bt_adapter *Adapter = priv->adapter;
+    ENTER();
+    skb_queue_purge(&priv->adapter->tx_queue);
+    /* Free the adapter object itself */
+    kfree(Adapter);
+    priv->adapter = NULL;
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function handle the ioctl 
+ *  
+ *  @param hev     A pointer to hci_dev structure
+ *  @cmd	   ioctl cmd 
+ *  @arg	    
+ *  @return 	   -ENOIOCTLCMD
+ */
+static int
+bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
+{
+    ENTER();
+    LEAVE();
+    return -ENOIOCTLCMD;
+}
+
+/** 
+ *  @brief This function handle destruct 
+ *  
+ *  @param hev     A pointer to hci_dev structure
+ *  
+ *  @return 	   n/a
+ */
+static void
+bt_destruct(struct hci_dev *hdev)
+{
+    ENTER();
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function handle the transmit
+ *  
+ *  @param skb     A pointer to sk_buffer structure
+ *  
+ *  @return 	   BT_STATUS_SUCCESS or other   
+ */
+static int
+bt_send_frame(struct sk_buff *skb)
+{
+    struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+    bt_private *priv = NULL;
+
+    ENTER();
+    PRINTM(INFO, "bt_send_frame: Type=%d, len=%d\n", skb->pkt_type, skb->len);
+    DBG_HEXDUMP(DBG_DATA, "bt_send_frame", skb->data, skb->len);
+    if (!hdev || !hdev->driver_data) {
+        PRINTM(ERROR, "Frame for unknown HCI device (hdev=NULL)\n");
+        LEAVE();
+        return -ENODEV;
+    }
+    priv = (bt_private *) hdev->driver_data;
+    if (!test_bit(HCI_RUNNING, &hdev->flags)) {
+        PRINTM(ERROR, "Fail test HCI_RUNING,flag=%lx\n", hdev->flags);
+        LEAVE();
+        return -EBUSY;
+    }
+    switch (bt_cb(skb)->pkt_type) {
+    case HCI_COMMAND_PKT:
+        hdev->stat.cmd_tx++;
+        break;
+    case HCI_ACLDATA_PKT:
+        hdev->stat.acl_tx++;
+        break;
+    case HCI_SCODATA_PKT:
+        hdev->stat.sco_tx++;
+        break;
+    }
+    skb_queue_tail(&priv->adapter->tx_queue, skb);
+    wake_up_interruptible(&priv->MainThread.waitQ);
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function flush the transmit queue
+ *  
+ *  @param hev     A pointer to hci_dev structure
+ *  
+ *  @return 	   BT_STATUS_SUCCESS   
+ */
+static int
+bt_flush(struct hci_dev *hdev)
+{
+    bt_private *priv = (bt_private *) hdev->driver_data;
+    ENTER();
+    skb_queue_purge(&priv->adapter->tx_queue);
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function close the bluetooth device
+ *  
+ *  @param hev     A pointer to hci_dev structure
+ *  
+ *  @return 	   BT_STATUS_SUCCESS   
+ */
+static int
+bt_close(struct hci_dev *hdev)
+{
+    bt_private *priv = (bt_private *) hdev->driver_data;
+    ENTER();
+    if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) {
+        LEAVE();
+        return BT_STATUS_SUCCESS;
+    }
+    skb_queue_purge(&priv->adapter->tx_queue);
+    module_put(THIS_MODULE);
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function open the bluetooth device
+ *  
+ *  @param hev     A pointer to hci_dev structure
+ *  
+ *  @return 	   BT_STATUS_SUCCESS  or other
+ */
+static int
+bt_open(struct hci_dev *hdev)
+{
+    ENTER();
+    if (try_module_get(THIS_MODULE) == 0)
+        return BT_STATUS_FAILURE;
+    set_bit(HCI_RUNNING, &hdev->flags);
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the major job in bluetooth driver.
+ *  it handles the event generated by firmware, rx data received
+ *  from firmware and tx data sent from kernel.
+ *  
+ *  @param data    A pointer to bt_thread structure
+ *  @return        BT_STATUS_SUCCESS
+ */
+static int
+bt_service_main_thread(void *data)
+{
+    bt_thread *thread = data;
+    bt_private *priv = thread->priv;
+    bt_adapter *Adapter = priv->adapter;
+    wait_queue_t wait;
+    u8 ireg = 0;
+    struct sk_buff *skb;
+    ENTER();
+    bt_activate_thread(thread);
+    init_waitqueue_entry(&wait, current);
+    current->flags |= PF_NOFREEZE;
+
+    for (;;) {
+        add_wait_queue(&thread->waitQ, &wait);
+        OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE);
+        if (priv->adapter->WakeupTries ||
+            ((!priv->adapter->IntCounter) &&
+             (!priv->bt_dev.tx_dnld_rdy ||
+              skb_queue_empty(&priv->adapter->tx_queue)))) {
+            PRINTM(INFO, "Main: Thread sleeping...\n");
+            schedule();
+        }
+        OS_SET_THREAD_STATE(TASK_RUNNING);
+        remove_wait_queue(&thread->waitQ, &wait);
+        if (kthread_should_stop() || Adapter->SurpriseRemoved) {
+            PRINTM(INFO, "main-thread: break from main thread: "
+                   "SurpriseRemoved=0x%x\n", Adapter->SurpriseRemoved);
+            break;
+        }
+
+        PRINTM(INFO, "Main: Thread waking up...\n");
+        if (priv->adapter->IntCounter) {
+            OS_INT_DISABLE;
+            Adapter->IntCounter = 0;
+            OS_INT_RESTORE;
+            sbi_get_int_status(priv, &ireg);
+        } else if ((priv->adapter->ps_state == PS_SLEEP) &&
+                   !skb_queue_empty(&priv->adapter->tx_queue)) {
+            priv->adapter->WakeupTries++;
+            sbi_wakeup_firmware(priv);
+            continue;
+        }
+        if (priv->adapter->ps_state == PS_SLEEP)
+            continue;
+        if (priv->bt_dev.tx_dnld_rdy == TRUE) {
+            if (!skb_queue_empty(&priv->adapter->tx_queue)) {
+                skb = skb_dequeue(&priv->adapter->tx_queue);
+                if (skb) {
+                    if (SendSinglePacket(priv, skb))
+                        priv->bt_dev.hcidev->stat.err_tx++;
+                    else
+                        priv->bt_dev.hcidev->stat.byte_tx += skb->len;
+                    kfree_skb(skb);
+                }
+            }
+        }
+    }
+    bt_deactivate_thread(thread);
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the interrupt. it will change PS
+ *  state if applicable. it will wake up main_thread to handle
+ *  the interrupt event as well.
+ *  
+ *  @param hdev    A pointer to hci_dev structure
+ *  @return        n/a
+ */
+void
+bt_interrupt(struct hci_dev *hdev)
+{
+    bt_private *priv = (bt_private *) hdev->driver_data;
+    ENTER();
+    priv->adapter->ps_state = PS_AWAKE;
+    priv->adapter->hs_state = HS_DEACTIVATED;
+    priv->adapter->WakeupTries = 0;
+    priv->adapter->IntCounter++;
+    wake_up_interruptible(&priv->MainThread.waitQ);
+    LEAVE();
+
+}
+
+/**
+ * @brief This function adds the card. it will probe the
+ * card, allocate the bt_priv and initialize the device. 
+ *  
+ *  @param card    A pointer to card
+ *  @return        A pointer to bt_private structure
+ */
+
+bt_private *
+bt_add_card(void *card)
+{
+    struct hci_dev *hdev = NULL;
+    bt_private *priv = NULL;
+    int ret;
+
+    ENTER();
+
+    priv = kzalloc(sizeof(bt_private), GFP_KERNEL);
+    if (!priv) {
+        PRINTM(FATAL, "Can not allocate priv\n");
+        LEAVE();
+        return NULL;
+    }
+    /* allocate buffer for bt_adapter */
+    if (!(priv->adapter = kzalloc(sizeof(bt_adapter), GFP_KERNEL))) {
+        PRINTM(FATAL, "Allocate buffer for bt_adapter failed!\n");
+        goto err_kmalloc;
+    }
+
+    bt_init_adapter(priv);
+
+    /* Register to HCI Core */
+    hdev = hci_alloc_dev();
+    if (!hdev) {
+        PRINTM(FATAL, "Can not allocate HCI device\n");
+        goto err_kmalloc;
+    }
+
+    PRINTM(INFO, "Starting kthread...\n");
+    priv->MainThread.priv = priv;
+    spin_lock_init(&priv->driver_lock);
+
+    bt_create_thread(bt_service_main_thread, &priv->MainThread,
+                     "bt_main_service");
+
+    /* wait for mainthread to up */
+    while (!priv->MainThread.pid) {
+        os_sched_timeout(1);
+    }
+    priv->bt_dev.hcidev = hdev;
+    priv->bt_dev.card = card;
+    btpriv = priv;
+    hdev->driver_data = priv;
+    ((struct sdio_mmc_card *) card)->priv = priv;
+    /* 
+     * Register the device. Fillup the private data structure with
+     * relevant information from the card and request for the required
+     * IRQ. 
+     */
+    if (sbi_register_dev(priv) < 0) {
+        PRINTM(FATAL, "Failed to register bt device!\n");
+        goto err_registerdev;
+    }
+    if (bt_init_fw(priv)) {
+        PRINTM(FATAL, "Firmware Init Failed\n");
+        goto err_init_fw;
+    }
+    priv->bt_dev.tx_dnld_rdy = TRUE;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
+    hdev->type = HCI_SDIO;
+#else
+    hdev->type = HCI_PCCARD;
+#endif
+
+    hdev->open = bt_open;
+    hdev->close = bt_close;
+    hdev->flush = bt_flush;
+    hdev->send = bt_send_frame;
+    hdev->destruct = bt_destruct;
+    hdev->ioctl = bt_ioctl;
+
+    hdev->owner = THIS_MODULE;
+    bt_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
+    priv->bt_dev.pscmd = TRUE;
+    priv->bt_dev.psmode = TRUE;
+    bt_prepare_command(priv);
+    wake_up_interruptible(&priv->MainThread.waitQ);
+    if (priv->bt_dev.devType == DEV_TYPE_AMP)
+        hdev->type |= HCI_BT_AMP;
+    ret = hci_register_dev(hdev);
+    if (ret < 0) {
+        PRINTM(FATAL, "Can not register HCI device\n");
+        goto err_init_fw;
+    }
+    bt_proc_init(priv);
+
+    LEAVE();
+    return priv;
+
+  err_init_fw:
+    sbi_unregister_dev(priv);
+  err_registerdev:
+    ((struct sdio_mmc_card *) card)->priv = NULL;
+    /* Stop the thread servicing the interrupts */
+    priv->adapter->SurpriseRemoved = TRUE;
+    wake_up_interruptible(&priv->MainThread.waitQ);
+    while (priv->MainThread.pid) {
+        os_sched_timeout(1);
+    }
+  err_kmalloc:
+    if (hdev)
+        hci_free_dev(hdev);
+    bt_free_adapter(priv);
+    kfree(priv);
+    btpriv = NULL;
+    LEAVE();
+    return NULL;
+}
+
+/** 
+ *  @brief This function removes the card.
+ *  
+ *  @param card    A pointer to card
+ *  @return        BT_STATUS_SUCCESS
+ */
+
+int
+bt_remove_card(void *card)
+{
+    struct hci_dev *hdev;
+    bt_private *priv = ((struct sdio_mmc_card *) card)->priv;
+
+    ENTER();
+
+    if (!priv) {
+        LEAVE();
+        return BT_STATUS_SUCCESS;
+    }
+    hdev = priv->bt_dev.hcidev;
+    /* Disable interrupts on the card */
+    sbi_disable_host_int(priv);
+    wake_up_interruptible(&priv->adapter->cmd_wait_q);
+    priv->adapter->SurpriseRemoved = TRUE;
+    wake_up_interruptible(&priv->MainThread.waitQ);
+    while (priv->MainThread.pid) {
+        os_sched_timeout(1);
+    }
+    bt_proc_remove(priv);
+    PRINTM(INFO, "unregester dev\n");
+    sbi_unregister_dev(priv);
+
+    /* UnRegister to HCI Core */
+    if (hci_unregister_dev(hdev) < 0)
+        PRINTM(ERROR, "Can not unregister HCI device %s\n", hdev->name);
+    hci_free_dev(hdev);
+    priv->bt_dev.hcidev = NULL;
+    bt_free_adapter(priv);
+    kfree(priv);
+    btpriv = NULL;
+
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function initializes module.
+ *  
+ *  @param     n/a    A pointer to bt_private structure
+ *  @return        BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static int
+bt_init_module(void)
+{
+    int ret = BT_STATUS_SUCCESS;
+    ENTER();
+    if (sbi_register() == NULL) {
+        ret = BT_STATUS_FAILURE;
+        goto done;
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function cleans module
+ *  
+ *  @param priv    n/a
+ *  @return        n/a
+ */
+static void
+bt_exit_module(void)
+{
+    ENTER();
+    if (btpriv) {
+        bt_send_module_cfg_cmd(btpriv, MODULE_SHUTDOWN_REQ);
+        btpriv->adapter->SurpriseRemoved = TRUE;
+    }
+    sbi_unregister();
+    LEAVE();
+}
+
+module_init(bt_init_module);
+module_exit(bt_exit_module);
+
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_DESCRIPTION("Marvell Bluetooth Driver Ver. " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
+module_param(fw, int, 1);
+MODULE_PARM_DESC(fw, "0: Skip firmware download; otherwise: Download firmware");
diff --git a/bt_src/bt/bt_proc.c b/bt_src/bt/bt_proc.c
new file mode 100755
index 0000000..f38e738
--- /dev/null
+++ b/bt_src/bt/bt_proc.c
@@ -0,0 +1,479 @@
+/** @file bt_proc.c
+  *  
+  * @brief This file handle the functions for proc files
+  * 
+  * Copyright (C) 2007-2008, Marvell International Ltd.
+  *   
+  * This software file (the "File") is distributed by Marvell International 
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+  * (the "License").  You may use, redistribute and/or modify this File in 
+  * accordance with the terms and conditions of the License, a copy of which 
+  * is available along with the File in the gpl.txt file or by writing to 
+  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
+  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+  * this warranty disclaimer.
+  *
+  */
+
+#include "include.h"
+
+/** proc diretory root */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#define PROC_DIR NULL
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#define PROC_DIR &proc_root
+#else
+#define PROC_DIR proc_net
+#endif
+
+/** Driver version */
+extern char driver_version[];
+
+struct proc_data
+{
+    /** Read length */
+    int rdlen;
+    /** Read buffer */
+    char *rdbuf;
+    /** Write length */
+    int wrlen;
+    /** Maximum write length */
+    int maxwrlen;
+    /** Write buffer */
+    char *wrbuf;
+    void (*on_close) (struct inode *, struct file *);
+};
+
+struct item_data
+{
+    /** Name */
+    char name[32];
+    /** Size */
+    u32 size;
+    /** Address */
+    u32 addr;
+    /** Offset */
+    u32 offset;
+    /** Flag */
+    u32 flag;
+};
+
+struct proc_private_data
+{
+    /** Name */
+    char name[32];
+    /** File flag */
+    u32 fileflag;
+    /** Buffer size */
+    u32 bufsize;
+    /** Number of items */
+    u32 num_items;
+    /** Item data */
+    struct item_data *pdata;
+    /** Private structure */
+    bt_private *pbt;
+    /** File operations */
+    struct file_operations *fops;
+};
+
+/** Default file permission */
+#define DEFAULT_FILE_PERM  0644
+
+/** Bluetooth device offset */
+#define OFFSET_BT_DEV		0x01
+/** Bluetooth adapter offset */
+#define OFFSET_BT_ADAPTER	0x02
+/** Show integer */
+#define SHOW_INT		0x10
+/** Show hex */
+#define SHOW_HEX		0x20
+/** Show string */
+#define SHOW_STRING		0x40
+
+/** Device size */
+#define item_dev_size(n) (sizeof ((bt_dev_t *)0)->n)
+/** Device address */
+#define item_dev_addr(n) ((u32) &((bt_dev_t *)0)->n)
+
+/** Adapter size */
+#define item_adapter_size(n) (sizeof ((bt_adapter *)0)->n)
+/** Adapter address */
+#define item_adapter_addr(n) ((u32) &((bt_adapter *)0)->n)
+static struct item_data config_items[] = {
+#ifdef	DEBUG_LEVEL1
+    {"drvdbg", sizeof(u32), (u32) & drvdbg, 0, SHOW_HEX}
+    ,
+#endif
+    {"psmode", item_dev_size(psmode), 0, item_dev_addr(psmode),
+     OFFSET_BT_DEV | SHOW_INT}
+    ,
+    {"pscmd", item_dev_size(pscmd), 0, item_dev_addr(pscmd),
+     OFFSET_BT_DEV | SHOW_INT}
+    ,
+    {"hsmode", item_dev_size(hsmode), 0, item_dev_addr(hsmode),
+     OFFSET_BT_DEV | SHOW_INT}
+    ,
+    {"hscmd", item_dev_size(hscmd), 0, item_dev_addr(hscmd),
+     OFFSET_BT_DEV | SHOW_INT}
+    ,
+    {"gpio_gap", item_dev_size(gpio_gap), 0, item_dev_addr(gpio_gap),
+     OFFSET_BT_DEV | SHOW_HEX}
+    ,
+    {"hscfgcmd", item_dev_size(hscfgcmd), 0, item_dev_addr(hscfgcmd),
+     OFFSET_BT_DEV | SHOW_INT}
+    ,
+};
+
+static struct item_data status_items[] = {
+    {"version", 0, (u32) driver_version, 0, SHOW_STRING},
+    {"tx_dnld_rdy", item_dev_size(tx_dnld_rdy), 0, item_dev_addr(tx_dnld_rdy),
+     OFFSET_BT_DEV | SHOW_INT},
+    {"psmode", item_adapter_size(psmode), 0, item_adapter_addr(psmode),
+     OFFSET_BT_ADAPTER | SHOW_INT},
+    {"hs_state", item_adapter_size(hs_state), 0, item_adapter_addr(hs_state),
+     OFFSET_BT_ADAPTER | SHOW_INT},
+    {"ps_state", item_adapter_size(ps_state), 0, item_adapter_addr(ps_state),
+     OFFSET_BT_ADAPTER | SHOW_INT},
+    {"irq_recv", item_adapter_size(irq_recv), 0, item_adapter_addr(irq_recv),
+     OFFSET_BT_ADAPTER | SHOW_INT},
+    {"irq_done", item_adapter_size(irq_done), 0, item_adapter_addr(irq_done),
+     OFFSET_BT_ADAPTER | SHOW_INT},
+    {"skb_pending", item_adapter_size(skb_pending), 0,
+     item_adapter_addr(skb_pending), OFFSET_BT_ADAPTER | SHOW_INT},
+};
+
+/** 
+ *  @brief convert string to number
+ *
+ *  @param s   	   pointer to numbered string
+ *  @return 	   converted number from string s
+ */
+int
+string_to_number(char *s)
+{
+    int r = 0;
+    int base = 0;
+    int pn = 1;
+
+    if (strncmp(s, "-", 1) == 0) {
+        pn = -1;
+        s++;
+    }
+    if ((strncmp(s, "0x", 2) == 0) || (strncmp(s, "0X", 2) == 0)) {
+        base = 16;
+        s += 2;
+    } else
+        base = 10;
+
+    for (s = s; *s != 0; s++) {
+        if ((*s >= '0') && (*s <= '9'))
+            r = (r * base) + (*s - '0');
+        else if ((*s >= 'A') && (*s <= 'F'))
+            r = (r * base) + (*s - 'A' + 10);
+        else if ((*s >= 'a') && (*s <= 'f'))
+            r = (r * base) + (*s - 'a' + 10);
+        else
+            break;
+    }
+
+    return (r * pn);
+}
+
+/** 
+ *  @brief This function handle generic proc file close
+ *  
+ *  @param inode   A pointer to inode structure
+ *  @param file    A pointer to file structure
+ *  @return 	   BT_STATUS_SUCCESS
+ */
+static int
+proc_close(struct inode *inode, struct file *file)
+{
+    struct proc_data *pdata = file->private_data;
+    ENTER();
+    if (pdata) {
+        if (pdata->on_close != NULL)
+            pdata->on_close(inode, file);
+        if (pdata->rdbuf)
+            kfree(pdata->rdbuf);
+        if (pdata->wrbuf)
+            kfree(pdata->wrbuf);
+        kfree(pdata);
+    }
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handle generic proc file read
+ *  
+ *  @param file    A pointer to file structure
+ *  @param buffer  A pointer to output buffer
+ *  @param len     number of byte to read
+ *  @param offset  A pointer to offset of file
+ *  @return 	   number of output data
+ */
+static ssize_t
+proc_read(struct file *file, char __user * buffer, size_t len, loff_t * offset)
+{
+    loff_t pos = *offset;
+    struct proc_data *pdata = (struct proc_data *) file->private_data;
+    if ((!pdata->rdbuf) || (pos < 0))
+        return -EINVAL;
+    if (pos >= pdata->rdlen)
+        return 0;
+    if (len > pdata->rdlen - pos)
+        len = pdata->rdlen - pos;
+    if (copy_to_user(buffer, pdata->rdbuf + pos, len))
+        return -EFAULT;
+    *offset = pos + len;
+    return len;
+}
+
+/** 
+ *  @brief This function handle generic proc file write
+ *  
+ *  @param file    A pointer to file structure
+ *  @param buffer  A pointer to input buffer
+ *  @param len     number of byte to write
+ *  @param offset  A pointer to offset of file
+ *  @return 	   number of input data
+ */
+static ssize_t
+proc_write(struct file *file,
+           const char __user * buffer, size_t len, loff_t * offset)
+{
+    loff_t pos = *offset;
+    struct proc_data *pdata = (struct proc_data *) file->private_data;
+
+    if (!pdata->wrbuf || (pos < 0))
+        return -EINVAL;
+    if (pos >= pdata->maxwrlen)
+        return 0;
+    if (len > pdata->maxwrlen - pos)
+        len = pdata->maxwrlen - pos;
+    if (copy_from_user(pdata->wrbuf + pos, buffer, len))
+        return -EFAULT;
+    if (pos + len > pdata->wrlen)
+        pdata->wrlen = len + file->f_pos;
+    *offset = pos + len;
+    return len;
+}
+
+/** 
+ *  @brief This function handle the generic file close 
+ *  
+ *  @param inode   A pointer to inode structure
+ *  @param file    A pointer to file structure
+ *  @return 	   BT_STATUS_SUCCESS or other 
+ */
+static void
+proc_on_close(struct inode *inode, struct file *file)
+{
+    struct proc_dir_entry *entry = PDE(inode);
+    struct proc_private_data *priv = entry->data;
+    struct proc_data *pdata = file->private_data;
+    char *line;
+    int i;
+    ENTER();
+    if (!pdata->wrlen)
+        return;
+    line = pdata->wrbuf;
+    while (line[0]) {
+        for (i = 0; i < priv->num_items; i++) {
+            if (!strncmp
+                (line, priv->pdata[i].name, strlen(priv->pdata[i].name))) {
+                line += strlen(priv->pdata[i].name) + 1;
+                if (priv->pdata[i].size == 1)
+                    *((u8 *) priv->pdata[i].addr) = (u8) string_to_number(line);
+                else if (priv->pdata[i].size == 2)
+                    *((u16 *) priv->pdata[i].addr) =
+                        (u16) string_to_number(line);
+                else if (priv->pdata[i].size == 4)
+                    *((u32 *) priv->pdata[i].addr) =
+                        (u32) string_to_number(line);
+            }
+        }
+        while (line[0] && line[0] != '\n')
+            line++;
+        if (line[0])
+            line++;
+    }
+    if (priv->pbt->bt_dev.hscmd || priv->pbt->bt_dev.pscmd
+        || priv->pbt->bt_dev.hscfgcmd) {
+        bt_prepare_command(priv->pbt);
+        wake_up_interruptible(&priv->pbt->MainThread.waitQ);
+    }
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function handle the generic file open
+ *  
+ *  @param inode   A pointer to inode structure
+ *  @param file    A pointer to file structure
+ *  @return 	   BT_STATUS_SUCCESS or other 
+ */
+static int
+proc_open(struct inode *inode, struct file *file)
+{
+    struct proc_dir_entry *entry = PDE(inode);
+    struct proc_private_data *priv = entry->data;
+    struct proc_data *pdata;
+    int i;
+    char *p;
+    u32 val = 0;
+    ENTER();
+    priv->pbt->adapter->skb_pending =
+        skb_queue_len(&priv->pbt->adapter->tx_queue);
+    if ((file->private_data =
+         kzalloc(sizeof(struct proc_data), GFP_KERNEL)) == NULL) {
+        PRINTM(ERROR, "Can not alloc mem for proc_data\n");
+        LEAVE();
+        return -ENOMEM;
+    }
+    pdata = (struct proc_data *) file->private_data;
+    if ((pdata->rdbuf = kmalloc(priv->bufsize, GFP_KERNEL)) == NULL) {
+        PRINTM(ERROR, "Can not alloc mem for rdbuf\n");
+        kfree(file->private_data);
+        LEAVE();
+        return -ENOMEM;
+    }
+    if (priv->fileflag == DEFAULT_FILE_PERM) {
+        if ((pdata->wrbuf = kzalloc(priv->bufsize, GFP_KERNEL)) == NULL) {
+            PRINTM(ERROR, "Can not alloc mem for wrbuf\n");
+            kfree(pdata->rdbuf);
+            kfree(file->private_data);
+            return -ENOMEM;
+        }
+        pdata->maxwrlen = priv->bufsize;
+        pdata->on_close = proc_on_close;
+    }
+    p = pdata->rdbuf;
+    for (i = 0; i < priv->num_items; i++) {
+        if (priv->pdata[i].size == 1)
+            val = *((u8 *) priv->pdata[i].addr);
+        else if (priv->pdata[i].size == 2)
+            val = *((u16 *) priv->pdata[i].addr);
+        else if (priv->pdata[i].size == 4)
+            val = *((u32 *) priv->pdata[i].addr);
+        if (priv->pdata[i].flag & SHOW_INT)
+            p += sprintf(p, "%s=%d\n", priv->pdata[i].name, val);
+        else if (priv->pdata[i].flag & SHOW_HEX)
+            p += sprintf(p, "%s=0x%x\n", priv->pdata[i].name, val);
+        else if (priv->pdata[i].flag & SHOW_STRING)
+            p += sprintf(p, "%s=%s\n", priv->pdata[i].name,
+                         (char *) priv->pdata[i].addr);
+    }
+    pdata->rdlen = strlen(pdata->rdbuf);
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+static struct file_operations proc_read_ops = {
+    .read = proc_read,
+    .open = proc_open,
+    .release = proc_close
+};
+
+static struct file_operations proc_rw_ops = {
+    .read = proc_read,
+    .write = proc_write,
+    .open = proc_open,
+    .release = proc_close
+};
+
+static struct proc_private_data proc_files[] = {
+    {"status", S_IRUGO, 1024, sizeof(status_items) / sizeof(status_items[0]),
+     &status_items[0], NULL, &proc_read_ops}
+    ,
+    {"config", DEFAULT_FILE_PERM, 512,
+     sizeof(config_items) / sizeof(config_items[0]), &config_items[0], NULL,
+     &proc_rw_ops}
+    ,
+};
+
+/** 
+ *  @brief This function init proc entry
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS
+ */
+int
+bt_proc_init(bt_private * priv)
+{
+    u8 ret = BT_STATUS_SUCCESS;
+    struct proc_dir_entry *entry;
+    int i, j;
+    ENTER();
+    if (!priv->proc_mbt) {
+        priv->proc_mbt = proc_mkdir("mbt", PROC_DIR);
+        if (!priv->proc_mbt) {
+            PRINTM(ERROR, "Could not mkdir mbt!\n");
+            ret = BT_STATUS_FAILURE;
+            goto done;
+        }
+        priv->proc_entry =
+            proc_mkdir(priv->bt_dev.hcidev->name, priv->proc_mbt);
+        if (!priv->proc_entry) {
+            PRINTM(ERROR, "Could not mkdir %s!\n", priv->bt_dev.hcidev->name);
+            ret = BT_STATUS_FAILURE;
+            goto done;
+        }
+        for (j = 0; j < sizeof(proc_files) / sizeof(proc_files[0]); j++) {
+            for (i = 0; i < proc_files[j].num_items; i++) {
+                if (proc_files[j].pdata[i].flag & OFFSET_BT_DEV)
+                    proc_files[j].pdata[i].addr =
+                        proc_files[j].pdata[i].offset + (u32) & priv->bt_dev;
+                if (proc_files[j].pdata[i].flag & OFFSET_BT_ADAPTER)
+                    proc_files[j].pdata[i].addr =
+                        proc_files[j].pdata[i].offset + (u32) priv->adapter;
+            }
+            proc_files[j].pbt = priv;
+            entry =
+                create_proc_entry(proc_files[j].name,
+                                  S_IFREG | proc_files[j].fileflag,
+                                  priv->proc_entry);
+            if (entry) {
+                entry->data = &proc_files[j];
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
+                entry->owner = THIS_MODULE;
+#endif
+                entry->proc_fops = proc_files[j].fops;
+            }
+        }
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief remove proc file
+ *
+ *  @param priv	   pointer wlan_private
+ *  @return 	   N/A
+ */
+void
+bt_proc_remove(bt_private * priv)
+{
+    int j;
+    ENTER();
+    if (priv->proc_mbt) {
+        if (priv->proc_entry) {
+            for (j = 0; j < sizeof(proc_files) / sizeof(proc_files[0]); j++)
+                remove_proc_entry(proc_files[j].name, priv->proc_entry);
+        }
+        remove_proc_entry(priv->bt_dev.hcidev->name, priv->proc_mbt);
+        remove_proc_entry("mbt", PROC_DIR);
+        priv->proc_entry = NULL;
+        priv->proc_mbt = NULL;
+    }
+    LEAVE();
+    return;
+}
diff --git a/bt_src/bt/bt_sdio.h b/bt_src/bt/bt_sdio.h
new file mode 100755
index 0000000..bf464ef
--- /dev/null
+++ b/bt_src/bt/bt_sdio.h
@@ -0,0 +1,236 @@
+/** @file bt_sdio.h
+ *  @brief This file contains SDIO (interface) module
+ *  related macros, enum, and structure.
+ *       
+ *  Copyright (C) 2007-2008, Marvell International Ltd.
+ *
+ *  This software file (the "File") is distributed by Marvell International 
+ *  Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ *  (the "License").  You may use, redistribute and/or modify this File in 
+ *  accordance with the terms and conditions of the License, a copy of which 
+ *  is available along with the File in the gpl.txt file or by writing to 
+ *  the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
+ *  02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+ *
+ *  THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ *  ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ *  this warranty disclaimer.
+ *
+ */
+
+#ifndef _BT_SDIO_H_
+#define _BT_SDIO_H_
+
+/** IRQ return type */
+typedef irqreturn_t IRQ_RET_TYPE;
+/** IRQ return */
+#define IRQ_RET		return IRQ_HANDLED
+/** ISR notifier function */
+typedef IRQ_RET_TYPE(*isr_notifier_fn_t) (s32 irq, void *dev_id,
+                                          struct pt_regs * reg);
+
+/** SDIO header length */
+#define SDIO_HEADER_LEN			4
+
+/* SD block size can not bigger than 64 due to buf size limit in firmware */
+/** define SD block size for data Tx/Rx */
+#define SD_BLOCK_SIZE			64
+/** define SD block size for firmware download */
+#define SD_BLOCK_SIZE_FW_DL		256
+
+/** Number of blocks for firmware transfer */
+#define FIRMWARE_TRANSFER_NBLOCK	2
+
+/** Firmware ready */
+#define FIRMWARE_READY			0xfedc
+
+/* Bus Interface Control Reg 0x07 */
+/** SD BUS width 1 */
+#define SD_BUS_WIDTH_1			0x00
+/** SD BUS width 4 */
+#define SD_BUS_WIDTH_4			0x02
+/** SD BUS width mask */
+#define SD_BUS_WIDTH_MASK		0x03
+/** Asynchronous interrupt mode */
+#define ASYNC_INT_MODE			0x20
+/* Host Control Registers */
+/** Host Control Registers : I/O port 0 */
+#define IO_PORT_0_REG			0x78
+/** Host Control Registers : I/O port 1 */
+#define IO_PORT_1_REG			0x79
+/** Host Control Registers : I/O port 2 */
+#define IO_PORT_2_REG			0x7A
+
+/** Host Control Registers : Configuration */
+#define CONFIGURATION_REG		0x00
+/** Host Control Registers : Host without Command 53 finish host*/
+#define HOST_TO_CARD_EVENT       (0x1U << 3)
+/** Host Control Registers : Host without Command 53 finish host */
+#define HOST_WO_CMD53_FINISH_HOST	(0x1U << 2)
+/** Host Control Registers : Host power up */
+#define HOST_POWER_UP			(0x1U << 1)
+/** Host Control Registers : Host power down */
+#define HOST_POWER_DOWN			(0x1U << 0)
+
+/** Host Control Registers : Host interrupt mask */
+#define HOST_INT_MASK_REG		0x02
+/** Host Control Registers : Upload host interrupt mask */
+#define UP_LD_HOST_INT_MASK		(0x1U)
+/** Host Control Registers : Download host interrupt mask */
+#define DN_LD_HOST_INT_MASK		(0x2U)
+/** Enable Host interrupt mask */
+#define HIM_ENABLE			(UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
+/** Disable Host interrupt mask */
+#define	HIM_DISABLE			0xff
+
+/** Host Control Registers : Host interrupt status */
+#define HOST_INTSTATUS_REG		0x03
+/** Host Control Registers : Upload host interrupt status */
+#define UP_LD_HOST_INT_STATUS		(0x1U)
+/** Host Control Registers : Download host interrupt status */
+#define DN_LD_HOST_INT_STATUS		(0x2U)
+
+/** Host Control Registers : Host interrupt RSR */
+#define HOST_INT_RSR_REG		0x01
+/** Host Control Registers : Upload host interrupt RSR */
+#define UP_LD_HOST_INT_RSR		(0x1U)
+
+/** Host Control Registers : Host interrupt status */
+#define HOST_INT_STATUS_REG		0x28
+/** Host Control Registers : Upload CRC error */
+#define UP_LD_CRC_ERR			(0x1U << 2)
+/** Host Control Registers : Upload restart */
+#define UP_LD_RESTART              	(0x1U << 1)
+/** Host Control Registers : Download restart */
+#define DN_LD_RESTART              	(0x1U << 0)
+
+/* Card Control Registers */
+/** Card Control Registers : Read SQ base address A0 register */
+#define SQ_READ_BASE_ADDRESS_A0_REG  	0x40
+/** Card Control Registers : Read SQ base address A1 register */
+#define SQ_READ_BASE_ADDRESS_A1_REG  	0x41
+/** Card Control Registers : Read SQ base address A2 register */
+#define SQ_READ_BASE_ADDRESS_A2_REG  	0x42
+/** Card Control Registers : Read SQ base address A3 register */
+#define SQ_READ_BASE_ADDRESS_A3_REG  	0x43
+/** Card Control Registers : Read SQ base address B0 register */
+#define SQ_READ_BASE_ADDRESS_B0_REG  	0x44
+/** Card Control Registers : Read SQ base address B1 register */
+#define SQ_READ_BASE_ADDRESS_B1_REG  	0x45
+/** Card Control Registers : Read SQ base address B2 register */
+#define SQ_READ_BASE_ADDRESS_B2_REG  	0x46
+/** Card Control Registers : Read SQ base address B3 register */
+#define SQ_READ_BASE_ADDRESS_B3_REG  	0x47
+
+/** Card Control Registers : Card status register */
+#define CARD_STATUS_REG              	0x30
+/** Card Control Registers : Card I/O ready */
+#define CARD_IO_READY              	(0x1U << 3)
+/** Card Control Registers : CIS card ready */
+#define CIS_CARD_RDY                 	(0x1U << 2)
+/** Card Control Registers : Upload card ready */
+#define UP_LD_CARD_RDY               	(0x1U << 1)
+/** Card Control Registers : Download card ready */
+#define DN_LD_CARD_RDY               	(0x1U << 0)
+
+/** Card Control Registers : Host interrupt mask register */
+#define HOST_INTERRUPT_MASK_REG      	0x34
+/** Card Control Registers : Host power interrupt mask */
+#define HOST_POWER_INT_MASK          	(0x1U << 3)
+/** Card Control Registers : Abort card interrupt mask */
+#define ABORT_CARD_INT_MASK          	(0x1U << 2)
+/** Card Control Registers : Upload card interrupt mask */
+#define UP_LD_CARD_INT_MASK          	(0x1U << 1)
+/** Card Control Registers : Download card interrupt mask */
+#define DN_LD_CARD_INT_MASK          	(0x1U << 0)
+
+/** Card Control Registers : Card interrupt status register */
+#define CARD_INTERRUPT_STATUS_REG    	0x38
+/** Card Control Registers : Power up interrupt */
+#define POWER_UP_INT                 	(0x1U << 4)
+/** Card Control Registers : Power down interrupt */
+#define POWER_DOWN_INT               	(0x1U << 3)
+
+/** Card Control Registers : Card interrupt RSR register */
+#define CARD_INTERRUPT_RSR_REG       	0x3c
+/** Card Control Registers : Power up RSR */
+#define POWER_UP_RSR                 	(0x1U << 4)
+/** Card Control Registers : Power down RSR */
+#define POWER_DOWN_RSR               	(0x1U << 3)
+
+/** Card Control Registers : Debug 0 register */
+#define DEBUG_0_REG                  	0x70
+/** Card Control Registers : SD test BUS 0 */
+#define SD_TESTBUS0                  	(0x1U)
+/** Card Control Registers : Debug 1 register */
+#define DEBUG_1_REG                  	0x71
+/** Card Control Registers : SD test BUS 1 */
+#define SD_TESTBUS1                  	(0x1U)
+/** Card Control Registers : Debug 2 register */
+#define DEBUG_2_REG                  	0x72
+/** Card Control Registers : SD test BUS 2 */
+#define SD_TESTBUS2                  	(0x1U)
+/** Card Control Registers : Debug 3 register */
+#define DEBUG_3_REG                  	0x73
+/** Card Control Registers : SD test BUS 3 */
+#define SD_TESTBUS3                  	(0x1U)
+/** Card Control Registers : Card OCR 0 register */
+#define CARD_OCR_0_REG               	0x68
+/** Card Control Registers : Card OCR 1 register */
+#define CARD_OCR_1_REG               	0x69
+/** Card Control Registers : Card OCR 3 register */
+#define CARD_OCR_3_REG               	0x6A
+/** Card Control Registers : Card config register */
+#define CARD_CONFIG_REG              	0x6B
+/** Card Control Registers : Card revision register */
+#define CARD_REVISION_REG            	0x5c
+/** Card Control Registers : Command 53 finish G BUS */
+#define CMD53_FINISH_GBUS            	(0x1U << 1)
+/** Card Control Registers : SD negative edge */
+#define SD_NEG_EDGE                  	(0x1U << 0)
+
+/* Special registers in function 0 of the SDxx card */
+/** Special register in function 0 of the SDxxx card : Scratch 0 */
+#define	SCRATCH_0_REG			0x80fe
+/** Special register in function 0 of the SDxxx card : Scratch 1 */
+#define	SCRATCH_1_REG			0x80ff
+/** Host F1 read base 0 */
+#define HOST_F1_RD_BASE_0		0x0040
+/** Host F1 read base 1 */
+#define HOST_F1_RD_BASE_1		0x0041
+/** Host F1 card ready */
+#define HOST_F1_CARD_RDY		0x0020
+
+/** Chip Id Register 0 */
+#define CARD_CHIP_ID_0_REG		0x801c
+/** Chip Id Register 1 */
+#define CARD_CHIP_ID_1_REG		0x801d
+/** Firmware status 0 register */
+#define CARD_FW_STATUS0_REG		0x60
+/** Firmware status 1 register */
+#define CARD_FW_STATUS1_REG		0x61
+/** Rx length register */
+#define CARD_RX_LEN_REG			0x62
+/** Rx unit register */
+#define CARD_RX_UNIT_REG		0x63
+
+struct sdio_mmc_card
+{
+        /** sdio_func structure pointer */
+    struct sdio_func *func;
+        /** bt_private structure pointer */
+    bt_private *priv;
+};
+#ifdef PXA3XX_DMA_ALIGN
+/** DMA alignment value for PXA3XX platforms */
+#define PXA3XX_DMA_ALIGNMENT	8
+/** Macros for Data Alignment : size */
+#define ALIGN_SZ(p, a)	\
+	(((p) + ((a) - 1)) & ~((a) - 1))
+
+/** Macros for Data Alignment : address */
+#define ALIGN_ADDR(p, a)	\
+	((((u32)(p)) + (((u32)(a)) - 1)) & ~(((u32)(a)) - 1))
+#endif /* !PXA3XX */
+#endif /* _BT_SDIO_H_ */
diff --git a/bt_src/bt/bt_sdiommc.c b/bt_src/bt/bt_sdiommc.c
new file mode 100755
index 0000000..b176fb4
--- /dev/null
+++ b/bt_src/bt/bt_sdiommc.c
@@ -0,0 +1,1214 @@
+/** @file bt_sdiommc.c
+ *  @brief This file contains SDIO IF (interface) module
+ *  related functions.
+ * 
+ * Copyright (C) 2007-2008, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available along with the File in the gpl.txt file or by writing to 
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+#include "include.h"
+
+/** define marvell vendor id */
+#define MARVELL_VENDOR_ID 0x02df
+
+/** Max retry number of CMD53 write */
+#define MAX_WRITE_IOMEM_RETRY	2
+/** Firmware name */
+char *fw_name = NULL;
+/** Default firmware name */
+#define DEFAULT_FW_NAME "mrvl/sd8787.bin"
+
+/** Function number 2 */
+#define FN2			2
+/** SD 8790 BT device ID */
+#define SD_DEVICE_ID_8790_BT    0x911D
+/** SD 8688 BT device ID */
+#define SD_DEVICE_ID_8688_BT    0x9105
+/** Device ID for SD8787 */
+#define SD_DEVICE_ID_8787_BT    0x911A
+
+static const struct sdio_device_id bt_ids[] = {
+    {SDIO_DEVICE(MARVELL_VENDOR_ID, SD_DEVICE_ID_8790_BT)},
+    {SDIO_DEVICE(MARVELL_VENDOR_ID, SD_DEVICE_ID_8688_BT)},
+    {SDIO_DEVICE(MARVELL_VENDOR_ID, SD_DEVICE_ID_8787_BT)},
+    {}
+};
+
+/********************************************************
+		Global Variables
+********************************************************/
+/**Interrupt status */
+static u8 sd_ireg = 0;
+/********************************************************
+		Local Functions
+********************************************************/
+
+/** 
+ *  @brief This function get rx_unit value
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+sd_get_rx_unit(bt_private * priv)
+{
+    int ret = BT_STATUS_SUCCESS;
+    u8 reg;
+    struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card;
+
+    ENTER();
+
+    reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret);
+    if (ret == BT_STATUS_SUCCESS)
+        priv->bt_dev.rx_unit = reg;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function reads fwstatus registers
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param dat	   A pointer to keep returned data
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static int
+sd_read_firmware_status(bt_private * priv, u16 * dat)
+{
+    int ret = BT_STATUS_SUCCESS;
+    u8 fws0;
+    u8 fws1;
+    struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card;
+
+    ENTER();
+
+    fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret);
+    if (ret < 0) {
+        LEAVE();
+        return BT_STATUS_FAILURE;
+    }
+
+    fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret);
+    if (ret < 0) {
+        LEAVE();
+        return BT_STATUS_FAILURE;
+    }
+
+    *dat = (((u16) fws1) << 8) | fws0;
+
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function reads rx length
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param dat	   A pointer to keep returned data
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static int
+sd_read_rx_len(bt_private * priv, u16 * dat)
+{
+    int ret = BT_STATUS_SUCCESS;
+    u8 reg;
+    struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card;
+
+    ENTER();
+
+    reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret);
+    if (ret == BT_STATUS_SUCCESS)
+        *dat = (u16) reg << priv->bt_dev.rx_unit;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function enables the host interrupts mask
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param mask	   the interrupt mask
+ *  @return 	   BT_STATUS_SUCCESS
+ */
+static int
+sd_enable_host_int_mask(bt_private * priv, u8 mask)
+{
+    int ret = BT_STATUS_SUCCESS;
+    struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card;
+
+    ENTER();
+
+    sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret);
+    if (ret) {
+        PRINTM(WARN, "Unable to enable the host interrupt!\n");
+        ret = BT_STATUS_FAILURE;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**  @brief This function disables the host interrupts mask.
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param mask	   the interrupt mask
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static int
+sd_disable_host_int_mask(bt_private * priv, u8 mask)
+{
+    int ret = BT_STATUS_FAILURE;
+    u8 host_int_mask;
+    struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card;
+
+    ENTER();
+
+    /* Read back the host_int_mask register */
+    host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret);
+    if (ret)
+        goto done;
+
+    /* Update with the mask and write back to the register */
+    host_int_mask &= ~mask;
+    sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret);
+    if (ret < 0) {
+        PRINTM(WARN, "Unable to diable the host interrupt!\n");
+        goto done;
+    }
+    ret = BT_STATUS_SUCCESS;
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function polls the card status register.
+ *  
+ *  @param priv    	A pointer to bt_private structure
+ *  @param bits    	the bit mask
+ *  @return 	   	BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static int
+sd_poll_card_status(bt_private * priv, u8 bits)
+{
+    int tries;
+    int rval;
+    struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card;
+    u8 cs;
+
+    ENTER();
+
+    for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) {
+        cs = sdio_readb(card->func, CARD_STATUS_REG, &rval);
+        if (rval != 0)
+            break;
+        if (rval == 0 && (cs & bits) == bits) {
+            LEAVE();
+            return BT_STATUS_SUCCESS;
+        }
+        udelay(1);
+    }
+    PRINTM(WARN, "mv_sdio_poll_card_status: FAILED!:%d\n", rval);
+
+    LEAVE();
+    return BT_STATUS_FAILURE;
+}
+
+/** 
+ *  @brief This function probe the card
+ *  
+ *  @param func    A pointer to sdio_func structure.
+ *  @param id	   A pointer to structure sd_device_id	
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static int
+sd_probe_card(struct sdio_func *func, const struct sdio_device_id *id)
+{
+    int ret = BT_STATUS_SUCCESS;
+    bt_private *priv = NULL;
+    struct sdio_mmc_card *card = NULL;
+
+    ENTER();
+
+    PRINTM(INFO, "vendor=%x,device=%x,class=%d,fn=%d\n", id->vendor, id->device,
+           id->class, func->num);
+    card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
+    if (!card) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    card->func = func;
+    priv = bt_add_card(card);
+    if (!priv) {
+        ret = BT_STATUS_FAILURE;
+        kfree(card);
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function checks if the firmware is ready to accept
+ *  command or not.
+ *  
+ *  @param priv     A pointer to bt_private structure
+ *  @param pollnum  Number of times to polling fw status 
+ *  @return         BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+sd_verify_fw_download(bt_private * priv, int pollnum)
+{
+    int ret = BT_STATUS_SUCCESS;
+    u16 firmwarestat;
+    int tries;
+
+    ENTER();
+
+    /* Wait for firmware initialization event */
+    for (tries = 0; tries < pollnum; tries++) {
+        if (sd_read_firmware_status(priv, &firmwarestat) < 0)
+            continue;
+        if (firmwarestat == FIRMWARE_READY) {
+            ret = BT_STATUS_SUCCESS;
+            break;
+        } else {
+            mdelay(10);
+            ret = BT_STATUS_FAILURE;
+        }
+    }
+    if (ret < 0)
+        goto done;
+
+    ret = BT_STATUS_SUCCESS;
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function downloads firmware image to the card.
+ *  
+ *  @param priv    	A pointer to bt_private structure
+ *  @return 	   	BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+sd_download_firmware_w_helper(bt_private * priv)
+{
+    struct sdio_mmc_card *card = (struct sdio_mmc_card *) priv->bt_dev.card;
+    const struct firmware *fw_firmware = NULL;
+    u8 *firmware = NULL;
+    int firmwarelen;
+    u8 base0;
+    u8 base1;
+    int ret = BT_STATUS_SUCCESS;
+    int offset;
+    void *tmpfwbuf = NULL;
+    int tmpfwbufsz;
+    u8 *fwbuf;
+    u16 len;
+    int txlen = 0;
+    int tx_blocks = 0;
+    int i = 0;
+    int tries = 0;
+#ifdef FW_DOWNLOAD_SPEED
+    u32 tv1, tv2;
+#endif
+
+    ENTER();
+
+    if ((ret =
+         request_firmware(&fw_firmware, fw_name, priv->hotplug_device)) < 0) {
+        PRINTM(FATAL, "request_firmware() failed, error code = %#x\n", ret);
+        goto done;
+    }
+
+    if (fw_firmware) {
+        firmware = (u8 *) fw_firmware->data;
+        firmwarelen = fw_firmware->size;
+    } else {
+        PRINTM(MSG, "No firmware image found! Terminating download\n");
+        ret = BT_STATUS_FAILURE;
+        goto done;
+    }
+
+    PRINTM(INFO, "Downloading FW image (%d bytes)\n", firmwarelen);
+
+#ifdef FW_DOWNLOAD_SPEED
+    tv1 = get_utimeofday();
+#endif
+
+#ifdef PXA3XX_DMA_ALIGN
+    tmpfwbufsz = ALIGN_SZ(BT_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT);
+#else /* PXA3XX_DMA_ALIGN */
+    tmpfwbufsz = BT_UPLD_SIZE;
+#endif
+    tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL);
+    if (!tmpfwbuf) {
+        PRINTM(ERROR,
+               "Unable to allocate buffer for firmware. Terminating download\n");
+        ret = BT_STATUS_FAILURE;
+        goto done;
+    }
+    memset(tmpfwbuf, 0, tmpfwbufsz);
+#ifdef PXA3XX_DMA_ALIGN
+    /* Ensure 8-byte aligned firmware buffer */
+    fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, PXA3XX_DMA_ALIGNMENT);
+#else /* PXA3XX_DMA_ALIGN */
+    fwbuf = (u8 *) tmpfwbuf;
+#endif
+
+    /* Perform firmware data transfer */
+    offset = 0;
+    do {
+        /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */
+        ret = sd_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY);
+        if (ret < 0) {
+            PRINTM(FATAL, "FW download with helper poll status timeout @ %d\n",
+                   offset);
+            goto done;
+        }
+
+        /* More data? */
+        if (offset >= firmwarelen)
+            break;
+
+        for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+            base0 = sdio_readb(card->func, SQ_READ_BASE_ADDRESS_A0_REG, &ret);
+            if (ret) {
+                PRINTM(WARN, "Dev BASE0 register read failed:"
+                       " base0=0x%04X(%d). Terminating download\n", base0,
+                       base0);
+                ret = BT_STATUS_FAILURE;
+                goto done;
+            }
+            base1 = sdio_readb(card->func, SQ_READ_BASE_ADDRESS_A1_REG, &ret);
+            if (ret) {
+                PRINTM(WARN, "Dev BASE1 register read failed:"
+                       " base1=0x%04X(%d). Terminating download\n", base1,
+                       base1);
+                ret = BT_STATUS_FAILURE;
+                goto done;
+            }
+            len = (((u16) base1) << 8) | base0;
+
+            if (len != 0)
+                break;
+            udelay(10);
+        }
+
+        if (len == 0)
+            break;
+        else if (len > BT_UPLD_SIZE) {
+            PRINTM(FATAL, "FW download failure @ %d, invalid length %d\n",
+                   offset, len);
+            ret = BT_STATUS_FAILURE;
+            goto done;
+        }
+
+        txlen = len;
+
+        if (len & BIT(0)) {
+            i++;
+            if (i > MAX_WRITE_IOMEM_RETRY) {
+                PRINTM(FATAL,
+                       "FW download failure @ %d, over max retry count\n",
+                       offset);
+                ret = BT_STATUS_FAILURE;
+                goto done;
+            }
+            PRINTM(ERROR, "FW CRC error indicated by the helper:"
+                   " len = 0x%04X, txlen = %d\n", len, txlen);
+            len &= ~BIT(0);
+            /* Setting this to 0 to resend from same offset */
+            txlen = 0;
+        } else {
+            i = 0;
+
+            /* Set blocksize to transfer - checking for last block */
+            if (firmwarelen - offset < txlen)
+                txlen = firmwarelen - offset;
+
+            PRINTM(INFO, ".");
+
+            tx_blocks = (txlen + SD_BLOCK_SIZE_FW_DL - 1) / SD_BLOCK_SIZE_FW_DL;
+
+            /* Copy payload to buffer */
+            memcpy(fwbuf, &firmware[offset], txlen);
+        }
+
+        /* Send data */
+        ret =
+            sdio_writesb(card->func, priv->bt_dev.ioport, fwbuf,
+                         tx_blocks * SD_BLOCK_SIZE_FW_DL);
+
+        if (ret < 0) {
+            PRINTM(ERROR, "FW download, write iomem (%d) failed @ %d\n", i,
+                   offset);
+            sdio_writeb(card->func, 0x04, CONFIGURATION_REG, &ret);
+            if (ret)
+                PRINTM(ERROR, "write ioreg failed (CFG)\n");
+        }
+
+        offset += txlen;
+    } while (TRUE);
+
+    PRINTM(INFO, "\nFW download over, size %d bytes\n", offset);
+
+    ret = BT_STATUS_SUCCESS;
+  done:
+#ifdef FW_DOWNLOAD_SPEED
+    tv2 = get_utimeofday();
+    PRINTM(INFO, "FW: %ld.%03ld.%03ld ", tv1 / 1000000,
+           (tv1 % 1000000) / 1000, tv1 % 1000);
+    PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000,
+           (tv2 % 1000000) / 1000, tv2 % 1000);
+    tv2 -= tv1;
+    PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000,
+           (tv2 % 1000000) / 1000, tv2 % 1000);
+#endif
+    if (tmpfwbuf)
+        kfree(tmpfwbuf);
+    if (fw_firmware)
+        release_firmware(fw_firmware);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function reads data from the card.
+ *  
+ *  @param priv    	A pointer to bt_private structure
+ *  @return 	   	BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static int
+sd_card_to_host(bt_private * priv)
+{
+    int ret = BT_STATUS_SUCCESS;
+    u16 buf_len = 0;
+    int buf_block_len;
+    int blksz;
+    struct sk_buff *skb = NULL;
+    u32 type;
+    u8 *payload = NULL;
+    struct hci_dev *hdev = priv->bt_dev.hcidev;
+    struct sdio_mmc_card *card = priv->bt_dev.card;
+
+    ENTER();
+
+    if (!card || !card->func) {
+        PRINTM(ERROR, "card or function is NULL!\n");
+        ret = BT_STATUS_FAILURE;
+        goto exit;
+    }
+
+    /* Read the length of data to be transferred */
+    ret = sd_read_rx_len(priv, &buf_len);
+    if (ret < 0) {
+        PRINTM(ERROR, "card_to_host, read scratch reg failed\n");
+        ret = BT_STATUS_FAILURE;
+        goto exit;
+    }
+
+    /* Allocate buffer */
+    blksz = SD_BLOCK_SIZE;
+    buf_block_len = (buf_len + blksz - 1) / blksz;
+    if (buf_len <= BT_HEADER_LEN || (buf_block_len * blksz) > ALLOC_BUF_SIZE) {
+        PRINTM(ERROR, "card_to_host, invalid packet length: %d\n", buf_len);
+        ret = BT_STATUS_FAILURE;
+        goto exit;
+    }
+    skb =
+        bt_skb_alloc(buf_block_len * blksz + PXA3XX_DMA_ALIGNMENT, GFP_ATOMIC);
+    if (skb == NULL) {
+        PRINTM(WARN, "No free skb\n");
+        goto exit;
+    }
+    if ((u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)) {
+        skb_put(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1));
+        skb_pull(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1));
+    }
+
+    payload = skb->tail;
+    ret = sdio_readsb(card->func, payload, priv->bt_dev.ioport,
+                      buf_block_len * blksz);
+    if (ret < 0) {
+        PRINTM(ERROR, "card_to_host, read iomem failed: %d\n", ret);
+        ret = BT_STATUS_FAILURE;
+        goto exit;
+    }
+    DBG_HEXDUMP(DBG_DATA, "SDIO Blk Rd", payload, blksz * buf_block_len);
+    /* This is SDIO specific header length: byte[2][1][0], type: byte[3]
+       (HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor) */
+    buf_len = payload[0];
+    buf_len |= (u16) payload[1] << 8;
+    type = payload[3];
+    switch (type) {
+    case HCI_ACLDATA_PKT:
+    case HCI_SCODATA_PKT:
+    case HCI_EVENT_PKT:
+        bt_cb(skb)->pkt_type = type;
+        skb->dev = (void *) hdev;
+        skb_put(skb, buf_len);
+        skb_pull(skb, BT_HEADER_LEN);
+        if (type == HCI_EVENT_PKT)
+            check_evtpkt(priv, skb);
+        hci_recv_frame(skb);
+        hdev->stat.byte_rx += buf_len;
+        break;
+    case MRVL_VENDOR_PKT:
+        bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
+        skb->dev = (void *) hdev;
+        skb_put(skb, buf_len);
+        skb_pull(skb, BT_HEADER_LEN);
+        if (BT_STATUS_SUCCESS != bt_process_event(priv, skb))
+            hci_recv_frame(skb);
+        hdev->stat.byte_rx += buf_len;
+        break;
+    default:
+        /* Driver specified event and command resp should be handle here */
+        PRINTM(INFO, "Unknow PKT type:%d\n", type);
+        kfree_skb(skb);
+        skb = NULL;
+        break;
+    }
+  exit:
+    if (ret) {
+        hdev->stat.err_rx++;
+        if (skb)
+            kfree_skb(skb);
+    }
+
+    LEAVE();
+    return ret;
+}
+
+#ifdef CONFIG_PM
+/** 
+ *  @brief This function handle the suspend function
+ *  
+ *  @param func    A pointer to sdio_func structure
+ *  @return        BT_STATUS_SUCCESS
+ */
+int
+sd_suspend(struct sdio_func *func)
+{
+    struct hci_dev *hcidev;
+    struct sdio_mmc_card *card;
+    bt_private *priv = NULL;
+
+    ENTER();
+    if (func) {
+        card = sdio_get_drvdata(func);
+        if (card)
+            priv = card->priv;
+    }
+    if (!priv) {
+        LEAVE();
+        return BT_STATUS_SUCCESS;
+    }
+    if (priv->adapter->hs_state != HS_ACTIVATED) {
+        if (BT_STATUS_SUCCESS != bt_enable_hs(priv)) {
+            LEAVE();
+            return BT_STATUS_FAILURE;
+        }
+    }
+    hcidev = priv->bt_dev.hcidev;
+    hci_suspend_dev(hcidev);
+    skb_queue_purge(&priv->adapter->tx_queue);
+
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handle the resume function
+ *  
+ *  @param func    A pointer to sdio_func structure
+ *  @return        BT_STATUS_SUCCESS
+ */
+int
+sd_resume(struct sdio_func *func)
+{
+    struct hci_dev *hcidev;
+    struct sdio_mmc_card *card;
+    bt_private *priv = NULL;
+
+    ENTER();
+
+    if (func) {
+        card = sdio_get_drvdata(func);
+        if (card)
+            priv = card->priv;
+    }
+    if (!priv) {
+        LEAVE();
+        return BT_STATUS_SUCCESS;
+    }
+    hcidev = priv->bt_dev.hcidev;
+    hci_resume_dev(hcidev);
+    /* if (is_bt_the_wakeup_src()){ */
+    {
+        PRINTM(MSG, "WAKEUP SRC: BT\n");
+        if ((priv->bt_dev.gpio_gap & 0x00ff) == 0xff) {
+            sbi_wakeup_firmware(priv);
+            priv->adapter->hs_state = HS_DEACTIVATED;
+        }
+    }
+
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+#endif
+
+/** 
+ *  @brief This function removes the card
+ *  
+ *  @param func    A pointer to sdio_func structure
+ *  @return        BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+static void
+sd_remove_card(struct sdio_func *func)
+{
+    struct sdio_mmc_card *card;
+
+    ENTER();
+
+    if (func) {
+        card = sdio_get_drvdata(func);
+        if (card) {
+            bt_remove_card(card);
+            kfree(card);
+        }
+    }
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function handles the interrupt.
+ *  
+ *  @param func  A pointer to sdio_func structure
+ *  @return      n/a
+ */
+static void
+sd_interrupt(struct sdio_func *func)
+{
+    bt_private *priv;
+    struct hci_dev *hcidev;
+    struct sdio_mmc_card *card;
+    int ret = BT_STATUS_SUCCESS;
+    u8 ireg = 0;
+
+    ENTER();
+
+    card = sdio_get_drvdata(func);
+    if (!card || !card->priv) {
+        PRINTM(INFO, "%s: sbi_interrupt(%p) card or priv is NULL, card=%p\n",
+               __FUNCTION__, func, card);
+        LEAVE();
+        return;
+    }
+    priv = card->priv;
+    hcidev = priv->bt_dev.hcidev;
+
+    ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
+    if (ret) {
+        PRINTM(WARN, "sdio_read_ioreg: read int status register failed\n");
+        goto done;
+    }
+    if (ireg != 0) {
+        /* 
+         * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+         * Clear the interrupt status register and re-enable the interrupt
+         */
+        PRINTM(INFO, "sdio_ireg = 0x%x\n", ireg);
+        priv->adapter->irq_recv = ireg;
+        sdio_writeb(card->func,
+                    ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS),
+                    HOST_INTSTATUS_REG, &ret);
+        if (ret) {
+            PRINTM(WARN,
+                   "sdio_write_ioreg: clear int status register failed\n");
+            goto done;
+        }
+    }
+    OS_INT_DISABLE;
+    sd_ireg |= ireg;
+    OS_INT_RESTORE;
+    bt_interrupt(hcidev);
+  done:
+    LEAVE();
+}
+
+/** 
+ *  @brief This function checks if the interface is ready to download
+ *  or not while other download interfaces are present
+ *  
+ *  @param priv   A pointer to bt_private structure
+ *  @return       BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ *                UPON BT_STATUS_SUCCESS the calling interface
+ *                is winner
+ */
+int
+sd_check_winner_status(bt_private * priv)
+{
+
+    int ret = BT_STATUS_SUCCESS;
+    u8 winner_status = 0;
+    struct sdio_mmc_card *cardp = (struct sdio_mmc_card *) priv->bt_dev.card;
+
+    ENTER();
+
+    winner_status = sdio_readb(cardp->func, CARD_FW_STATUS0_REG, &ret);
+    if (ret != BT_STATUS_SUCCESS) {
+        LEAVE();
+        return BT_STATUS_FAILURE;
+    }
+    if (winner_status != 0)
+        ret = BT_STATUS_FAILURE;
+    else
+        ret = BT_STATUS_SUCCESS;
+
+    LEAVE();
+    return ret;
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+static struct sdio_driver sdio_bt = {
+    .name = "sdio_bt",
+    .id_table = bt_ids,
+    .probe = sd_probe_card,
+    .remove = sd_remove_card,
+/*
+#ifdef CONFIG_PM
+	.suspend	= sd_suspend,
+	.resume		= sd_resume, 
+#endif
+*/
+};
+
+/** 
+ *  @brief This function registers the bt module in bus driver.
+ *  
+ *  @return	   An int pointer that keeps returned value
+ */
+int *
+sbi_register(void)
+{
+    int *ret;
+
+    ENTER();
+
+    if (sdio_register_driver(&sdio_bt) != 0) {
+        PRINTM(FATAL, "SD Driver Registration Failed \n");
+        LEAVE();
+        return NULL;
+    } else
+        ret = (int *) 1;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function de-registers the bt module in bus driver.
+ *  
+ *  @return 	   n/a
+ */
+void
+sbi_unregister(void)
+{
+    ENTER();
+    sdio_unregister_driver(&sdio_bt);
+    LEAVE();
+}
+
+/** 
+ *  @brief This function registers the device.
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+sbi_register_dev(bt_private * priv)
+{
+    int ret = BT_STATUS_SUCCESS;
+    u8 reg;
+    u8 chiprev;
+    struct sdio_mmc_card *card = priv->bt_dev.card;
+    struct sdio_func *func;
+
+    ENTER();
+
+    if (!card || !card->func) {
+        PRINTM(ERROR, "Error: card or function is NULL!\n");
+        goto failed;
+    }
+    func = card->func;
+    priv->hotplug_device = &func->dev;
+    if (fw_name == NULL)
+        fw_name = DEFAULT_FW_NAME;
+
+    /* Initialize the private structure */
+    strncpy(priv->bt_dev.name, "bt_sdio0", sizeof(priv->bt_dev.name));
+    priv->bt_dev.ioport = 0;
+    priv->bt_dev.fn = func->num;
+
+    sdio_claim_host(func);
+    ret = sdio_enable_func(func);
+    if (ret) {
+        PRINTM(FATAL, "sdio_enable_func() failed: ret=%d\n", ret);
+        goto release_host;
+    }
+    ret = sdio_claim_irq(func, sd_interrupt);
+    if (ret) {
+        PRINTM(FATAL, "sdio_claim_irq failed: ret=%d\n", ret);
+        goto disable_func;
+    }
+    ret = sdio_set_block_size(card->func, SD_BLOCK_SIZE);
+    if (ret) {
+        PRINTM(FATAL, "%s: cannot set SDIO block size\n", __FUNCTION__);
+        goto release_irq;
+    }
+
+    /* read Revision Register to get the chip revision number */
+    chiprev = sdio_readb(func, CARD_REVISION_REG, &ret);
+    if (ret) {
+        PRINTM(FATAL, "cannot read CARD_REVISION_REG\n");
+        goto release_irq;
+    }
+    priv->adapter->chip_rev = chiprev;
+    PRINTM(INFO, "revision=%#x\n", chiprev);
+
+    /* Read the IO port */
+    reg = sdio_readb(func, IO_PORT_0_REG, &ret);
+    if (ret < 0)
+        goto release_irq;
+    else
+        priv->bt_dev.ioport |= reg;
+
+    reg = sdio_readb(func, IO_PORT_1_REG, &ret);
+    if (ret < 0)
+        goto release_irq;
+    else
+        priv->bt_dev.ioport |= (reg << 8);
+
+    reg = sdio_readb(func, IO_PORT_2_REG, &ret);
+    if (ret < 0)
+        goto release_irq;
+    else
+        priv->bt_dev.ioport |= (reg << 16);
+
+    PRINTM(INFO, "SDIO FUNC%d IO port: 0x%x\n", priv->bt_dev.fn,
+           priv->bt_dev.ioport);
+    sdio_set_drvdata(func, card);
+    sdio_release_host(func);
+
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+  release_irq:
+    sdio_release_irq(func);
+  disable_func:
+    sdio_disable_func(func);
+  release_host:
+    sdio_release_host(func);
+  failed:
+
+    LEAVE();
+    return BT_STATUS_FAILURE;
+}
+
+/** 
+ *  @brief This function de-registers the device.
+ *  
+ *  @param priv    A pointer to  bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS
+ */
+int
+sbi_unregister_dev(bt_private * priv)
+{
+    struct sdio_mmc_card *card = priv->bt_dev.card;
+
+    ENTER();
+
+    if (card && card->func) {
+        sdio_claim_host(card->func);
+        sdio_release_irq(card->func);
+        sdio_disable_func(card->func);
+        sdio_release_host(card->func);
+        sdio_set_drvdata(card->func, NULL);
+    }
+
+    LEAVE();
+    return BT_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function enables the host interrupts.
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS
+ */
+int
+sbi_enable_host_int(bt_private * priv)
+{
+    struct sdio_mmc_card *card = priv->bt_dev.card;
+    int ret;
+
+    ENTER();
+
+    if (!card || !card->func) {
+        LEAVE();
+        return BT_STATUS_FAILURE;
+    }
+    sdio_claim_host(card->func);
+    ret = sd_enable_host_int_mask(priv, HIM_ENABLE);
+    sd_get_rx_unit(priv);
+    sdio_release_host(card->func);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function disables the host interrupts.
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+sbi_disable_host_int(bt_private * priv)
+{
+    struct sdio_mmc_card *card = priv->bt_dev.card;
+    int ret;
+
+    ENTER();
+
+    if (!card || !card->func) {
+        LEAVE();
+        return BT_STATUS_FAILURE;
+    }
+    sdio_claim_host(card->func);
+    ret = sd_disable_host_int_mask(priv, HIM_DISABLE);
+    sdio_release_host(card->func);
+
+    LEAVE();
+    return ret;
+}
+
+/**  
+ *  @brief This function sends data to the card.
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param payload A pointer to the data/cmd buffer
+ *  @param nb	   the length of data/cmd
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+sbi_host_to_card(bt_private * priv, u8 * payload, u16 nb)
+{
+    struct sdio_mmc_card *card = priv->bt_dev.card;
+    int ret = BT_STATUS_SUCCESS;
+    int buf_block_len;
+    int blksz;
+    int i = 0;
+    u8 *buf = NULL;
+#ifdef PXA3XX_DMA_ALIGN
+    void *tmpbuf = NULL;
+    int tmpbufsz;
+#endif
+
+    ENTER();
+
+    if (!card || !card->func) {
+        PRINTM(ERROR, "card or function is NULL!\n");
+        LEAVE();
+        return BT_STATUS_FAILURE;
+    }
+    buf = payload;
+#ifdef PXA3XX_DMA_ALIGN
+    if ((u32) payload & (PXA3XX_DMA_ALIGNMENT - 1)) {
+        tmpbufsz = ALIGN_SZ(nb, PXA3XX_DMA_ALIGNMENT);
+        tmpbuf = kmalloc(tmpbufsz, GFP_KERNEL);
+        memset(tmpbuf, 0, tmpbufsz);
+        /* Ensure 8-byte aligned CMD buffer */
+        buf = (u8 *) ALIGN_ADDR(tmpbuf, PXA3XX_DMA_ALIGNMENT);
+        memcpy(buf, payload, nb);
+    }
+#endif
+    /* Allocate buffer and copy payload */
+    blksz = SD_BLOCK_SIZE;
+    buf_block_len = (nb + blksz - 1) / blksz;
+    sdio_claim_host(card->func);
+#define MAX_WRITE_IOMEM_RETRY	2
+    do {
+        /* Transfer data to card */
+        ret = sdio_writesb(card->func, priv->bt_dev.ioport, buf,
+                           buf_block_len * blksz);
+        if (ret < 0) {
+            i++;
+            PRINTM(ERROR, "host_to_card, write iomem (%d) failed: %d\n", i,
+                   ret);
+            ret = BT_STATUS_FAILURE;
+            if (i > MAX_WRITE_IOMEM_RETRY)
+                goto exit;
+        } else {
+            DBG_HEXDUMP(DBG_DATA, "SDIO Blk Wr", payload, nb);
+        }
+    } while (ret == BT_STATUS_FAILURE);
+    priv->bt_dev.tx_dnld_rdy = FALSE;
+  exit:
+    sdio_release_host(card->func);
+#ifdef PXA3XX_DMA_ALIGN
+    if (tmpbuf)
+        kfree(tmpbuf);
+#endif
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function initializes firmware
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+sbi_dowload_fw(bt_private * priv)
+{
+    struct sdio_mmc_card *card = priv->bt_dev.card;
+    int ret = BT_STATUS_SUCCESS;
+    int poll_num = MAX_FIRMWARE_POLL_TRIES;
+
+    ENTER();
+
+    if (!card || !card->func) {
+        PRINTM(ERROR, "card or function is NULL!\n");
+        LEAVE();
+        return BT_STATUS_FAILURE;
+    }
+    sdio_claim_host(card->func);
+    if (BT_STATUS_SUCCESS == sd_verify_fw_download(priv, 1)) {
+        PRINTM(INFO, "Firmware already downloaded!\n");
+        goto done;
+    }
+    /* Check if other interface is downloading */
+    ret = sd_check_winner_status(priv);
+    if (ret == BT_STATUS_FAILURE) {
+        PRINTM(INFO, "winner interface already running! Skip FW download\n");
+        poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
+        goto poll_fw;
+    }
+
+    /* Download the main firmware via the helper firmware */
+    if (sd_download_firmware_w_helper(priv)) {
+        PRINTM(INFO, "Bluetooth FW download failed!\n");
+        ret = BT_STATUS_FAILURE;
+        goto done;
+    }
+  poll_fw:
+    /* check if the fimware is downloaded successfully or not */
+    if (sd_verify_fw_download(priv, poll_num)) {
+        PRINTM(INFO, "FW failed to be active in time!\n");
+        ret = BT_STATUS_FAILURE;
+        goto done;
+    }
+  done:
+    sdio_release_host(card->func);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function checks the interrupt status and handle it accordingly.
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @param ireg    A pointer to variable that keeps returned value
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+sbi_get_int_status(bt_private * priv, u8 * ireg)
+{
+    int ret = BT_STATUS_SUCCESS;
+    u8 sdio_ireg = 0;
+    struct sdio_mmc_card *card = priv->bt_dev.card;
+
+    ENTER();
+
+    *ireg = 0;
+    OS_INT_DISABLE;
+    sdio_ireg = sd_ireg;
+    sd_ireg = 0;
+    OS_INT_RESTORE;
+
+    sdio_claim_host(card->func);
+    priv->adapter->irq_done = sdio_ireg;
+    if (sdio_ireg & DN_LD_HOST_INT_STATUS) {    /* tx_done INT */
+        if (priv->bt_dev.tx_dnld_rdy) { /* tx_done already received */
+            PRINTM(INFO,
+                   "warning: tx_done already received: tx_dnld_rdy=0x%x int status=0x%x\n",
+                   priv->bt_dev.tx_dnld_rdy, sdio_ireg);
+        } else {
+            priv->bt_dev.tx_dnld_rdy = TRUE;
+        }
+    }
+    if (sdio_ireg & UP_LD_HOST_INT_STATUS)
+        sd_card_to_host(priv);
+
+    *ireg = sdio_ireg;
+    ret = BT_STATUS_SUCCESS;
+    sdio_release_host(card->func);
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function wakeup firmware
+ *  
+ *  @param priv    A pointer to bt_private structure
+ *  @return 	   BT_STATUS_SUCCESS or BT_STATUS_FAILURE
+ */
+int
+sbi_wakeup_firmware(bt_private * priv)
+{
+    struct sdio_mmc_card *card = priv->bt_dev.card;
+    int ret = BT_STATUS_SUCCESS;
+
+    ENTER();
+
+    if (!card || !card->func) {
+        PRINTM(ERROR, "card or function is NULL!\n");
+        LEAVE();
+        return BT_STATUS_FAILURE;
+    }
+    sdio_claim_host(card->func);
+    sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
+    sdio_release_host(card->func);
+    PRINTM(CMD, "wake up firmware\n");
+
+    LEAVE();
+    return ret;
+}
+
+module_param(fw_name, charp, 0);
+MODULE_PARM_DESC(fw_name, "Firmware name");
diff --git a/bt_src/bt/include.h b/bt_src/bt/include.h
new file mode 100755
index 0000000..4aa360b
--- /dev/null
+++ b/bt_src/bt/include.h
@@ -0,0 +1,43 @@
+/** @file include.h
+ *  @brief This file contains all the necessary include file.
+ *       
+ *  Copyright (C) 2007-2008, Marvell International Ltd.
+ *
+ *  This software file (the "File") is distributed by Marvell International 
+ *  Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ *  (the "License").  You may use, redistribute and/or modify this File in 
+ *  accordance with the terms and conditions of the License, a copy of which 
+ *  is available along with the File in the gpl.txt file or by writing to 
+ *  the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
+ *  02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
+ *
+ *  THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ *  IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ *  ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ *  this warranty disclaimer.
+ *
+ */
+
+#ifndef _INCLUDE_H_
+#define _INCLUDE_H_
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <linux/proc_fs.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include  <linux/version.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/card.h>
+#include "bt_drv.h"
+#include "bt_sdio.h"
+#endif /* _INCLUDE_H_ */
diff --git a/bt_src/gpl.txt b/bt_src/gpl.txt
new file mode 100755
index 0000000..f90922e
--- /dev/null
+++ b/bt_src/gpl.txt
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..cbe0747
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+set -e
+
+export KERNELDIR=$PWD/../../build/kernels/kernel-i386-intel-menlow/linux-2.6.31.4/
+export CROSS_COMPILE=
+export ARCH=i386
+
+# The number of jobs to pass to tools that can run in parallel (such as make
+# and dpkg-buildpackage
+NUM_JOBS=`cat /proc/cpuinfo | grep processor | awk '{a++} END {print a}'`
+
+BUILDDIR=$PWD/build
+rm -rf $BUILDDIR
+mkdir -p $BUILDDIR
+
+pushd wlan_src
+make clean || true
+make -j$NUM_JOBS KERNELDIR=$KERNELDIR CROSS_COMPILE=$CROSS_COMPILE ARCH=$ARCH
+make KERNELDIR=$KERNELDIR ARCH=$ARCH INSTALLDIR=$BUILDDIR install
+popd
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..f9797a4
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,5 @@
+marvell-8787 (0.1) karmic; urgency=low
+
+  * Initial import
+
+ -- The Chromium OS Authors <chromium-os-dev@googlegroups.com>  Tue, 11 Aug 2009 06:56:24 +0000
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..f41d045
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,16 @@
+# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+Source: marvell-8787
+Section: unknown
+Priority: extra
+Maintainer: The Chromium OS Authors <chromium-os-dev@googlegroups.com>
+Build-Depends: debhelper (>= 7)
+Standards-Version: 3.8.0
+
+Package: marvell-8787
+Architecture: any
+Depends:
+Description: mrvl8787
+ Marvell driver for 8787 WiFi+BT+FM radio part.
diff --git a/debian/dirs b/debian/dirs
new file mode 100644
index 0000000..78790c5
--- /dev/null
+++ b/debian/dirs
@@ -0,0 +1,8 @@
+# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+lib/firmware
+lib/firmware/mrvl
+etc
+etc/modprobe.d
diff --git a/debian/postinst b/debian/postinst
new file mode 100644
index 0000000..b84fc8b
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# postinst script for marvell-8787
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <postinst> `abort-remove'
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    configure)
+    ;;
+
+    abort-upgrade|abort-remove|abort-deconfigure)
+    ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..dba398e
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,98 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+flavour=chromeos-intel-menlow
+ARCH=i386
+CROSS_COMPILE=
+KERNELDIR=~/trunk/src/build/kernels/kernel-${flavour}/debian/build/build-${flavour}
+
+MRVL_MAKE=$(MAKE) KERNELDIR=$(KERNELDIR) CROSS_COMPILE=$(CROSS_COMPILE) \
+	ARCH=$(ARCH)
+
+INSTALL_DIR=$(CURDIR)/debian/marvell-8787
+MODULES_DIR=lib/modules/2.6.31-0-${flavour}/vendor/marvell
+
+configure: configure-stamp
+configure-stamp:
+	dh_testdir
+	# nothing to do to configure package
+	touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp
+	dh_testdir
+	# NB: $(MAKE) -C wlan_src fails 'cuz $(PWD) is set wrong
+	cd wlan_src; $(MRVL_MAKE)
+	touch $@
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+	$(MRVL_MAKE) -C wlan_src clean
+	dh_clean
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_prep
+	dh_installdirs
+
+	mkdir -p $(INSTALL_DIR)/$(MODULES_DIR)
+	# NB: $(MAKE) -C wlan_src fails 'cuz $(PWD) is set wrong
+	cd wlan_src; $(MRVL_MAKE) INSTALLDIR=$(INSTALL_DIR)/$(MODULES_DIR) \
+	     install
+
+	mkdir -p $(INSTALL_DIR)
+	cp marvell_8787.conf $(INSTALL_DIR)/etc/modprobe.d
+
+	mkdir -p $(INSTALL_DIR)/lib/firmware/mrvl
+	cp FwImage/sd8787.bin $(INSTALL_DIR)/lib/firmware/mrvl
+
+# Build architecture-independent files here.
+binary-indep: install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: install
+	dh_testdir
+	dh_testroot
+#	dh_installchangelogs
+#	dh_installdocs
+#	dh_installexamples
+#	dh_install
+#	dh_installmenu
+#	dh_installdebconf
+#	dh_installlogrotate
+#	dh_installemacsen
+#	dh_installpam
+#	dh_installmime
+#	dh_python
+#	dh_installinit
+#	dh_installcron
+#	dh_installinfo
+#	dh_installman
+#	dh_link
+#	dh_strip
+	dh_compress
+	dh_fixperms
+#	dh_perl
+#	dh_makeshlibs
+	dh_installdeb
+	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/io/sdio/syskt/Makefile b/io/sdio/syskt/Makefile
new file mode 100755
index 0000000..ff07bd5
--- /dev/null
+++ b/io/sdio/syskt/Makefile
@@ -0,0 +1,58 @@
+# File: Makefile
+#
+# Copyright (C) 2003-2009, Marvell International Ltd. 
+#
+# This software file (the "File") is distributed by Marvell International 
+# Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+# (the "License").  You may use, redistribute and/or modify this File in 
+# accordance with the terms and conditions of the License, a copy of which 
+# is available by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+# ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+# this warranty disclaimer.
+ 
+# Things that need to export symbols
+# export-objs := sdiobus.o
+
+
+# Objects to compile in this module
+# 
+STDHOSTOBJS = 	sdiobus.o \
+		stdhost.o \
+		skisr.o 
+
+
+obj-m += mrvlsdio.o
+mrvlsdio-objs := $(STDHOSTOBJS)
+
+
+# EXTRA_CFLAGS += -DDBG
+# EXTRA_CFLAGS += -DSDIO_API_INTERNAL
+# EXTRA_CFLAGS += -DSDIO_BUS_DRIVER
+EXTRA_CFLAGS += -DSDIO_ALTERNATIVE_IRQ
+EXTRA_CFLAGS += -I$(PWD)
+
+#
+# Make target rules
+# 
+all: mrvlsdio.o
+ifeq ($(KVER),2.6)
+	@echo "Finished Making Marvell SDIO Stdhost Linux Driver for Kernel 2.6"
+else
+	@echo "Finished Making Marvell SDIO Stdhost Linux Driver for Kernel 2.4"
+endif
+
+mrvlsdio.o: $(STDHOSTOBJS)
+	   $(LD) -r $^ -o $@	
+
+clean:
+	find . -name "*.o" -exec rm {} \;
+	find . -name "*.*~" -exec rm {} \;
+	find . -name "*.d" -exec rm {} \;
+	find . -name "*.mod.c" -exec rm {} \;
+	find . -name "*.ko" -exec rm {} \;
+	find . -name ".*.cmd" -exec rm {} \;
diff --git a/io/sdio/syskt/diagvers.h b/io/sdio/syskt/diagvers.h
new file mode 100644
index 0000000..2d93c64
--- /dev/null
+++ b/io/sdio/syskt/diagvers.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ *
+ * Name:	diagvers.h_
+ * Project:	Wireless LAN, SDIO Bus driver
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2007/01/18 09:23:14 $
+ * Purpose:	SDIO bus driver version control
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *	$Log: diagvers.h,v $
+ *	Revision 1.1  2007/01/18 09:23:14  pweber
+ *	Put under CVS control
+ *	
+ *
+ ******************************************************************************/
+
+// #define      SK_SIGNON_MSG   "___OEM_SIGNONMSG__"
+#define	SK_SIGNON_MSG	"Marvell SD Standard Host Driver V.2.0.0.0"
diff --git a/io/sdio/syskt/gpl.txt b/io/sdio/syskt/gpl.txt
new file mode 100755
index 0000000..f90922e
--- /dev/null
+++ b/io/sdio/syskt/gpl.txt
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/io/sdio/syskt/h/sdio.h b/io/sdio/syskt/h/sdio.h
new file mode 100644
index 0000000..ed938c4
--- /dev/null
+++ b/io/sdio/syskt/h/sdio.h
@@ -0,0 +1,133 @@
+/**
+ *
+ * Name:	sdio.h
+ * Project:	Wireless LAN, Bus driver for SDIO interface
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2007/01/18 09:26:19 $
+ * Purpose:	Bus driver for SDIO interface definitions
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd. 
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+#ifndef	_SDIO_H_
+#define	_SDIO_H_
+
+#include <linux/types.h>
+#include "sdio_spec.h"
+
+/* CMD53 parameter*/
+//mode
+#define BLOCK_MODE	0x1
+#define BYTE_MODE    0x0
+//opcode
+#define FIXED_ADDRESS 	0x0
+#define INCREMENTAL_ADDRESS 0x1
+
+/*****************************************************************/
+/*            New Multifunction SDIO Bus Driver API              */
+/*****************************************************************/
+
+#define SD_CLASS_ANY            (0xFFFF)
+#define SD_FUNCTION_ANY         (0xFFFF)
+#define SD_VENDOR_ANY           (0xFFFF)
+#define SD_DEVICE_ANY           (0xFFFF)
+
+#define SD_VENDOR_MARVELL 			0x02df
+
+#define SD_CLASS_BT_A						0x02
+#define SD_CLASS_BT_B						0x03
+#define SD_CLASS_WLAN						0x07
+
+typedef struct _sd_device_id
+{
+    u16 vendor;                 /* vendor id */
+    u16 device;                 /* device id */
+    u16 class;                  /* class id */
+    u16 fn;                     /* function number: 1-7 */
+    u16 blocksize;              /* block size */
+} sd_device_id, *psd_device_id;
+
+#define COMPARE_DEVICE_ID(dev_id_1,dev_id_2) \
+(((sd_device_id *)(dev_id_1)->vendor == (sd_device_id *)(dev_id_2)->vendor) && \
+ ((sd_device_id *)(dev_id_1)->device == (sd_device_id *)(dev_id_2)->device) && \
+ ((sd_device_id *)(dev_id_1)->class  == (sd_device_id *)(dev_id_2)->class) &&  \
+ ((sd_device_id *)(dev_id_1)->fn     == (sd_device_id *)(dev_id_2)->fn))
+
+#define MAX_SDIO_FUNCTIONS	8
+typedef void (*sd_int_handler) (void *dev, sd_device_id * id, void *context);
+
+typedef struct _sd_function
+{
+    u16 class;                  /* class id */
+    sd_int_handler int_handler; /* interrupt handler per function */
+    void *context;              /* private context per function, will be
+                                   passed back to the int_handler */
+} sd_function, *psd_function;
+
+struct _sd_device
+{
+    struct _sd_driver *drv;     /* pointer to the SD client driver */
+    sd_function functions[MAX_SDIO_FUNCTIONS];  /* All supported functions */
+    void *sd_bus;               /* Pointer to bus driver's private data */
+    psd_device_id pCurrent_Ids; /* pointer to current ids */
+    u8 chiprev;
+    u32 *cisptr;
+    u8 supported_functions;
+    struct device *dev;         /* generic device interface for hotplug */
+    u8 probe_called;
+    u8 remove_called;
+    void *priv;
+};
+
+struct _sd_driver
+{
+    const char *name;           /* name of client */
+    sd_device_id *ids;          /* ids for this client driver */
+    int (*probe) (struct _sd_device * dev, sd_device_id * id);  /* client
+                                                                   driver probe 
+                                                                   handler */
+    int (*remove) (struct _sd_device * dev);    /* client driver remove handler 
+                                                 */
+    int (*suspend) (struct _sd_device * dev);   /* client driver suspend
+                                                   handler */
+    int (*resume) (struct _sd_device * dev);    /* client driver resume handler 
+                                                 */
+};
+
+typedef struct _sd_driver sd_driver, *psd_driver;
+typedef struct _sd_device sd_device, *psd_device;
+
+/* Functions exported out for WLAN Layer */
+int sd_driver_register(sd_driver * drv);
+int sd_driver_unregister(sd_driver * drv);
+int sd_request_int(sd_device * dev, sd_device_id * id, sd_function * function);
+int sd_release_int(sd_device * dev, sd_device_id * id);
+int sd_unmask(sd_device * dev, sd_device_id * id);
+int sd_enable_int(sd_device * dev, sd_device_id * id);
+int sd_disable_int(sd_device * dev, sd_device_id * id);
+int sd_set_buswidth(sd_device * dev, int width);
+int sd_set_busclock(sd_device * dev, int clock);
+int sd_set_clock_on(sd_device * dev, int on);
+int sd_start_clock(sd_device * dev);
+int sd_stop_clock(sd_device * dev);
+int sd_set_gpo(sd_device * dev, int on);
+int sdio_read_ioreg(sd_device * dev, u8 fn, u32 reg, u8 * dat);
+int sdio_write_ioreg(sd_device * dev, u8 fn, u32 reg, u8 dat);
+int sdio_read_iomem(sd_device * dev, u8 fn, u32 address, u8 blkmode, u8 opcode,
+                    u32 blkcnt, u32 blksz, u8 * buffer);
+int sdio_write_iomem(sd_device * dev, u8 fn, u32 address, u8 blkmode, u8 opcode,
+                     u32 blkcnt, u32 blksz, u8 * buffer);
+#endif /* sdio.h */
diff --git a/io/sdio/syskt/h/sdio_spec.h b/io/sdio/syskt/h/sdio_spec.h
new file mode 100644
index 0000000..9a0762a
--- /dev/null
+++ b/io/sdio/syskt/h/sdio_spec.h
@@ -0,0 +1,238 @@
+/**
+ * 	File :	sdio_spec.h
+ * 	Addresses defined by SDIO Specifications 
+ *
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd. 
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+#ifndef _SDIOSPEC_H_
+#define _SDIOSPEC_H_
+
+#define MAX_SDIO_TUPLE_BODY_LEN 255
+
+/* CCCR (Card Common Control Registers) */
+#define CCCR_SDIO_REV_REG		0x00
+#define CCCR_FORMAT_VERSION(reg)    	(((reg) & 0xf0 >> 4))
+#define SDIO_SPEC_REVISION(reg)		(((reg) & 0x0f))
+
+#define SD_SPEC_REV_REG			0x01
+#define SD_PHYS_SPEC_VERSION(reg)	(((reg) & 0x0f))
+
+#define IO_ENABLE_REG			0x02
+#define IOE(x)				(0x1U << (x))
+#define IOE_1				IOE(1)
+#define IOE_2				IOE(2)
+#define IOE_3				IOE(3)
+#define IOE_4				IOE(4)
+#define IOE_5				IOE(5)
+#define IOE_6				IOE(6)
+#define IOE_7				IOE(7)
+
+#define IO_READY_REG			0x03
+#define IOR(x)				(0x1U << (x))
+#define IOR_1				IOR(1)
+#define IOR_2				IOR(2)
+#define IOR_3				IOR(3)
+#define IOR_4				IOR(4)
+#define IOR_5				IOR(5)
+#define IOR_6				IOR(6)
+#define IOR_7				IOR(7)
+
+#define INT_ENABLE_REG			0x04
+#define IENM				0x1
+#define IEN(x)				(0x1U << (x))
+#define IEN_1				IEN(1)
+#define IEN_2				IEN(2)
+#define IEN_3				IEN(3)
+#define IEN_4				IEN(4)
+#define IEN_5				IEN(5)
+#define IEN_6				IEN(6)
+#define IEN_7				IEN(7)
+
+#define INT_PENDING_REG			0x05
+#define INT(x)				(0x1U << (x))
+#define INT_1				INT(1)
+#define INT_2				INT(2)
+#define INT_3				INT(3)
+#define INT_4				INT(4)
+#define INT_5				INT(5)
+#define INT_6				INT(6)
+#define INT_7				INT(7)
+
+#define IO_ABORT_REG			0x06
+#define AS(x)				((x) & 0x7)
+#define AS_1				AS(1)
+#define AS_2				AS(2)
+#define AS_3				AS(3)
+#define AS_4				AS(4)
+#define AS_5				AS(5)
+#define AS_6				AS(6)
+#define AS_7				AS(7)
+
+#define RES					(0x00)
+
+#define BUS_INTERFACE_CONTROL_REG 	0x07
+#define BUS_WIDTH(reg)			((reg) & 0x3)
+#define CD_DISABLE			(0x1U << 7)
+
+#define CARD_CAPABILITY_REG		0x08
+#define SDC				(0x1U << 0)
+#define SMB				(0x1U << 1)
+#define SRW				(0x1U << 2)
+#define SBS				(0x1U << 3)
+#define S4MI				(0x1U << 4)
+#define E4MI				(0x1U << 5)
+#define LSC				(0x1U << 6)
+#define S4BLS				(0x1U << 7)
+
+#define COMMON_CIS_POINTER_0_REG	0x09
+
+#define COMMON_CIS_POINTER_1_REG	0x0a
+
+#define COMMON_CIS_POINTER_2_REG	0x0b
+
+#define BUS_SUSPEND_REG			0x0c
+#define BUS_STATUS			(0x1U << 0)
+#define BUS_REL_REQ_STATUS		(0x1U << 1)
+
+#define FUNCTION_SELECT_REG		0x0d
+#ifdef FS
+#undef FS
+#endif
+#define FS(x)				((x) & 0xf)
+#define FS_1				FS(1)
+#define FS_2				FS(2)
+#define FS_3				FS(3)
+#define FS_4				FS(4)
+#define FS_5				FS(5)
+#define FS_6				FS(6)
+#define FS_7				FS(7)
+#define FS_MEM				FS(8)
+#define DF				(0x1U << 7)
+
+#define EXEC_FLAGS_REG			0x0e
+#define EXM				0x0
+#define EX(x)				(0x1U << (x))
+#define EX_1				EX(1)
+#define EX_2				EX(2)
+#define EX_3				EX(3)
+#define EX_4				EX(4)
+#define EX_5				EX(5)
+#define EX_6				EX(6)
+#define EX_7				EX(7)
+
+#define READY_FLAGS_REG			0x0f
+#define RFM				0x0
+#define RF(x)				(0x1U << (x))
+#define RF_1				RF(1)
+#define RF_2				RF(2)
+#define RF_3				RF(3)
+#define RF_4				RF(4)
+#define RF_5				RF(5)
+#define RF_6				RF(6)
+#define RF_7				IEN(7)
+
+/* FBR (Function Basic Registers) */
+#define FN_CSA_REG(x)			(0x100 * (x) + 0x00)
+#define FN_CIS_POINTER_0_REG(x)		(0x100 * (x) + 0x09)
+#define FN_CIS_POINTER_1_REG(x)		(0x100 * (x) + 0x0a)
+#define FN_CIS_POINTER_2_REG(x)		(0x100 * (x) + 0x0b)
+#define FN_CSA_DAT_REG(x)		(0x100 * (x) + 0x0f)
+#define FN_BLOCK_SIZE_0_REG(x)		(0x100 * (x) + 0x10)
+#define FN_BLOCK_SIZE_1_REG(x)		(0x100 * (x) + 0x11)
+
+/* Function 0  -- duplicate, see the CCRC section */
+#define FN0_CIS_POINTER_0_REG		FN_CIS_POINTER_0_REG(1)
+#define FN0_CIS_POINTER_1_REG		FN_CIS_POINTER_1_REG(1)
+#define FN0_CIS_POINTER_2_REG		FN_CIS_POINTER_1_REG(1)
+#define FN0_BLOCK_SIZE_0_REG		FN_BLOCK_SIZE_0_REG(1)
+#define FN0_BLOCK_SIZE_1_REG		FN_BLOCK_SIZE_1_REG(1)
+/*      Function 1       */
+#define FN1_CSA_REG			FN_CSA_REG(1)
+#define FN1_CIS_POINTER_0_REG		FN_CIS_POINTER_0_REG(1)
+#define FN1_CIS_POINTER_1_REG		FN_CIS_POINTER_1_REG(1)
+#define FN1_CIS_POINTER_2_REG		FN_CIS_POINTER_1_REG(1)
+#define FN1_CSA_DAT_REG			FN_CSA_DAT_REG(1)
+#define FN1_BLOCK_SIZE_0_REG		FN_BLOCK_SIZE_0_REG(1)
+#define FN1_BLOCK_SIZE_1_REG		FN_BLOCK_SIZE_1_REG(1)
+/*      Function 2       */
+#define FN2_CSA_REG			FN_CSA_REG(2)
+#define FN2_CIS_POINTER_0_REG		FN_CIS_POINTER_0_REG(2)
+#define FN2_CIS_POINTER_1_REG		FN_CIS_POINTER_1_REG(2)
+#define FN2_CIS_POINTER_2_REG		FN_CIS_POINTER_2_REG(2)
+#define FN2_CSA_DAT_REG			FN_CSA_DAT_REG(2)
+#define FN2_BLOCK_SIZE_0_REG		FN_BLOCK_SIZE_0_REG(2)
+#define FN2_BLOCK_SIZE_1_REG		FN_BLOCK_SIZE_1_REG(2)
+/*      Function 3       */
+#define FN3_CSA_REG			FN_CSA_REG(3)
+#define FN3_CIS_POINTER_0_REG		FN_CIS_POINTER_0_REG(3)
+#define FN3_CIS_POINTER_1_REG		FN_CIS_POINTER_1_REG(3)
+#define FN3_CIS_POINTER_2_REG		FN_CIS_POINTER_2_REG(3)
+#define FN3_CSA_DAT_REG			FN_CSA_DAT_REG(3)
+#define FN3_BLOCK_SIZE_0_REG		FN_BLOCK_SIZE_0_REG(3)
+#define FN3_BLOCK_SIZE_1_REG		FN_BLOCK_SIZE_1_REG(3)
+/*      Function 4       */
+#define FN4_CSA_REG			FN_CSA_REG(4)
+#define FN4_CIS_POINTER_0_REG		FN_CIS_POINTER_0_REG(4)
+#define FN4_CIS_POINTER_1_REG		FN_CIS_POINTER_1_REG(4)
+#define FN4_CIS_POINTER_2_REG		FN_CIS_POINTER_2_REG(4)
+#define FN4_CSA_DAT_REG			FN_CSA_DAT_REG(4)
+#define FN4_BLOCK_SIZE_0_REG		FN_BLOCK_SIZE_0_REG(4)
+#define FN4_BLOCK_SIZE_1_REG		FN_BLOCK_SIZE_1_REG(4)
+/*      Function 5       */
+#define FN5_CSA_REG			FN_CSA_REG(5)
+#define FN5_CIS_POINTER_0_REG		FN_CIS_POINTER_0_REG(5)
+#define FN5_CIS_POINTER_1_REG		FN_CIS_POINTER_1_REG(5)
+#define FN5_CIS_POINTER_2_REG		FN_CIS_POINTER_2_REG(5)
+#define FN5_CSA_DAT_REG			FN_CSA_DAT_REG(5)
+#define FN5_BLOCK_SIZE_0_REG		FN_BLOCK_SIZE_0_REG(5)
+#define FN5_BLOCK_SIZE_1_REG		FN_BLOCK_SIZE_1_REG(5)
+/*      Function 6       */
+#define FN6_CSA_REG			FN_CSA_REG(6)
+#define FN6_CIS_POINTER_0_REG		FN_CIS_POINTER_0_REG(6)
+#define FN6_CIS_POINTER_1_REG		FN_CIS_POINTER_1_REG(6)
+#define FN6_CIS_POINTER_2_REG		FN_CIS_POINTER_2_REG(6)
+#define FN6_CSA_DAT_REG			FN_CSA_DAT_REG(6)
+#define FN6_BLOCK_SIZE_0_REG		FN_BLOCK_SIZE_0_REG(6)
+#define FN6_BLOCK_SIZE_1_REG		FN_BLOCK_SIZE_1_REG(6)
+/*      Function 7       */
+#define FN7_CSA_REG			FN_CSA_REG(7)
+#define FN7_CIS_POINTER_0_REG		FN_CIS_POINTER_0_REG(7)
+#define FN7_CIS_POINTER_1_REG		FN_CIS_POINTER_1_REG(7)
+#define FN7_CIS_POINTER_2_REG		FN_CIS_POINTER_2_REG(7)
+#define FN7_CSA_DAT_REG			FN_CSA_DAT_REG(7)
+#define FN7_BLOCK_SIZE_0_REG		FN_BLOCK_SIZE_0_REG(7)
+#define FN7_BLOCK_SIZE_1_REG		FN_BLOCK_SIZE_1_REG(7)
+
+/* FBR bit definitions */
+#define FN_IODEV_INTERFACE_CODE(reg)	((reg) & 0xf)
+#define FN_SUPPORTS_CSA			(0x1U << 6)
+#define FN_CSA_ENABLE			(0x1U << 7)
+
+/* Misc. helper definitions */
+#define FN(x)				(x)
+#define FN0				FN(0)
+#define FN1				FN(1)
+#define FN2				FN(2)
+#define FN3				FN(3)
+#define FN4				FN(4)
+#define FN5				FN(5)
+#define FN6				FN(6)
+#define FN7				FN(7)
+
+#endif /* __SDIO_SPEC__H */
diff --git a/io/sdio/syskt/h/sdiobus.h b/io/sdio/syskt/h/sdiobus.h
new file mode 100644
index 0000000..0cbfa5f
--- /dev/null
+++ b/io/sdio/syskt/h/sdiobus.h
@@ -0,0 +1,268 @@
+/**
+ *
+ * Name:	sdiobus.h
+ * Project:	Wireless LAN, Bus driver for SDIO interface
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2007/01/18 09:26:19 $
+ * Purpose:	Bus driver for SDIO interface definitions
+ *
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *	$Log: sdiobus.h,v $
+ *	Revision 1.1  2007/01/18 09:26:19  pweber
+ *	Put under CVS control
+ *	
+ ******************************************************************************/
+#ifndef SDIOBUS_H
+#define SDIOBUS_H
+
+#include "sdio.h"
+
+#define USE_SDIO_IF_SEMA
+
+#ifdef USE_SDIO_IF_SEMA
+#ifdef DEBUG_SDIO_IF_SEMA
+#define GET_IF_SEMA() \
+		printk(">>>> %s@%d: SEMA DOWN\n",__FUNCTION__,__LINE__);\
+		if ( down_interruptible(&sd_if_sema)) return -ERESTARTSYS;
+#define GET_IF_SEMA_NO_RC() \
+		printk(">>>> %s@%d: SEMA DOWN\n",__FUNCTION__,__LINE__);\
+		if ( down_interruptible(&sd_if_sema)) return;
+#else
+#define GET_IF_SEMA() \
+		if ( down_interruptible(&sd_if_sema)) return -ERESTARTSYS;
+#define GET_IF_SEMA_NO_RC() \
+		if ( down_interruptible(&sd_if_sema)) return;
+#endif
+
+#ifdef DEBUG_SDIO_IF_SEMA
+#define REL_IF_SEMA() \
+		printk("<<<< %s@%d: SEMA UP\n",__FUNCTION__,__LINE__);\
+		up(&sd_if_sema)
+#else
+#define REL_IF_SEMA() \
+		up(&sd_if_sema)
+#endif
+#else
+#define GET_IF_SEMA()
+#define GET_IF_SEMA_NO_RC()
+#define REL_IF_SEMA()
+#endif
+
+#define MIN(a,b)		((a) < (b) ? (a) : (b))
+
+#define FILE_DEVICE_SDIOBUSENUM 0x2A    // same as for Windows
+#define SDIOBUSENUM_IOCTL(_index_) \
+		_IOWR(FILE_DEVICE_SDIOBUSENUM, _index_, unsigned int )
+
+#define IOCTL_SDIOBUSENUM_PLUGIN_HARDWARE               SDIOBUSENUM_IOCTL (0x0)
+#define IOCTL_SDIOBUSENUM_UNPLUG_HARDWARE               SDIOBUSENUM_IOCTL (0x1)
+#define IOCTL_SDIOBUSENUM_EJECT_HARDWARE                SDIOBUSENUM_IOCTL (0x2)
+#define IOCTL_SDIOBUS_DONT_DISPLAY_IN_UI_DEVICE         SDIOBUSENUM_IOCTL (0x3)
+// IOCTL for FPGA Configuration GUI
+#define IOCTL_SDIOBUSENUM_SET_VOLTAGE                   SDIOBUSENUM_IOCTL (0x4)
+#define IOCTL_SDIOBUSENUM_SET_BUSTYPE                   SDIOBUSENUM_IOCTL (0x5)
+#define IOCTL_SDIOBUSENUM_SET_BUSWIDTH                  SDIOBUSENUM_IOCTL (0x6)
+#define IOCTL_SDIOBUSENUM_SET_CLKSPEED                  SDIOBUSENUM_IOCTL (0x7)
+#define IOCTL_SDIOBUSENUM_GET_BOARDREV                  SDIOBUSENUM_IOCTL (0x8)
+#define IOCTL_SDIOBUSENUM_GET_JUMPER                    SDIOBUSENUM_IOCTL (0x9)
+
+#define _SLEEP_MS( pDev, millisecs ) mdelay(millisecs)
+
+#define MMC_TYPE_HOST		1
+#define MMC_TYPE_CARD		2
+#define MMC_REG_TYPE_USER	3
+
+#define SD_BLOCK_SIZE	32
+
+#define BIT_0         0x01
+#define BIT_1         0x02
+#define BIT_2         0x04
+#define BIT_3         0x08
+#define BIT_4         0x10
+#define BIT_5         0x20
+#define BIT_6         0x40
+#define BIT_7         0x80
+
+/* FBR (Function Basic Registers) */
+#define FN_CSA_REG(x)             (0x100 * (x) + 0x00)
+#define FN_CIS_POINTER_0_REG(x)   (0x100 * (x) + 0x09)
+#define FN_CIS_POINTER_1_REG(x)   (0x100 * (x) + 0x0a)
+#define FN_CIS_POINTER_2_REG(x)   (0x100 * (x) + 0x0b)
+#define FN_CSA_DAT_REG(x)         (0x100 * (x) + 0x0f)
+#define FN_BLOCK_SIZE_0_REG(x)    (0x100 * (x) + 0x10)
+#define FN_BLOCK_SIZE_1_REG(x)    (0x100 * (x) + 0x11)
+
+/* The following defines function 1 registers of SD25 */
+/* Ref.: SD-25 SDIO Interface Specification Rev. 2.0.  */
+/*       Marvell Semiconductor, Inc.                  */
+
+/* SDIO Interface Registers */
+#define IO_ENABLE_REG								0x02
+#define IO_READY_REG								0x03
+#define INT_ENABLE_REG							0x04
+#define INT_PENDING_REG							0x05
+#define IO_ABORT_REG								0x06
+#define BUS_INTERFACE_CONTROL_REG 	0x07
+#define CARD_CAPABILITY_REG					0x08
+#define FUNCTION_SELECT_REG					0x0d
+#define EXEC_FLAGS_REG							0x0e
+#define READY_FLAGS_REG							0x0f
+#define HIGH_SPEED_REG              	0x13
+#define SHS                         	BIT_0
+#define EHS                         	BIT_1
+
+#define CARD_ADD_EVENT 			1
+#define CARD_REMOVED_EVENT 	2
+
+#define SDIOBUS_COMPATIBLE_IDS L"SDIOBUS\\MrvlCompatibleSDIOBus\0"
+#define SDIOBUS_COMPATIBLE_IDS_LENGTH sizeof(SDIOBUS_COMPATIBLE_IDS)
+
+#define SDIOBUS_POOL_TAG (ULONG) 'lvrM'
+
+#define WAIT_SDIO_CMD_RESPONSE() UDELAY(2)
+
+#define MILLI_SECOND 10000
+
+#define SDIO_BUS_TYPE			1
+#define SDIO_SPI_TYPE			2
+
+#define SDIO_1_BIT				1
+#define SDIO_4_BIT				4
+
+#define DMA_WR_SUPPORT			0x01
+#define DMA_RD_SUPPORT			0x02
+                                                                                                                                                                        /*--- mmoser 8/29/2006 ---*/
+typedef struct _SDHOST_EVENT
+{
+    long event;
+    wait_queue_head_t wq;
+} SDHOST_EVENT;
+
+//
+// A common header for the device extensions of the PDOs and FDO
+//
+
+#define DEVICE_NAME_LENGTH 256
+typedef struct _SD_CLIENT
+{
+    struct list_head sd_client_list_entry;
+    struct _sd_driver *drv;     /* pointer to the SD client driver */
+} SD_CLIENT, *PSD_CLIENT;
+
+typedef struct _SD_DEVICE_DATA
+{
+    struct list_head sd_dev_list_entry;
+
+#ifdef SYSKT_DMA_MALIGN_TEST
+    SK_U32 dma_rx_malign;
+    SK_U32 dma_tx_malign;
+    SK_U32 dma_start_malign;
+    SK_U8 dma_rbuff[1024 * 8];  // __attribute__((aligned(4)));
+    SK_U8 dma_tbuff[1024 * 8];  // __attribute__((aligned(4)));
+    // struct sk_buff *dma_skb;
+#endif
+    sd_device sd_dev[MAX_SDIO_FUNCTIONS];       /* API to client driver */
+    sd_device_id sd_ids[MAX_SDIO_FUNCTIONS];    /* sd ids for this device */
+    sd_device *irq_device_cache[MAX_SDIO_FUNCTIONS];    /* cache for speed up
+                                                           irq response */
+    u32 cisptr[MAX_SDIO_FUNCTIONS];
+
+    u8 number_of_functions;
+
+    spinlock_t sd_dev_lock;
+    unsigned long sd_dev_lock_flags;
+
+    int thread_id;
+    int stop_thread;
+
+    // mmoser 2005-11-28
+    atomic_t card_add_event;
+    atomic_t card_remove_event;
+
+                                                                                                                                                                        /*--- mmoser 8/29/2006 ---*/
+    SDHOST_EVENT trans_complete_evt;
+    SDHOST_EVENT cmd_complete_evt;
+    SDHOST_EVENT thread_started_evt;
+    struct workqueue_struct *workqueue;
+
+    struct work_struct irq_work;
+    struct work_struct card_out_work;
+    SK_BOOL isRemoving;
+
+                                                                                                                                                                        /*--- mmoser 10/11/2006 ---*/
+    struct pci_dev *dev;
+
+    SK_U32 ioport;
+
+    // IOBase Addresses
+    SK_U32 *IOBase[2];
+    SK_U32 IOBaseLength[2];
+    SK_U32 IOBaseIx;
+    SK_U32 Interrupt;
+    SK_U32 Affinity;
+    SK_U32 InterruptMode;
+    SK_U32 lastIntStatus;
+    SK_U8 lastCardIntStatus;
+    SK_U8 MACEvent;
+    SK_U8 DeviceName[2 * (DEVICE_NAME_LENGTH + 1)];
+    SK_U32 DeviceNameLength;
+
+    SK_BOOL dump;
+    SK_U32 ClockSpeed;
+    SK_BOOL initialized;
+                                                                                                                                                                                        /*--- mmoser 13.09.2005 ---*/
+    SK_BOOL SurpriseRemoved;
+
+    atomic_t if_lock;
+
+    SK_U8 dnlType;
+    SK_U8 CmdInProgress;
+
+    SK_U16 lastIRQSignalMask;
+    SK_U16 currentIRQSignalMask;
+    SK_U16 lastErrorIRQSignalMask;
+    SK_U8 baseClockFreq;
+    SK_U8 maxSupplyVoltage;
+    SK_U16 max_block_size;
+    SK_U32 debug_flags;
+    SK_U32 sdio_voltage;
+
+    SK_U32 errorOccured;
+
+    SK_U32 bus_errors;
+    SK_U32 bus_width;
+    SK_U32 bus_type;
+    SK_U32 crc_len;
+
+    SK_U8 dma_support;
+
+    SK_U8 PsState;              // pweber 17.08.2005
+
+    SK_BOOL CardIn;
+} SD_DEVICE_DATA, *PSD_DEVICE_DATA;
+
+BOOLEAN SDIOBus_CardPluggedIn(PSD_DEVICE_DATA SdData);
+BOOLEAN SDIOBus_CardRemoved(PSD_DEVICE_DATA SdData);
+
+#endif
diff --git a/io/sdio/syskt/h/skdebug.h b/io/sdio/syskt/h/skdebug.h
new file mode 100644
index 0000000..c868c79
--- /dev/null
+++ b/io/sdio/syskt/h/skdebug.h
@@ -0,0 +1,147 @@
+/**
+ *
+ * Name: skdebug.h
+ * Project: Wireless LAN SDIO bus driver
+ * Version: $Revision: 1.1 $
+ * Date:    $Date: 2007/01/18 09:26:19 $
+ * Purpose: 
+ *
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/*****************************************************************************
+*
+* History:
+* $Log: skdebug.h,v $
+* Revision 1.1  2007/01/18 09:26:19  pweber
+* Put under CVS control
+*
+*
+*****************************************************************************/
+
+#ifndef _SKDEBUG_H_
+#define _SKDEBUG_H_
+
+// #define DEBUG_VERBOSE                1
+
+#define DBG_NONE        0x00000000      // No debug - all off.
+#define DBG_ERROR       0x00000001      // Debug for ERRORS
+#define DBG_WARNING     0x00000002      // Debug for Warnings.
+#define DBG_LOAD        0x00000004      // Debug for driver load
+#define DBG_PNP		      0x00000008
+#define DBG_PWR		      0x00000010
+#define DBG_IOCTL				0x00000020
+#define DBG_PDO					0x00000040
+#define DBG_IRQ					0x00000080
+#define DBG_W528D				0x00000100
+#define DBG_W528D_CMD52	0x00000200
+#define DBG_W528D_CMD53	0x00000400
+#define DBG_API					0x00000800
+
+#define DBG_T1          0x01000000      // Our various time stamps.. up to 6.
+#define DBG_T2          0x02000000      // ||
+#define DBG_T3          0x04000000      // ||
+#define DBG_T4          0x08000000      // ||
+#define DBG_T5          0x10000000      // ||
+#define DBG_T6          0x20000000      // \/
+#define DBG_ALL         0xffffffff      // All debug enabled.
+
+#define DBG_TIMESTAMPS ( DBG_T1 |  DBG_T2  | DBG_T3 | DBG_T4 | DBG_T5 | DBG_T6 )
+
+#undef KERN_DEBUG
+#define KERN_DEBUG
+
+#define DBG_DEFAULT (DBG_NONE \
+| DBG_ERROR      \
+| DBG_WARNING    \
+| DBG_W528D			 \
+| DBG_LOAD      \
+)
+/***
+| DBG_W528D_CMD52 \
+| DBG_W528D_CMD53 \
+|	DBG_TIMESTAMPS \
+| DBG_PNP        \
+| DBG_IRQ        \
+| DBG_PDO        \
+| DBG_PWR        \
+| DBG_W528D			 \
+| DBG_LOAD      \
+| DBG_IOCTL      \
+| DBG_ERROR      \
+| DBG_WARNING    \
+
+****/
+
+#ifdef DBG
+extern unsigned char lptRegImage1;
+extern unsigned char lptRegImage2;
+extern ULONG stdDebugLevel;
+#endif // #ifdef DBG
+
+#ifdef DBG
+
+#define DBG_CRLF        0x00000000      // add some cr lfs before this message.
+#define DBG_RAW         0x00000000      // raw debug output
+#define DBG_DONTCARE (DBG_RAW | DBG_CRLF)       // either of these by
+                                                // themselves should not cause
+                                                // debug to print.
+
+/**
+#define LED_ON(x){\
+SK_U32 ___ulVal,___ulMask;\
+	MEM_READ_ULONG (pDev, SK_SLOT_0, 0x200,  &___ulVal);\
+	___ulMask = (1<<(16+(x)));\
+	___ulVal |= ___ulMask;\
+	MEM_WRITE_ULONG (pDev, SK_SLOT_0, 0x200,  ___ulVal);\
+}
+#define LED_OFF(x){\
+SK_U32 ___ulVal,___ulMask;\
+	MEM_READ_ULONG (pDev, SK_SLOT_0, 0x200,  &___ulVal);\
+	___ulMask = (1<<(16+(x)));\
+	___ulVal &= ~___ulMask;\
+	MEM_WRITE_ULONG (pDev, SK_SLOT_0, 0x200,  ___ulVal);\
+}
+**/
+
+#define BUGPRINT(Str) DbgPrint Str
+
+#define	ENTER()			DBGPRINT(DBG_LOAD,( KERN_DEBUG "Enter: %s, %s:%i\n", __FUNCTION__, \
+							__FILE__, __LINE__))
+#define	LEAVE()			DBGPRINT(DBG_LOAD,( KERN_DEBUG "Exit: %s, %s:%i\n", __FUNCTION__, \
+							__FILE__, __LINE__))
+
+#define PrintMacro printk
+
+#define INITDEBUG()
+
+#define DBGPRINT(lvl, Str)                              \
+    {                                                   \
+    ULONG __lvl = lvl;                                  \
+    if (stdDebugLevel & (__lvl & ~DBG_DONTCARE))            \
+    {                                                   \
+        PrintMacro Str ;                                   \
+    }}
+
+#else
+#define DBGPRINT(lvl,Str)
+#define INITDEBUG()
+#define ENTER()
+#define LEAVE()
+#endif
+#endif
diff --git a/io/sdio/syskt/h/skdrv1st.h b/io/sdio/syskt/h/skdrv1st.h
new file mode 100644
index 0000000..286eb78
--- /dev/null
+++ b/io/sdio/syskt/h/skdrv1st.h
@@ -0,0 +1,95 @@
+/**
+ *
+ * Name:	skdrv1st.h
+ * Project:	Wireless LAN, SDIO bus driver
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2007/01/18 09:26:19 $
+ * Purpose:	Contains all defines system specific definitions
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *	Copyright (C) 2003-2009, Marvell International Ltd.
+ *
+ *	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL
+ *	The copyright notice above does not evidence any
+ *	actual or intended publication of such source code.
+ *
+ *	This Module contains Proprietary Information of Marvell
+ *	and should be treated as Confidential.
+ *
+ *	The information in this file is provided for the exclusive use of
+ *	the licensees of Marvell.
+ *	Such users have the right to use, modify, and incorporate this code
+ *	into products for purposes authorized by the license agreement
+ *	provided they include this notice and the associated copyright notice
+ *	with any such product.
+ *	The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * History:
+ *	$Log: skdrv1st.h,v $
+ *	Revision 1.1  2007/01/18 09:26:19  pweber
+ *	Put under CVS control
+ *	
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKDRV1ST_H
+#define __INC_SKDRV1ST_H
+
+#define SDIO_BUS_DRIVER
+
+// Linux specific stuff
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
+#include <linux/config.h>
+#endif
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include <linux/semaphore.h>
+#else
+#include <asm/semaphore.h>
+#endif
+#include <linux/sched.h>        // kernel_thread
+#include <linux/mm.h>           // memory manager
+#include <linux/stat.h>
+#include <linux/wait.h>
+
+// kernel specific inludes ++++++++++++++++++++++
+
+#include <linux/workqueue.h>    /* for struct work_queue */
+#include <linux/timer.h>
+
+// defines ++++++++++++++++++++
+
+// #define UDELAY udelay
+#define UDELAY(x)
+
+#define INTERLOCKED_INC(x) (atomic_inc((x)),atomic_read((x)))
+#define INTERLOCKED_DEC(x) (atomic_dec((x)),atomic_read((x)))
+#define ZERO_MEMORY( pBuf,len) memset((pBuf),0,(len));
+
+#include "sktypes.h"
+// #include "../h/sdio.h"
+
+#define MRVL_DEVICE_NAME "MrvlSdioBus"
+
+/* defines ********************************************************************/
+/* typedefs *******************************************************************/
+/* function prototypes ********************************************************/
+
+#endif /* __INC_SKDRV1ST_H */
diff --git a/io/sdio/syskt/h/skdrv2nd.h b/io/sdio/syskt/h/skdrv2nd.h
new file mode 100644
index 0000000..27e80b1
--- /dev/null
+++ b/io/sdio/syskt/h/skdrv2nd.h
@@ -0,0 +1,54 @@
+/**
+ *
+ * Name:	skdrv2nd.h
+ * Project:	Wireless LAN SDIO Bus driver
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2007/01/18 09:26:19 $
+ * Purpose:	Contains all defines system specific definitions
+ *
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *	$Log: skdrv2nd.h,v $
+ *	Revision 1.1  2007/01/18 09:26:19  pweber
+ *	Put under CVS control
+ *	
+ *	
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKDRV2ND_H
+#define __INC_SKDRV2ND_H
+
+#include "skdebug.h"
+
+#include "sdiobus.h"
+#include "stdhost.h"
+#include "skisr.h"
+// #include "../h/sdio.h"
+
+/* defines ********************************************************************/
+
+/* function prototypes ********************************************************/
+/* Macros ************************************************************/
+
+#endif /* __INC_SKDRV2ND_H */
diff --git a/io/sdio/syskt/h/skisr.h b/io/sdio/syskt/h/skisr.h
new file mode 100644
index 0000000..19fc304
--- /dev/null
+++ b/io/sdio/syskt/h/skisr.h
@@ -0,0 +1,40 @@
+/**
+ *
+ * Name:	skisr.h
+ * Project:	Wireless LAN, Bus driver for SDIO interface
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2007/01/18 09:26:19 $
+ * Purpose:	This module handles the interrupts.
+ *
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *	$Log: skisr.h,v $
+ *	Revision 1.1  2007/01/18 09:26:19  pweber
+ *	Put under CVS control
+ *	
+ *	
+ ******************************************************************************/
+
+void SDIOBus_Dpc(unsigned long arg);
+
+irqreturn_t SDIOBus_Isr(int irq, void *dev_id, struct pt_regs *regs);
diff --git a/io/sdio/syskt/h/sktypes.h b/io/sdio/syskt/h/sktypes.h
new file mode 100644
index 0000000..2689823
--- /dev/null
+++ b/io/sdio/syskt/h/sktypes.h
@@ -0,0 +1,80 @@
+/**
+ *
+ * Name:	sktypes.h
+ * Project:	Wireless LAN, SDIO Bus driver
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2007/01/18 09:26:19 $
+ * Purpose:	Define data types for SDIO bus driver
+ *
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd. 
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *	$Log: sktypes.h,v $
+ *	Revision 1.1  2007/01/18 09:26:19  pweber
+ *	Put under CVS control
+ *	
+ *	
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKTYPES_H
+#define __INC_SKTYPES_H
+
+/* defines ********************************************************************/
+
+/*
+ * Data types with a specific size. 'I' = signed, 'U' = unsigned.
+ */
+#define SK_I8	s8
+#define SK_U8	u8
+#define SK_I16	s16
+#define SK_U16	u16
+#define SK_I32	s32
+#define SK_U32	u32
+#define SK_U64	u64
+
+#define SK_UPTR	SK_U32          /* casting pointer <-> integral */
+
+#define	SK_CONSTI64(x)	(x##L)
+#define	SK_CONSTU64(x)	(x##UL)
+/*
+ * Boolean type.
+ */
+#define SK_BOOL		SK_U8
+#define SK_FALSE	(SK_BOOL)0
+#define SK_TRUE		(SK_BOOL)(!SK_FALSE)
+
+#define VOID 		void
+#define PVOID 	VOID*
+#define ULONG		SK_U32
+#define USHORT	SK_U16
+#define UCHAR		SK_U8
+#define PUCHAR	SK_U8*
+#define BOOLEAN	SK_BOOL
+#define IN
+#define OUT
+
+/* typedefs *******************************************************************/
+
+/* function prototypes ********************************************************/
+
+#endif /* __INC_SKTYPES_H */
diff --git a/io/sdio/syskt/h/stdhost.h b/io/sdio/syskt/h/stdhost.h
new file mode 100644
index 0000000..5a012b3
--- /dev/null
+++ b/io/sdio/syskt/h/stdhost.h
@@ -0,0 +1,576 @@
+/**
+ *
+ * Name: stdhost.h
+ * Project: Wireless LAN, Bus driver for SDIO interface
+ * Version: $Revision: 1.1 $
+ * Date: $Date: 2007/01/18 09:26:19 $
+ * Purpose: This module handles the SDIO Standard Host Interface.
+ *
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd. 
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************************************
+ *
+ * History:
+ *
+ * $Log: stdhost.h,v $
+ * Revision 1.1  2007/01/18 09:26:19  pweber
+ * Put under CVS control
+ *
+ * 
+ ******************************************************************************/
+
+//  pweber 17.08.2005 taken from eagledev.h
+typedef enum
+{
+    // card is in full power
+    PS_STATE_FULL_POWER,
+    // PS mode, but card is ready for TX
+    PS_STATE_WAKEUP,
+    // PS Mode, card is not ready for TX
+    PS_STATE_SLEEP,
+    // SLEEP event is already received, but have not sent confirm yet
+    PS_STATE_SLEEP_PENDING,
+} PS_STATE;
+
+#define MAX_BUS_ERRORS 10
+
+// #define SD_BLOCK_SIZE 32
+
+#define DEBUG_BREAK_CMD53_RD      0x00000001
+#define DEBUG_BREAK_CMD53_WR      0x00000002
+#define DEBUG_DISABLE_HW_WORKAROUND_RD 0x00000004
+#define DEBUG_DISABLE_HW_WORKAROUND_WR 0x00000008
+#define DEBUG_SHOW_REG_10_14      0x00000010
+#define DEBUG_USE_RD_DMA      0x00000100
+#define DEBUG_USE_WR_DMA            0x00000200
+#define DEBUG_BREAK_START_FDO      0x80000000
+
+// SDIO CMD Macros
+#define MAKE_SDIO_OFFSET(x)   ((SK_U32)((SK_U32)(x)<<9))
+#define MAKE_SDIO_OP_CODE(x)   ((SK_U32)((SK_U32)(x)<<26))
+#define MAKE_SDIO_BLOCK_MODE(x) ((SK_U32)((SK_U32)(x)<<27))
+#define MAKE_SDIO_FUNCTION(x) 	((SK_U32)((SK_U32)(x)<<28))
+#define MAKE_SDIO_DIR(x) 				((SK_U32)((SK_U32)(x)<<31))
+
+// SD Host Standard Register                                                                                                                                            
+#define DMA_16K_BOUNDARY (0x2 << 12)
+#define STDHOST_SYSTEM_ADDRESS			 			0x00    // System 
+                                                                                // Address 
+                                                                                // 4 
+                                                                                // bytes
+#define STDHOST_BLOCK_SIZE					 			0x04    // 2 
+                                                                                                // bytes
+#define STDHOST_BLOCK_COUNT					 			0x06    // 2 
+                                                                                                // bytes
+#define STDHOST_CMD_ARGUMENT				 			0x08    // 4 
+                                                                                        // bytes 
+                                                                                        // -> 
+                                                                                        // bit 
+                                                                                        // 39 
+                                                                                        // - 
+                                                                                        // 8 
+                                                                                        // of 
+                                                                                        // SDIO 
+                                                                                        // CMD
+#define STDHOST_TRANSFER_MODE				 			0x0C    // 2 
+                                                                                        // bytes
+#define STDHOST_MULTI_BLOCK_SELECT 				(1<<5)
+#define STDHOST_READ_DIR_SELECT						(1<<4)
+#define STDHOST_AUTO_CMD12_ENA						(1<<2)
+#define STDHOST_BLOCK_COUNT_ENA 					(1<<1)
+#define STDHOST_DMA_ENA										(1<<0)
+
+#define STDHOST_COMMAND							 			0x0E    // 2 
+                                                                                                        // bytes
+#define STDHOST_CMD_TYPE_NORMAL						0x00
+#define STDHOST_CMD_TYPE_SUSPEND					0x01
+#define STDHOST_CMD_TYPE_RESUME						0x02
+#define STDHOST_CMD_TYPE_ABORT						0x03
+#define STDHOST_CMD_TYPE_MASK							0x03
+#define MK_CMD_TYPE(x) 										((x)<<6)
+#define MK_CMD(x) 												((x)<<8)
+#define MAX_WAIT_COMMAND_COMPLETE					1000
+
+#define STDHOST_CMD_DATA_PRESENT					(1<<5)
+#define STDHOST_CMD_INDEX_CHK_ENA					(1<<4)
+#define STDHOST_CMD_CRC_CHK_ENA						(1<<3)
+#define STDHOST_RESP_TYPE_NONE						0x00
+#define STDHOST_RESP_TYPE_R2							0x01
+#define STDHOST_RESP_TYPE_R1							0x02
+#define STDHOST_RESP_TYPE_R3							0x02
+#define STDHOST_RESP_TYPE_R4							0x02
+#define STDHOST_RESP_TYPE_R5							0x02
+#define STDHOST_RESP_TYPE_R6							0x02
+#define STDHOST_RESP_TYPE_R1b							0x03
+#define STDHOST_RESP_TYPE_R5b							0x03
+
+#define STDHOST_RESP_BITS_31_0  		 			0x10    // 4 
+                                                                                // bytes
+#define STDHOST_RESP_BITS_63_32			 			0x14    // 4 
+                                                                                // bytes
+#define STDHOST_RESP_BITS_95_64			 			0x18    // 4 
+                                                                                // bytes
+#define STDHOST_RESP_BITS_127_96		 			0x1C    // 4 
+                                                                                // bytes
+
+#define	GET_BITS_135_128(x)	((SK_U8)((SK_U32)(x)>>24))
+#define	GET_BITS_127_120(x)	((SK_U8)((SK_U32)(x)>>16))
+#define	GET_BITS_119_112(x)	((SK_U8)((SK_U32)(x)>>8))
+#define	GET_BITS_111_104(x)	((SK_U8)(x))
+#define	GET_BITS_103_96(x) 	((SK_U8)((SK_U32)(x)>>24))
+#define	GET_BITS_95_88(x)		((SK_U8)((SK_U32)(x)>>16))
+#define	GET_BITS_87_80(x)		((SK_U8)((SK_U32)(x)>>8))
+#define	GET_BITS_79_72(x)		((SK_U8)(x))
+#define	GET_BITS_71_64(x)		((SK_U8)((SK_U32)(x)>>24))
+#define	GET_BITS_63_56(x)		((SK_U8)((SK_U32)(x)>>16))
+#define	GET_BITS_55_48(x)		((SK_U8)((SK_U32)(x)>>8))
+#define	GET_BITS_47_40(x)		((SK_U8)(x))
+#define	GET_BITS_39_32(x)		((SK_U8)((SK_U32)(x)>>24))
+#define	GET_BITS_31_24(x)		((SK_U8)((SK_U32)(x)>>16))
+#define	GET_BITS_23_16(x) 	((SK_U8)((SK_U32)(x)>>8))
+#define	GET_BITS_15_08(x) 	((SK_U8)(x))
+
+/*
+#define	GET_BITS_135_128(x)	((SK_U8)(x))
+#define	GET_BITS_127_120(x)	((SK_U8)((SK_U32)(x)>>8)) 
+#define	GET_BITS_119_112(x)	((SK_U8)((SK_U32)(x)>>16))  
+#define	GET_BITS_111_104(x)	((SK_U8)((SK_U32)(x)>>24))      
+#define	GET_BITS_103_96(x) 	((SK_U8)(x))               
+#define	GET_BITS_95_88(x)		((SK_U8)((SK_U32)(x)>>8))  
+#define	GET_BITS_87_80(x)		((SK_U8)((SK_U32)(x)>>16)) 
+#define	GET_BITS_79_72(x)		((SK_U8)((SK_U32)(x)>>24))
+#define	GET_BITS_71_64(x)		((SK_U8)(x))               
+#define	GET_BITS_63_56(x)		((SK_U8)((SK_U32)(x)>>8))  
+#define	GET_BITS_55_48(x)		((SK_U8)((SK_U32)(x)>>16)) 
+#define	GET_BITS_47_40(x)		((SK_U8)((SK_U32)(x)>>24))
+#define	GET_BITS_39_32(x)		((SK_U8)(x))              
+#define	GET_BITS_31_24(x)		((SK_U8)((SK_U32)(x)>>8)) 
+#define	GET_BITS_23_16(x) 	((SK_U8)((SK_U32)(x)>>16))	
+#define	GET_BITS_15_08(x) 	((SK_U8)((SK_U32)(x)>>24))
+*/
+
+/* CIS Tuples*/
+#define CISTPL_VERS_1   0x15
+#define CISTPL_MANFID   0x20
+#define CISTPL_FUNCID   0x21
+#define CISTPL_FUNCE    0x22
+#define CISTPL_NULL			0x00
+#define CISTPL_END      0xFF
+
+#define STDHOST_DATA_PORT						 			0x20    // 4 
+                                                                                                        // bytes
+
+#define STDHOST_PRESENT_STATE				 			0x24    // 4 
+                                                                                        // bytes
+#define STDHOST_STATE_CMD_LINE_LVL				(1<<24)
+#define STDHOST_STATE_DAT3_LINE_LVL				(1<<23)
+#define STDHOST_STATE_DAT2_LINE_LVL				(1<<22)
+#define STDHOST_STATE_DAT1_LINE_LVL				(1<<21)
+#define STDHOST_STATE_DAT0_LINE_LVL				(1<<20)
+#define STDHOST_STATE_WRITE_PROTECT_LVL		(1<<19)
+#define STDHOST_STATE_CARD_DETECT_LVL			(1<<18)
+#define STDHOST_STATE_CARD_STATE_STABLE 	(1<<17)
+#define STDHOST_STATE_CARD_INSERTED				(1<<16)
+#define STDHOST_STATE_BUFFER_RD_ENABLE		(1<<11)
+#define STDHOST_STATE_BUFFER_WR_ENABLE		(1<<10)
+#define STDHOST_STATE_RD_TRANSFER_ACTIVE	(1<<9)
+#define STDHOST_STATE_WR_TRANSFER_ACTIVE	(1<<8)
+#define STDHOST_STATE_DAT_LINE_ACTIVE			(1<<2)
+#define STDHOST_STATE_CMD_INHIB_DAT				(1<<1)
+#define STDHOST_STATE_CMD_INHIB_CMD				(1<<0)
+#define MAX_WAIT_COMMAND_INHIBIT					1000
+
+#define STDHOST_HOST_CTRL						 			0x28    // 1 
+                                                                                                        // byte
+#define STDHOST_HIGH_SPEED_ENA						(1<<2)
+#define STDHOST_4_BIT_ENA									(1<<1)
+#define STDHOST_LED_ON										(1<<0)
+
+#define STDHOST_POWER_CTRL					 			0x29    // 1 
+                                                                                                // byte
+#define STDHOST_VOLTAGE_3_3_V							0x07
+#define STDHOST_VOLTAGE_3_0_V							0x06
+#define STDHOST_VOLTAGE_1_8_V							0x05
+#define MK_VOLTAGE(x)											((x)<<1)
+#define STDHOST_POWER_ON									(1<<0)
+
+#define STDHOST_BLOCK_GAP_CTRL			 			0x2A    // 1 
+                                                                                // byte
+#define STDHOST_WAKEUP_CTRL					 			0x2B    // 1 
+                                                                                                // byte
+#define STDHOST_WAKEUP_ON_CARD_REMOVE			0x04
+#define STDHOST_WAKEUP_ON_CARD_INSERT			0x02
+#define STDHOST_WAKEUP_ON_CARD_IRQ				0x01
+
+#define STDHOST_CLOCK_CTRL					 			0x2C    // 2 
+                                                                                                // byte
+#define STDHOST_CLOCK_DIV_BASE_CLK  			0x00
+#define STDHOST_CLOCK_DIV_2								0x01
+#define STDHOST_CLOCK_DIV_4								0x02
+#define STDHOST_CLOCK_DIV_8								0x04
+#define STDHOST_CLOCK_DIV_16							0x08
+#define STDHOST_CLOCK_DIV_32							0x10
+#define STDHOST_CLOCK_DIV_64							0x20
+#define STDHOST_CLOCK_DIV_128							0x40
+#define STDHOST_CLOCK_DIV_256							0x80
+#define MK_CLOCK(x)												((x)<<8)
+#define STDHOST_CLOCK_ENA								  (1<<2)
+#define STDHOST_INTERNAL_CLK_STABLE				(1<<1)
+#define STDHOST_INTERNAL_CLK_ENA					(1<<0)
+#define	MAX_WAIT_CLOCK_STABLE							1000
+
+#define STDHOST_TIMEOUT_CTRL				 			0x2E    // 1 
+                                                                                        // byte
+#define STDHOST_SW_RESET						 			0x2F    // 1 
+                                                                                                        // byte
+#define STDHOST_SW_RESET_DAT_LINE					(1<<2)
+#define STDHOST_SW_RESET_CMD_LINE					(1<<1)
+#define STDHOST_SW_RESET_ALL							(1<<0)
+
+#define STDHOST_NORMAL_IRQ_STATUS		 			0x30    // 2 
+                                                                                // byte
+#define STDHOST_NORMAL_IRQ_ERROR					(1<<15)
+#define STDHOST_NORMAL_IRQ_CARD 					(1<<8)
+#define STDHOST_NORMAL_IRQ_CARD_OUT				(1<<7)
+#define STDHOST_NORMAL_IRQ_CARD_IN				(1<<6)
+#define STDHOST_NORMAL_IRQ_BUF_RD_RDY			(1<<5)
+#define STDHOST_NORMAL_IRQ_BUF_WR_RDY			(1<<4)
+#define STDHOST_NORMAL_IRQ_DMA						(1<<3)
+#define STDHOST_NORMAL_IRQ_BLOCK_GAP			(1<<2)
+#define STDHOST_NORMAL_IRQ_TRANS_COMPLETE	(1<<1)
+#define STDHOST_NORMAL_IRQ_CMD_COMPLETE		(1<<0)
+
+#define STDHOST_ERROR_IRQ_STATUS		 			0x32    // 2 
+                                                                                // byte
+#define STDHOST_ERROR_IRQ_VENDOR					(0x0F<<12)
+#define STDHOST_ERROR_IRQ_GPI_1						(1<<15)
+#define STDHOST_ERROR_IRQ_GPI_0						(1<<14)
+#define STDHOST_ERROR_IRQ_AUTO_CMD12			(1<<8)
+#define STDHOST_ERROR_IRQ_CURRENT_LIMIT		(1<<7)
+#define STDHOST_ERROR_IRQ_DATA_END_BIT		(1<<6)
+#define STDHOST_ERROR_IRQ_DATA_CRC				(1<<5)
+#define STDHOST_ERROR_IRQ_DATA_TIMEOUT		(1<<4)
+#define STDHOST_ERROR_IRQ_CMD_INDEX				(1<<3)
+#define STDHOST_ERROR_IRQ_CMD_END_BIT			(1<<2)
+#define STDHOST_ERROR_IRQ_CMD_CRC					(1<<1)
+#define STDHOST_ERROR_IRQ_CMD_TIMEOUT			(1<<0)
+
+#define STDHOST_NORMAL_IRQ_STATUS_ENABLE	0x34    // 2 byte
+#define STDHOST_NORMAL_IRQ_CARD_ENA				(1<<8)
+#define STDHOST_NORMAL_IRQ_CARD_OUT_ENA		(1<<7)
+#define STDHOST_NORMAL_IRQ_CARD_IN_ENA		(1<<6)
+#define STDHOST_NORMAL_IRQ_BUF_RD_RDY_ENA	(1<<5)
+#define STDHOST_NORMAL_IRQ_BUF_WR_RDY_ENA	(1<<4)
+#define STDHOST_NORMAL_IRQ_DMA_ENA				(1<<3)
+#define STDHOST_NORMAL_IRQ_BLOCK_GAP_ENA	(1<<2)
+#define STDHOST_NORMAL_IRQ_TRANS_COMPLETE_ENA	(1<<1)
+#define STDHOST_NORMAL_IRQ_CMD_COMPLETE_ENA	(1<<0)
+
+#define STDHOST_ERROR_IRQ_STATUS_ENABLE		0x36    // 2 byte
+#define STDHOST_ERROR_IRQ_VENDOR_ENA				(0x0F<<12)
+#define STDHOST_ERROR_IRQ_AUTO_CMD12_ENA		(1<<8)
+#define STDHOST_ERROR_IRQ_CURRENT_LIMIT_ENA	(1<<7)
+#define STDHOST_ERROR_IRQ_DATA_END_BIT_ENA	(1<<6)
+#define STDHOST_ERROR_IRQ_DATA_CRC_ENA			(1<<5)
+#define STDHOST_ERROR_IRQ_DATA_TIMEOUT_ENA	(1<<4)
+#define STDHOST_ERROR_IRQ_CMD_INDEX_ENA			(1<<3)
+#define STDHOST_ERROR_IRQ_CMD_END_BIT_ENA		(1<<2)
+#define STDHOST_ERROR_IRQ_CMD_CRC_ENA				(1<<1)
+#define STDHOST_ERROR_IRQ_CMD_TIMEOUT_ENA		(1<<0)
+
+#define STDHOST_NORMAL_IRQ_SIGNAL_ENABLE	0x38    // 2 byte
+#define STDHOST_NORMAL_IRQ_ALL_SIG_ENA						0xFFFF
+#define STDHOST_NORMAL_IRQ_CARD_SIG_ENA						(1<<8)
+#define STDHOST_NORMAL_IRQ_CARD_OUT_SIG_ENA				(1<<7)
+#define STDHOST_NORMAL_IRQ_CARD_IN_SIG_ENA				(1<<6)
+#define STDHOST_NORMAL_IRQ_BUF_RD_RDY_SIG_ENA			(1<<5)
+#define STDHOST_NORMAL_IRQ_BUF_WR_RDY_SIG_ENA			(1<<4)
+#define STDHOST_NORMAL_IRQ_DMA_SIG_ENA						(1<<3)
+#define STDHOST_NORMAL_IRQ_BLOCK_GAP_SIG_ENA			(1<<2)
+#define STDHOST_NORMAL_IRQ_TRANS_COMPLETE_SIG_ENA	(1<<1)
+#define STDHOST_NORMAL_IRQ_CMD_COMPLETE_SIG_ENA		(1<<0)
+
+/*
+#define STDHOST_NORMAL_IRQ_CARD_ALL_ENA	( STDHOST_NORMAL_IRQ_CARD_OUT_SIG_ENA | \
+																					STDHOST_NORMAL_IRQ_CARD_IN_SIG_ENA  | \
+			      STDHOST_NORMAL_IRQ_CARD_SIG_ENA)
+*/
+
+/*
+#define STDHOST_NORMAL_IRQ_CARD_ALL_ENA	( STDHOST_NORMAL_IRQ_CARD_OUT_SIG_ENA | \
+																					STDHOST_NORMAL_IRQ_CARD_IN_SIG_ENA  | \
+																					STDHOST_NORMAL_IRQ_TRANS_COMPLETE_SIG_ENA | \
+																					STDHOST_NORMAL_IRQ_CARD_SIG_ENA)
+*/
+ /**/ extern int intmode;
+#define STDHOST_GPIO_IRQ_CARD_ALL_ENA	(  \
+		STDHOST_NORMAL_IRQ_CARD_OUT_SIG_ENA | \
+		STDHOST_NORMAL_IRQ_CARD_IN_SIG_ENA  | \
+		STDHOST_NORMAL_IRQ_TRANS_COMPLETE_SIG_ENA)
+
+#define STDHOST_NORMAL_IRQ_CARD_ALL_ENA         \
+		((intmode == 0) ? (STDHOST_GPIO_IRQ_CARD_ALL_ENA | STDHOST_NORMAL_IRQ_CARD_SIG_ENA) : \
+		(STDHOST_GPIO_IRQ_CARD_ALL_ENA))
+ /**/
+#define STDHOST_ERROR_IRQ_SIGNAL_ENABLE		0x3A    // 2 byte
+#define STDHOST_ERROR_IRQ_VENDOR_SIG_ENA				(0x0F<<12)
+#define STDHOST_ERROR_IRQ_AUTO_CMD12_SIG_ENA		(1<<8)
+#define STDHOST_ERROR_IRQ_CURRENT_LIMIT_SIG_ENA	(1<<7)
+#define STDHOST_ERROR_IRQ_DATA_END_BIT_SIG_ENA	(1<<6)
+#define STDHOST_ERROR_IRQ_DATA_CRC_SIG_ENA			(1<<5)
+#define STDHOST_ERROR_IRQ_DATA_TIMEOUT_SIG_ENA	(1<<4)
+#define STDHOST_ERROR_IRQ_CMD_INDEX_SIG_ENA			(1<<3)
+#define STDHOST_ERROR_IRQ_CMD_END_BIT_SIG_ENA		(1<<2)
+#define STDHOST_ERROR_IRQ_CMD_CRC_SIG_ENA				(1<<1)
+#define STDHOST_ERROR_IRQ_CMD_TIMEOUT_SIG_ENA		(1<<0)
+#define STDHOST_AUTO_CMD12_ERROR_STATUS		0x3C    // 2 byte
+#define STDHOST_CAPABILITIES							0x40    // 4 
+                                                                                        // byte
+#define STDHOST_CAP_VOLTAGE_1_8						(1<<26)
+#define STDHOST_CAP_VOLTAGE_3_0						(1<<25)
+#define STDHOST_CAP_VOLTAGE_3_3						(1<<24)
+#define STDHOST_CAP_SUSPENSE_RESUME				(1<<23)
+#define STDHOST_CAP_DMA										(1<<22)
+#define STDHOST_CAP_HIGH_SPEED						(1<<21)
+#define STDHOST_CAP_MAX_BLOCK_LEN					(0x03<<16)
+#define STDHOST_CAP_MAX_BLOCK_512					(0x00<<16)
+#define STDHOST_CAP_MAX_BLOCK_1024				(0x01<<16)
+#define STDHOST_CAP_MAX_BLOCK_2048				(0x02<<16)
+#define STDHOST_CAP_BASE_CLOCK_FREQ				(0x3F<<8)
+#define GET_CAP_BASE_CLOCK_FREQ(x)				(SK_U8)(((x)>>8)&0x000000FF)
+#define STDHOST_CAP_TIMEOUT_CLOCK_UNIT		(1<<7)
+#define STDHOST_CAP_TIMEOUT_CLOCK_UNIT_MHZ	(1<<7)
+#define STDHOST_CAP_TIMEOUT_CLOCK_FREQ		0x3F
+#define STDHOST_CAPABILITIES_RESERVED			0x44    // 4 byte
+#define STDHOST_MAX_CURRENT_CAP						0x48    // 4 
+                                                                                // byte
+#define STDHOST_MAX_CURRENT_CAP_1_8_V			(0xFF<<16)
+#define GET_MAX_CURRENT_CAP_1_8_V(x)			(((x)>>16)&0x000000FF)
+#define STDHOST_MAX_CURRENT_CAP_3_0_V			(0xFF<<8)
+#define GET_MAX_CURRENT_CAP_3_0_V(x)			(((x)>>8)&0x000000FF)
+#define STDHOST_MAX_CURRENT_CAP_3_3_V		 	0xFF
+#define GET_MAX_CURRENT_CAP_3_3_V(x)			((x)&0x000000FF)
+#define CALC_MAX_CURRENT_IN_MA(x)					((x)*4)
+#define STDHOST_MAX_CURRENT_CAP_RESERVED	0x4C    // 4 byte
+#define STDHOST_SLOT_IRQ_STATUS						0xFC    // 2 
+                                                                                // byte
+#define STDHOST_SLOT_IRQ_SLOT_0						0x01
+#define STDHOST_SLOT_IRQ_SLOT_1						0x02
+#define STDHOST_SLOT_IRQ_SLOT_2						0x04
+#define STDHOST_SLOT_IRQ_SLOT_3						0x08
+#define STDHOST_SLOT_IRQ_SLOT_4						0x10
+#define STDHOST_SLOT_IRQ_SLOT_5						0x20
+#define STDHOST_SLOT_IRQ_SLOT_6						0x40
+#define STDHOST_SLOT_IRQ_SLOT_7						0x80
+#define STDHOST_HOST_CONTROLLER_VERSION		0xFE    // 2 byte
+#define GET_VENDOR_VERSION_NR(x)					((x)>>8)
+#define GET_SPEC_VERSION_NR(x)						((x)&0x00FF)
+// FPGA specific registers
+#define FPGA_CORE_CTRL_REG									0x200
+#define FPGA_RAISING_EDGE								(1 << 8)
+#define FPGA_CARD_REVISION								0x210
+#define FPGA_CARD_REV_1_0									0x10
+#define FPGA_CARD_REV_1_1									0x11
+#define FPGA_CHIP_REVISION								0x211
+#define FPGA_CHIP_REV_1_0									0x10    // SDIO/SPI
+#define FPGA_CHIP_REV_1_1									0x11    // SDIO/SPI/G-SPI
+#define FPGA_CHIP_REV_2_0									0x20    // SDIO/SPI/G-SPI/DMA
+#define FPGA_CONFIG_ID										0x212
+#define FPGA_CONFIG_3_3_V									(1<<0)
+#define FPGA_CONFIG_2_5_V									(1<<1)
+#define FPGA_CONFIG_1_8_V									(1<<2)
+#define FPGA_POWER_REG_DATA								0x20C
+#define FPGA_POWER_REG_3_3_V							0xEF
+#define FPGA_POWER_REG_2_5_V              0xDC
+#define FPGA_POWER_REG_1_8_V              0xCC
+#define FPGA_POWER_REG_CMD								0x20D
+#define FPGA_POWER_REG_CMD_START					0x80
+#define FPGA_POWER_REG_STATUS							0x20E
+#define FPGA_POWER_REG_STABLE							(1<<0)
+#define FPGA_POWER_REG_1_8_V_MIN            0xBC        // 1.54 V
+#define FPGA_POWER_REG_1_8_V_MAX            0xD9        // 2.31 V
+#define FPGA_POWER_REG_2_5_V_MIN            0xCF        // 1.98 V
+#define FPGA_POWER_REG_2_5_V_MAX            0xEC        // 3.08 V
+#define FPGA_POWER_REG_3_3_V_MIN            0xE8        // 2.70 V
+#define FPGA_POWER_REG_3_3_V_MAX            0xEF        // 3.30 V
+#define FPGA_POWER_REG_0_7_V		    0x88        // 0.72 V
+#define FPGA_POWER_REG_0_8_V		    0x8B        // 0.78 V
+#define FPGA_POWER_REG_0_9_V		    0x98        // 0.90 V
+#define FPGA_POWER_REG_1_0_V		    0x9B        // 0.97 V
+#define FPGA_POWER_REG_1_1_V		    0xA8        // 1.08 V
+#define FPGA_POWER_REG_1_2_V		    0xAB        // 1.17 V
+#define FPGA_POWER_REG_1_2_5_V		    0xAC        // 1.23 V
+#define FPGA_POWER_REG_1_3_V		    0xAF        // 1.32 V
+#define FPGA_POWER_REG_1_4_V		    0xBA        // 1.42 V
+#define FPGA_POWER_REG_1_5_V		    0xBC        // 1.53 V
+#define FPGA_POWER_REG_1_6_V		    0xC8        // 1.62 V
+#define FPGA_POWER_REG_1_8_V		    0xCC        // 1.84 V
+#define FPGA_POWER_REG_2_0_V		    0xCF        // 1.98 V
+#define FPGA_POWER_REG_2_2_V		    0xD8        // 2.25 V
+#define FPGA_POWER_REG_2_4_V		    0xDB        // 2.43 V
+#define FPGA_POWER_REG_2_6_V		    0xDD        // 2.62 V
+#define FPGA_POWER_REG_2_7_V		    0xDF        // 2.75 V
+#define FPGA_POWER_REG_2_9_V		    0xEB        // 2.92 V
+#define FPGA_POWER_REG_3_1_V		    0xED        // 3.15 V
+#define FPGA_POWER_REG_3_3_V		    0xEF        // 3.30 V
+#define FPGA_POWER_STEPS		    20
+//[mb] 300 is a good value for 3.3V
+#define FPGA_POWER_RAMP_DELAY		300
+#define FPGA_POWER_VAL_ENUM	{ \
+				FPGA_POWER_REG_0_7_V, \
+				FPGA_POWER_REG_0_8_V, \
+				FPGA_POWER_REG_0_9_V, \
+				FPGA_POWER_REG_1_0_V, \
+				FPGA_POWER_REG_1_1_V, \
+				FPGA_POWER_REG_1_2_V, \
+				FPGA_POWER_REG_1_2_5_V, \
+				FPGA_POWER_REG_1_3_V, \
+				FPGA_POWER_REG_1_4_V, \
+				FPGA_POWER_REG_1_5_V, \
+				FPGA_POWER_REG_1_6_V, \
+				FPGA_POWER_REG_1_8_V, \
+				FPGA_POWER_REG_2_0_V, \
+				FPGA_POWER_REG_2_2_V, \
+				FPGA_POWER_REG_2_4_V, \
+				FPGA_POWER_REG_2_6_V, \
+				FPGA_POWER_REG_2_7_V, \
+				FPGA_POWER_REG_2_9_V, \
+				FPGA_POWER_REG_3_1_V, \
+				FPGA_POWER_REG_3_3_V}
+#define SK_SLOT_0	0
+#define SK_SLOT_1	1
+#define SK_BAR( _pObj, _nr ) ((PSD_DEVICE_DATA)(_pObj)->IOBase[_nr])
+//
+//          PCI memory mapped I/O access routines
+//
+#define MEM_WRITE_UCHAR(_pObj,_base, _offset, _value)  *(SK_U8 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset)) = (SK_U8)(_value)
+#define MEM_WRITE_USHORT(_pObj,_base, _offset, _value) *(SK_U16 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset)) = (SK_U16)(_value)
+#define MEM_WRITE_ULONG(_pObj,_base, _offset, _value)  *(SK_U32 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset)) = (SK_U32)(_value)
+/*
+#define MEM_WRITE_UCHAR(_pObj,_base, _offset, _value)\
+	printk("wr-uc:%p=0x%2.02X\n",(SK_U8 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset)),(SK_U8)(_value));\
+  *(SK_U8 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset)) = (SK_U8)(_value)
+
+#define MEM_WRITE_USHORT(_pObj,_base, _offset, _value)\
+	printk("wr-us:%p=0x%4.04X\n",(SK_U16 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset)),(SK_U16)(_value));\
+ *(SK_U16 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset)) = (SK_U16)(_value)
+
+#define MEM_WRITE_ULONG(_pObj,_base, _offset, _value)\
+	printk("wr-ul:%p=0x%8.08X\n",(SK_U32 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset)),(SK_U32)(_value));\
+  *(SK_U32 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset)) = (SK_U32)(_value)
+*/
+#define MEM_READ_UCHAR(_pObj,_base, _offset, _pBuf)  *(SK_U8 *)(_pBuf) = *(volatile SK_U8 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset))
+#define MEM_READ_USHORT(_pObj,_base, _offset, _pBuf) *(SK_U16 *)(_pBuf) = *(volatile SK_U16 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset))
+#define MEM_READ_ULONG(_pObj,_base, _offset, _pBuf)  *(SK_U32 *)(_pBuf) = *(volatile SK_U32 *)(((SK_U32)(SK_BAR((_pObj),(_base))))+(_offset))
+void SDHost_Init(PSD_DEVICE_DATA pDev);
+SK_BOOL SDHost_isCardPresent(PSD_DEVICE_DATA pDev);
+SK_BOOL isCmdFailed(PSD_DEVICE_DATA pDev);
+SK_BOOL SDHost_InitializeCard(PSD_DEVICE_DATA pDev);
+VOID SDHost_EnableInterrupt(PSD_DEVICE_DATA pDev, SK_U16 mask);
+VOID SDHost_DisableInterrupt(PSD_DEVICE_DATA pDev, SK_U16 mask);
+VOID SDHost_if_EnableInterrupt(PSD_DEVICE_DATA pDev);
+VOID SDHost_if_DisableInterrupt(PSD_DEVICE_DATA pDev);
+SK_BOOL SDHost_ReadOCR(PSD_DEVICE_DATA pDev, SK_U8 * pOcr);
+SK_BOOL SDHost_SendCmd(PSD_DEVICE_DATA pDev, SK_U8 cmd, SK_U32 arg,
+                       SK_U16 transferMode, SK_U32 * pulResp);
+VOID SDHost_SetCardOutEvent(PSD_DEVICE_DATA pDev);
+SK_BOOL SDHost_WriteOCR(PSD_DEVICE_DATA pDev, SK_U8 * pOcr);
+SK_BOOL SDHost_ReadRCA(PSD_DEVICE_DATA pDev, SK_U8 * pRca);
+SK_BOOL SDHost_SendAbort(PSD_DEVICE_DATA pDev);
+SK_BOOL SDHost_CMD52_Write(PSD_DEVICE_DATA pDev, SK_U32 Offset,
+                           SK_U8 function_number, SK_U8 Data);
+SK_BOOL SDHost_CMD52_Read(PSD_DEVICE_DATA pDev, SK_U32 Offset,
+                          SK_U8 function_number, SK_U8 * pReturnData);
+SK_BOOL SDHost_ReadCIS(PSD_DEVICE_DATA pDev, SK_U8 function_number,
+                       SK_U8 cistpl, SK_U8 * pBuf, SK_U32 * length);
+SK_BOOL SDHost_CMD53_Write(PSD_DEVICE_DATA pDev, SK_U32 Offset,
+                           SK_U8 function_number, SK_U8 mode, SK_U8 opcode,
+                           SK_U8 * pData, SK_U32 Count, SK_U32 blksz);
+SK_BOOL SDHost_CMD53_Write_DMA(PSD_DEVICE_DATA pDev, SK_U32 Offset,
+                               SK_U8 function_number, SK_U8 mode, SK_U8 opcode,
+                               SK_U8 * pData, SK_U32 Count, SK_U32 blksz);
+SK_BOOL SDHost_CMD53_Read(PSD_DEVICE_DATA pDev, SK_U32 Offset,
+                          SK_U8 function_number, SK_U8 mode, SK_U8 opcode,
+                          SK_U8 * pData, SK_U32 Count, SK_U32 blksz);
+SK_BOOL SDHost_CMD53_Read_DMA(PSD_DEVICE_DATA pDev, SK_U32 Offset,
+                              SK_U8 function_number, SK_U8 mode, SK_U8 opcode,
+                              SK_U8 * pData, SK_U32 Count, SK_U32 blksz);
+
+SK_BOOL SDHost_CMD53_WriteEx(PSD_DEVICE_DATA pDev,
+                             SK_U32 Offset,
+                             SK_U8 function_number,
+                             SK_U8 mode,
+                             SK_U8 opcode,
+                             SK_U8 * pData, SK_U32 Count, SK_U32 blksz);
+
+SK_BOOL SDHost_CMD53_ReadEx(PSD_DEVICE_DATA pDev,
+                            SK_U32 Offset,
+                            SK_U8 function_number,
+                            SK_U8 mode,
+                            SK_U8 opcode,
+                            SK_U8 * pData, SK_U32 Count, SK_U32 blksz);
+
+SK_BOOL SDHost_disable_host_int(PSD_DEVICE_DATA pDev, SK_U8 function_number,
+                                SK_U8 mask);
+SK_BOOL SDHost_enable_host_int(PSD_DEVICE_DATA pDev, SK_U8 function_number,
+                               SK_U8 mask);
+SK_U32 SDHost_send_cmd(PSD_DEVICE_DATA pDev, SK_U8 * payload, SK_U32 length,
+                       SK_BOOL wait_status);
+VOID SDHost_ErrorRecovery(PSD_DEVICE_DATA pDev);
+SK_BOOL SDHost_lockInterface(PSD_DEVICE_DATA pDev);
+VOID SDHost_unlockInterface(PSD_DEVICE_DATA pDev);
+VOID SDHost_SetLed(PSD_DEVICE_DATA pDev, SK_U8 led, SK_U8 on);
+VOID SDHost_PsState(PSD_DEVICE_DATA pDev, SK_U8 State); // pweber 17.08.2005
+SK_BOOL SDHost_SetGPO(PSD_DEVICE_DATA pDev, SK_U8 on);  // mmoser 2007-02-20
+SK_U32 SDHost_wait_event(PSD_DEVICE_DATA pDev, SDHOST_EVENT * pEvt, SK_U32 to);
+VOID SDHost_SetClock(PSD_DEVICE_DATA pDev, SK_U8 on);
+SK_BOOL SDHost_SetBusWidth(PSD_DEVICE_DATA pDev, SK_U8 width);
+VOID SDHost_SetClockSpeed(PSD_DEVICE_DATA pDev, SK_U32 bus_freq);
+SK_BOOL SDHost_Enable_HighSpeedMode(PSD_DEVICE_DATA pDev);
+SK_BOOL SDHost_Disable_HighSpeedMode(PSD_DEVICE_DATA pDev);
+
+#define LED_ON(x){\
+SK_U32 ___ulVal,___ulMask;\
+	MEM_READ_ULONG (pDev, SK_SLOT_0, 0x200,  &___ulVal);\
+	___ulMask = (1<<(16+(x)));\
+	___ulVal |= ___ulMask;\
+	MEM_WRITE_ULONG (pDev, SK_SLOT_0, 0x200,  ___ulVal);\
+}
+#define LED_OFF(x){\
+SK_U32 ___ulVal,___ulMask;\
+	MEM_READ_ULONG (pDev, SK_SLOT_0, 0x200,  &___ulVal);\
+	___ulMask = (1<<(16+(x)));\
+	___ulVal &= ~___ulMask;\
+	MEM_WRITE_ULONG (pDev, SK_SLOT_0, 0x200,  ___ulVal);\
+}
+
+#define GPO_ON(){\
+SK_U32 ___ulVal,___ulMask;\
+	MEM_READ_ULONG (pDev, SK_SLOT_0, 0x200,  &___ulVal);\
+	___ulMask = (1<<24);\
+	___ulVal |= ___ulMask;\
+	MEM_WRITE_ULONG (pDev, SK_SLOT_0, 0x200,  ___ulVal);\
+}
+#define GPO_OFF(){\
+SK_U32 ___ulVal,___ulMask;\
+	MEM_READ_ULONG (pDev, SK_SLOT_0, 0x200,  &___ulVal);\
+	___ulMask = (1<<24);\
+	___ulVal &= ~___ulMask;\
+	MEM_WRITE_ULONG (pDev, SK_SLOT_0, 0x200,  ___ulVal);\
+}
diff --git a/io/sdio/syskt/sdiobus.c b/io/sdio/syskt/sdiobus.c
new file mode 100644
index 0000000..ecb7107
--- /dev/null
+++ b/io/sdio/syskt/sdiobus.c
@@ -0,0 +1,2022 @@
+/**
+ *
+ * Name: sdiobus.c
+ * Project: Wireless LAN, Bus driver for SDIO interface
+ * Version: $Revision: 1.1 $
+ * Date: $Date: 2007/01/18 09:21:35 $
+ * Purpose: Bus driver for SDIO interface
+ * 
+ * Copyright (C) 2003-2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *	$Log: sdiobus.c,v $
+ *	Revision 1.1  2007/01/18 09:21:35  pweber
+ *	Put under CVS control
+ *	
+ *	Revision 1.2  2005/12/08 12:01:00  ebauer
+ *	Driver ckecks AND update voltage registry value if not correct
+ *	
+ *	Revision 1.1  2005/10/07 08:43:47  jschmalz
+ *	Put SDIO with FPGA under CVS control
+ *	
+ *	
+ ******************************************************************************/
+#ifndef _lint
+static const char SysKonnectFileId[] = "@(#)" __FILE__ " (C) Marvell ";
+#endif /* !_lint */
+
+#include "diagvers.h"           /* diag version control */
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+#include <linux/proc_fs.h>      // proc filesystem
+
+#ifdef DBG
+SK_U32 stdDebugLevel = DBG_DEFAULT;
+#endif // #ifdef DBG
+
+#define USE_DEBOUNCE_CARD_IN
+                                                                                                                                                                        /*--- mmoser 12/21/2006 ---*/
+#define MAX_DEBOUNCE_TIME 100
+
+DECLARE_MUTEX(sd_if_sema);
+DECLARE_MUTEX(sd_client_sema);
+
+static int sdio_major = 0;
+
+int mrvlsdio_open(struct inode *inode, struct file *filp);
+int mrvlsdio_release(struct inode *inode, struct file *filp);
+int SDIOBus_IoCtl(struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg);
+
+static void call_client_probe(PSD_DEVICE_DATA pDev, int fn);
+//
+// Module parameters
+//
+
+static int bus_type = SDIO_BUS_TYPE;
+static int bus_width = SDIO_1_BIT;
+int block_size = SD_BLOCK_SIZE;
+int dma_support = 1;
+static int clock_speed = 0;
+static int gpi_0_mode = 1;      // edge triggered
+static int gpi_0_level = 1;     // high->low 
+static int gpi_1_mode = 1;      // edge triggered
+static int gpi_1_level = 1;     // high-->low 
+#define INTMODE_SDIO	0
+#define INTMODE_GPIO	1
+int intmode = 0;                // GPIO intmode enabled
+int gpiopin = 0;                // GPIO pin number for SDIO alternative IRQ
+EXPORT_SYMBOL(intmode);
+EXPORT_SYMBOL(gpiopin);
+
+//static int debug_flags  = 0;
+static int debug_flags = 0x0c;
+
+static int sdio_voltage = FPGA_POWER_REG_3_3_V;
+
+DECLARE_WAIT_QUEUE_HEAD(add_remove_queue);
+
+// kernel 2.6.x
+module_param(bus_type, int, S_IRUGO);
+module_param(bus_width, int, S_IRUGO);
+module_param(block_size, int, S_IRUGO);
+module_param(clock_speed, int, S_IRUGO);
+module_param(dma_support, int, S_IRUGO);
+module_param(debug_flags, int, S_IRUGO);
+module_param(sdio_voltage, int, S_IRUGO);
+module_param(gpi_0_mode, int, S_IRUGO); // 0 = level triggered 1 = edge
+                                        // triggered
+module_param(gpi_0_level, int, S_IRUGO);        // 0 = low->high or low 1 =
+                                                // high->low or high
+module_param(gpi_1_mode, int, S_IRUGO); // 0 = level triggered 1 = edge
+                                        // triggered 
+module_param(gpi_1_level, int, S_IRUGO);        // 0 = low->high or low 1 =
+                                                // high->low or high 
+module_param(intmode, int, S_IRUGO);
+module_param(gpiopin, int, S_IRUGO);
+
+// prototypes
+// for filling the "/proc/mrvsdio" entry
+int mrvlsdio_read_procmem(char *buf, char **start, off_t offset, int count,
+                          int *eof, void *data);
+int sd_match_device(sd_driver * drv, PSD_DEVICE_DATA dev);
+
+// static PSD_DEVICE_DATA gSD_dev_data = NULL;
+
+struct list_head sd_dev_list;
+spinlock_t sd_dev_list_lock;
+unsigned long sd_dev_list_lock_flags;
+
+struct list_head sd_client_list;
+spinlock_t sd_client_list_lock;
+unsigned long sd_client_list_lock_flags;
+
+static int SDIOThread(void *data);
+
+static int probe(struct pci_dev *dev, const struct pci_device_id *id);
+static void remove(struct pci_dev *dev);
+
+static DECLARE_COMPLETION(on_exit);
+
+// kernel 2.6
+
+static struct pci_device_id ids[] = {
+    {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x8000),},
+    {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, ids);
+
+/*
+ * The fops
+ */
+
+struct file_operations mrvlsdio_fops = {
+  llseek:NULL,
+  read:NULL,
+  write:NULL,
+  ioctl:SDIOBus_IoCtl,
+  mmap:NULL,
+  open:mrvlsdio_open,
+  release:mrvlsdio_release,
+};
+
+/*
+ * Open and close
+ */
+
+int
+mrvlsdio_open(struct inode *inode, struct file *filp)
+{
+    ENTER();
+
+    if (list_empty(&sd_dev_list)) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG
+                  "mrvlsdio_open: sd_dev_list is empty -> Adapter not in CardBus slot!\n"));
+        return -ENODEV;
+    }
+
+    filp->f_op = &mrvlsdio_fops;
+
+    // Pointer to first device in list
+    // This works ONLY with one CardBus slot and one SDIO2PCI Adapter !!!
+    // With more SDIO2PCI Adapter we need to implement virtual devices
+    filp->private_data = sd_dev_list.next;
+
+    LEAVE();
+    return 0;                   /* success */
+}
+
+int
+mrvlsdio_release(struct inode *inode, struct file *filp)
+{
+    ENTER();
+    LEAVE();
+    return 0;
+}
+
+/*
+ * The ioctl() implementation
+ */
+
+int
+SDIOBus_IoCtl(struct inode *inode, struct file *filp,
+              unsigned int cmd, unsigned long arg)
+{
+    int ret = 0;
+    UCHAR ucValue;
+    ULONG ulValue;
+    ULONG cnt;
+    PSD_DEVICE_DATA sd_dev;
+
+    ENTER();
+
+    sd_dev = (SD_DEVICE_DATA *) filp->private_data;
+    if (sd_dev == NULL) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "SDIOBus_IoCtl : sd_dev= 0x%p !!!!!!!!!!!!!!!!\n",
+                  sd_dev));
+        return -ENOTTY;
+    }
+
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG
+              "SDIOBus_IoCtl : sd_dev= 0x%p sd_dev->IOBase[0]= 0x%p\n", sd_dev,
+              sd_dev->IOBase[0]));
+
+    switch (cmd) {
+    case IOCTL_SDIOBUSENUM_SET_VOLTAGE:
+        {
+            ret = get_user(ucValue, (int *) arg);
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG
+                      "SDIOBus_IoCtl : IOCTL_SDIOBUSENUM_SET_VOLTAGE: 0x%2.02X\n",
+                      ucValue));
+            MEM_WRITE_UCHAR(sd_dev, SK_SLOT_0, FPGA_POWER_REG_DATA, ucValue);
+            MEM_WRITE_UCHAR(sd_dev, SK_SLOT_0, FPGA_POWER_REG_CMD,
+                            FPGA_POWER_REG_CMD_START);
+            DBGPRINT(DBG_LOAD, (KERN_DEBUG "wait for stable voltage\n"));
+            cnt = 0;
+            do {
+                MEM_READ_UCHAR(sd_dev, SK_SLOT_0, FPGA_POWER_REG_STATUS,
+                               &ucValue);
+                DBGPRINT(DBG_LOAD,
+                         (KERN_DEBUG "PowerRegulatorControl: 0x%x\n", ucValue));
+            } while (++cnt < 10000 && (ucValue & FPGA_POWER_REG_STABLE) == 0);
+            DBGPRINT(DBG_LOAD,
+                     ("IOCTL_SDIOBUSENUM_SET_VOLTAGE: cnt=%d\n", cnt));
+            break;
+        }
+    case IOCTL_SDIOBUSENUM_GET_BOARDREV:
+        {
+            MEM_READ_ULONG(sd_dev, SK_SLOT_0, FPGA_CARD_REVISION, &ulValue);
+
+            ret = put_user(ulValue, (int *) arg);
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG
+                      "SDIOBus_IoCtl : IOCTL_SDIOBUSENUM_GET_BOARDREV 0x%8.08X\n",
+                      ulValue));
+            break;
+        }
+    case IOCTL_SDIOBUSENUM_GET_JUMPER:
+        {
+            DBGPRINT(DBG_LOAD, ("IOCTL_SDIOBUSENUM_GET_JUMPER\n"));
+            MEM_READ_ULONG(sd_dev, SK_SLOT_0, FPGA_CARD_REVISION, &ulValue);
+            ret = put_user(ulValue, (int *) arg);
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG
+                      "SDIOBus_IoCtl : IOCTL_SDIOBUSENUM_GET_JUMPER 0x%8.08X\n",
+                      ulValue));
+            break;
+        }
+
+    case IOCTL_SDIOBUSENUM_SET_BUSTYPE:
+        {
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG
+                      "SDIOBus_IoCtl : IOCTL_SDIOBUSENUM_SET_BUSTYPE --> IGNORED!\n"));
+            break;
+        }
+    case IOCTL_SDIOBUSENUM_SET_BUSWIDTH:
+        {
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG
+                      "SDIOBus_IoCtl : IOCTL_SDIOBUSENUM_SET_BUSWIDTH --> IGNORED!\n"));
+            break;
+        }
+    case IOCTL_SDIOBUSENUM_SET_CLKSPEED:
+        {
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG
+                      "SDIOBus_IoCtl : IOCTL_SDIOBUSENUM_SET_CLKSPEED --> IGNORED!\n"));
+            break;
+        }
+    default:
+        {
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG "SDIOBus_IoCtl : invalid cmd=%d (0x%8.08X)!\n",
+                      cmd, cmd));
+            return -ENOTTY;
+        }
+    }
+
+    LEAVE();
+    return ret;
+
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void
+card_out_work(PSD_DEVICE_DATA pDev)
+#else
+static void
+card_out_work(struct work_struct *work)
+#endif
+{
+    int j;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
+    PSD_DEVICE_DATA pDev = container_of(work, SD_DEVICE_DATA, card_out_work);
+#endif
+
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "%s: CARD_REMOVE_EVENT received.\n", __FUNCTION__));
+    for (j = 1; j <= pDev->number_of_functions; j++) {
+        if (down_interruptible(&sd_client_sema))
+            return;
+        if (pDev->sd_dev[j].drv != NULL && pDev->sd_dev[j].drv->remove != NULL) {
+            if (pDev->sd_dev[j].remove_called == 0) {
+                DBGPRINT(DBG_LOAD | DBG_ERROR,
+                         (KERN_DEBUG "%s: call remove() handler on fn=%d\n",
+                          __FUNCTION__, j));
+
+                pDev->sd_dev[j].probe_called = 0;
+                pDev->sd_dev[j].remove_called = 1;
+                pDev->sd_dev[j].dev = NULL;
+                pDev->sd_dev[j].drv->remove(&pDev->sd_dev[j]);
+            }
+        } else {
+            // If we have no remove() handler at this point, we will never get
+            // one. 
+            // So discard the CARD_REMOVE_EVENT to avoid an endless loop.
+            // This situation is considered a bug in the client driver !!!!
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG
+                      "%s: no remove() handler installed for fn=%d! Revise client driver!!!\n",
+                      __FUNCTION__, j));
+        }
+        up(&sd_client_sema);
+    }
+
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void
+card_irq_work(PSD_DEVICE_DATA pDev)
+#else
+static void
+card_irq_work(struct work_struct *work)
+#endif
+{
+    SK_U32 irq_handler_called;
+    SK_U8 int_pending;
+    SK_U32 ix;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
+    PSD_DEVICE_DATA pDev = container_of(work, SD_DEVICE_DATA, irq_work);
+#endif
+
+    irq_handler_called = 0;
+
+    // Read function specific interrupt information
+    GET_IF_SEMA_NO_RC();
+    if (SDHost_CMD52_Read(pDev, INT_PENDING_REG, 0, &int_pending)) {
+        REL_IF_SEMA();
+        DBGPRINT(DBG_IRQ,
+                 (KERN_DEBUG "INT Pending = 0x%2.02X\n ", int_pending));
+
+        for (ix = 1; ix <= 7; ix++) {
+            if (int_pending & INT(ix)) {
+                // Function ix interrupt is pending and enabled
+                if (pDev->irq_device_cache[ix] != NULL) {
+                    DBGPRINT(DBG_IRQ,
+                             (KERN_DEBUG
+                              "Call registered interrupt handler for function %d.\n",
+                              ix));
+                    irq_handler_called++;
+                    if (pDev->irq_device_cache[ix]->functions[ix].int_handler !=
+                        NULL) {
+                        pDev->irq_device_cache[ix]->functions[ix].
+                            int_handler(pDev->irq_device_cache[ix],
+                                        pDev->irq_device_cache[ix]->
+                                        pCurrent_Ids,
+                                        pDev->irq_device_cache[ix]->
+                                        functions[ix].context);
+                    }
+                }
+            }
+        }
+    } else
+        REL_IF_SEMA();
+
+    if (irq_handler_called == 0) {
+        DBGPRINT(DBG_IRQ,
+                 (KERN_DEBUG "No interrupt handler registered. (sd_dev=%p)\n",
+                  pDev));
+        SDHost_EnableInterrupt(pDev, pDev->lastIRQSignalMask);
+    }
+
+}
+
+static struct pci_driver mrvlsdio = {
+    .name = "mrvlsdio",
+    .id_table = ids,
+    .probe = probe,
+    .remove = remove,
+};
+
+static int
+probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+    int i, ret;
+    SK_U8 ucValue;
+    SK_U32 mem;
+    SK_U32 ulValue;
+    PSD_DEVICE_DATA pTmpDev;
+
+    DBGPRINT(DBG_LOAD, (KERN_DEBUG "mrvlsdio : probe()\n"));
+
+    if (pci_enable_device(dev)) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "mrvlsdio: pci_enable_device() failed\n"));
+        return -EIO;
+    }
+    if (pci_set_dma_mask(dev, 0xffffffff)) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "mrvlsdio: 32-bit PCI DMA not supported"));
+        pci_disable_device(dev);
+        return -EIO;
+    }
+    pci_set_master(dev);
+
+                                                                                                                                                                                /*--- mmoser 6/21/2007 ---*/
+    pTmpDev = (PSD_DEVICE_DATA) kmalloc(sizeof(SD_DEVICE_DATA), GFP_KERNEL);
+
+    if (pTmpDev == NULL) {
+        return -ENOMEM;
+    }
+#ifdef SDIO_MEM_TRACE
+    printk(">>> kmalloc(SD_DEVICE_DATA)\n");
+#endif
+
+    memset(pTmpDev, 0, sizeof(SD_DEVICE_DATA));
+
+    pTmpDev->IOBaseIx = 0;
+                                                                                                                                                                                /*--- mmoser 10/11/2006 ---*/
+    pTmpDev->dev = dev;
+    pTmpDev->workqueue = create_workqueue("MRVL-SDIO");
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+    INIT_WORK(&pTmpDev->irq_work, (void (*)(void *)) card_irq_work, pTmpDev);
+    INIT_WORK(&pTmpDev->card_out_work, (void (*)(void *)) card_out_work,
+              pTmpDev);
+#else
+    INIT_WORK(&pTmpDev->irq_work, card_irq_work);
+    INIT_WORK(&pTmpDev->card_out_work, card_out_work);
+#endif
+
+    if (pci_request_regions(dev, "MRVL-SDIO")) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "mrvlsdio: pci_request_regions() failed.\n"));
+        pci_disable_device(dev);
+        return -EIO;
+    }
+
+    for (i = 0; i < 5; i++) {
+        mem = pci_resource_start(dev, i);
+
+        if (mem != 0) {
+            if (IORESOURCE_MEM & pci_resource_flags(dev, i)) {
+                pTmpDev->IOBaseLength[pTmpDev->IOBaseIx] =
+                    pci_resource_end(dev, i) - mem + 1;
+                pTmpDev->IOBase[pTmpDev->IOBaseIx] =
+                    ioremap_nocache(mem,
+                                    pTmpDev->IOBaseLength[pTmpDev->IOBaseIx]);
+                DBGPRINT(DBG_LOAD,
+                         (KERN_DEBUG
+                          "mrvlsdio: IOBase[%d] = 0x%8.08X IOBaseLength = %u\n",
+                          i, (SK_U32) pTmpDev->IOBase[pTmpDev->IOBaseIx],
+                          pTmpDev->IOBaseLength[pTmpDev->IOBaseIx]));
+                pTmpDev->IOBaseIx++;
+                if (pTmpDev->IOBaseIx >= 2) {
+                    DBGPRINT(DBG_LOAD,
+                             (KERN_DEBUG
+                              "mrvlsdio : Too many memory address ranges!\n"));
+                    pTmpDev->IOBaseIx = 0;
+                }
+            }
+        }
+    }
+
+    // Dummy read. Function return SUCCESS but value is messy !!!
+    pci_read_config_byte(dev, PCI_INTERRUPT_LINE,
+                         (SK_U8 *) & pTmpDev->Interrupt);
+
+    for (i = 0; i < 3; i++) {
+        ret =
+            pci_read_config_byte(dev, PCI_INTERRUPT_LINE,
+                                 (SK_U8 *) & pTmpDev->Interrupt);
+        if (ret) {
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG
+                      "mrvlsdio: Failed to retrieve Interrupt Line (%d) %d ret=%d\n",
+                      i, pTmpDev->Interrupt, ret));
+            UDELAY(100);
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (i >= 3) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG
+                  "mrvlsdio: Failed to retrieve Interrupt Line (%d) ret=%d\n",
+                  i, ret));
+        return -ENODEV;
+    }
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: Interrupt Line = %d  (%d)\n",
+              pTmpDev->Interrupt, i));
+
+    MEM_READ_UCHAR(pTmpDev, SK_SLOT_0, FPGA_CARD_REVISION, &ucValue);
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: CardRevision: 0x%X (sd_dev_data=0x%p)\n",
+              ucValue, &pTmpDev));
+
+    pTmpDev->bus_type = bus_type;
+    pTmpDev->bus_width = bus_width;
+    pTmpDev->ClockSpeed = clock_speed;
+    pTmpDev->debug_flags = debug_flags;
+    pTmpDev->sdio_voltage = sdio_voltage;
+
+    pci_read_config_byte(dev, 0x0c, &ucValue);
+
+    if (ucValue == 0)
+        pci_write_config_byte(dev, 0x0c, 2);
+
+    pci_read_config_byte(dev, 0x0c, &ucValue);
+// printk("config[0x0c]=0x%2.02X\n",ucValue);
+    pci_read_config_byte(dev, 0x0d, &ucValue);
+    // printk("config[0x0d]=0x%2.02X\n",ucValue);
+    printk("debug_flags=0x%8.08X\n", debug_flags);
+
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: bus_type     : SDIO%s\n",
+              bus_type == SDIO_BUS_TYPE ? "" : "/SPI"));
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: bus_width    : %s\n",
+              bus_width == SDIO_4_BIT ? "4-bit" : "1-bit"));
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: block_size   : %d\n", block_size));
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: clock_speed  : %d\n", clock_speed));
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: debug_flags  : 0x%8.08X\n", debug_flags));
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: sdio_voltage : %d\n", sdio_voltage));
+
+                                                                                                                                                                        /*--- mmoser 3/12/2007 ---*/
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: gpi_0_mode   : %s triggered\n",
+              gpi_0_mode == 0 ? "level" : "edge"));
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: gpi_0_level  : %s\n",
+              gpi_0_level == 0 ? (gpi_0_mode ==
+                                  0 ? "low" : "low->high") : (gpi_0_mode ==
+                                                              0 ? "high" :
+                                                              "high->low")));
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: gpi_1_mode   : %s triggered\n",
+              gpi_1_mode == 0 ? "level" : "edge"));
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "mrvlsdio: gpi_1_level  : %s\n",
+              gpi_1_level == 0 ? (gpi_1_mode ==
+                                  0 ? "low" : "low->high") : (gpi_1_mode ==
+                                                              0 ? "high" :
+                                                              "high->low")));
+
+    // mmoser 2005-11-29
+    atomic_set(&pTmpDev->card_add_event, 0);
+    atomic_set(&pTmpDev->card_remove_event, 0);
+
+                                                                                                                                                                        /*--- mmoser 8/29/2006 ---*/
+    init_waitqueue_head(&pTmpDev->trans_complete_evt.wq);
+    init_waitqueue_head(&pTmpDev->cmd_complete_evt.wq);
+    init_waitqueue_head(&pTmpDev->thread_started_evt.wq);
+
+                                                                                                                                                                        /*--- mmoser 3/12/2007 ---*/
+    MEM_READ_ULONG(pTmpDev, SK_SLOT_0, 0x200, &ulValue);
+    ulValue &= 0x0FFFFFFF;
+    ulValue |=
+        ((gpi_1_mode << 3 | gpi_1_level << 2 | gpi_0_mode << 1 | gpi_0_level) <<
+         28);
+//      printk("mrvlsdio: ulValue = 0x%8.08X\n",ulValue);
+    MEM_WRITE_ULONG(pTmpDev, SK_SLOT_0, 0x200, ulValue);
+
+//      printk("mrvlsdio: reg[0x200] = 0x%8.08X\n",ulValue);
+
+    spin_lock_init(&pTmpDev->sd_dev_lock);
+
+    spin_lock_irqsave(&sd_dev_list_lock, sd_dev_list_lock_flags);
+    list_add_tail((struct list_head *) pTmpDev, &sd_dev_list);
+
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG
+              "%s@%d: sd_dev_list=%p sd_dev_list.prev=%p sd_dev_list.next=%p pTmpDev=%p\n",
+              __FUNCTION__, __LINE__, &sd_dev_list, sd_dev_list.prev,
+              sd_dev_list.next, pTmpDev));
+
+    spin_unlock_irqrestore(&sd_dev_list_lock, sd_dev_list_lock_flags);
+
+    SDHost_Init(pTmpDev);
+
+    // mmoser 2005-11-29
+    if (0 != request_irq(pTmpDev->Interrupt,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+                         SDIOBus_Isr, SA_SHIRQ,
+#else
+                         (irq_handler_t) SDIOBus_Isr, IRQF_SHARED,
+#endif
+                         MRVL_DEVICE_NAME, (PVOID) pTmpDev)
+        ) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG
+                  "mrvlsdio: Failed to register interrupt handler\n"));
+        return -ENODEV;
+    }
+
+    if (SDHost_isCardPresent(pTmpDev) == SK_TRUE) {
+        if (SDIOBus_CardPluggedIn(pTmpDev) == SK_TRUE) {
+            pTmpDev->CardIn = SK_TRUE;
+        }
+        SDHost_EnableInterrupt(pTmpDev, (STDHOST_NORMAL_IRQ_CARD_OUT_SIG_ENA |
+                                         STDHOST_NORMAL_IRQ_CARD_IN_SIG_ENA));
+    }
+#ifdef SYSKT_DMA_MALIGN_TEST
+    pTmpDev->dma_tx_malign = 0;
+    pTmpDev->dma_rx_malign = 0;
+    // pTmpDev->dma_start_malign = 4096 - 32;
+    pTmpDev->dma_start_malign = 0;
+#endif
+
+// mmoser 2005-11-22 start the thread as the last action
+
+// mmoser 2005-11-21
+    pTmpDev->stop_thread = SK_FALSE;
+
+    pTmpDev->thread_id = kernel_thread(SDIOThread,
+                                       pTmpDev,
+                                       (CLONE_FS | CLONE_FILES |
+                                        CLONE_SIGHAND));
+
+    if (pTmpDev->thread_id == 0) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "mrvlsdio: Failed to start kernel thread!\n"));
+        return -1;
+    } else {
+
+        if (SDHost_wait_event(pTmpDev, &pTmpDev->thread_started_evt, 1000)) {
+            pTmpDev->stop_thread = SK_TRUE;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+            kill_pid(find_get_pid(pTmpDev->thread_id), SIGTERM, 1);
+#else
+            kill_proc(pTmpDev->thread_id, SIGTERM, 1);
+#endif
+            pTmpDev->thread_id = 0;
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "%s @ %d: Wait SDIOThread started ---> FAILED !\n",
+                      __FUNCTION__, __LINE__));
+            return 0;
+        }
+
+    }
+
+    return 0;
+}
+
+static void
+remove(struct pci_dev *dev)
+{
+    struct list_head *pTmp;
+    struct list_head *pNext;
+    PSD_DEVICE_DATA pTmpDev;
+    int j;
+    SK_U8 ucValue;
+    SK_U32 cnt;
+
+    DBGPRINT(DBG_LOAD, (KERN_DEBUG "remove mrvlsdio ... \n"));
+
+    /* clean up any allocated resources and stuff here. like call
+       release_region(); */
+
+    /* 
+     *      iterate through the device list
+     *      call remove() for each client driver
+     *  remove device from list
+     *  free allocated memory
+     */
+    if (!list_empty(&sd_dev_list)) {
+        pTmp = sd_dev_list.next;
+
+        while (pTmp != &sd_dev_list) {
+            pNext = pTmp->next;
+            pTmpDev = (PSD_DEVICE_DATA) pTmp;
+            if (pTmpDev->dev == dev) {
+                pTmpDev->isRemoving = SK_TRUE;
+                for (j = 1; j <= pTmpDev->number_of_functions; j++) {
+                    if (down_interruptible(&sd_client_sema))
+                        return;
+                    if (pTmpDev->sd_dev[j].drv != NULL &&
+                        pTmpDev->sd_dev[j].drv->remove != NULL) {
+                        if (pTmpDev->sd_dev[j].remove_called == 0) {
+                            pTmpDev->sd_dev[j].probe_called = 0;
+                            pTmpDev->sd_dev[j].remove_called = 1;
+                            pTmpDev->sd_dev[j].dev = NULL;
+                            pTmpDev->sd_dev[j].drv->remove(&pTmpDev->sd_dev[j]);
+                        }
+                    }
+                    up(&sd_client_sema);
+                }
+
+                if (pTmpDev->thread_id) {
+                    pTmpDev->stop_thread = SK_TRUE;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                    kill_pid(find_get_pid(pTmpDev->thread_id), SIGTERM, 1);
+#else
+                    kill_proc(pTmpDev->thread_id, SIGTERM, 1);
+#endif
+                    wait_for_completion(&on_exit);
+                    DBGPRINT(DBG_LOAD,
+                             (KERN_DEBUG "%s: SDIOThread killed ... \n",
+                              __FUNCTION__));
+                }
+                // Send I/O Card Reset
+                SDHost_CMD52_Write((PSD_DEVICE_DATA) pTmp, IO_ABORT_REG, FN0,
+                                   RES);
+                SDHost_DisableInterrupt((PSD_DEVICE_DATA) pTmp,
+                                        STDHOST_NORMAL_IRQ_ALL_SIG_ENA);
+                SDHost_SetClock((PSD_DEVICE_DATA) pTmp, 0);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+                cancel_delayed_work(&pTmpDev->card_out_work);
+                cancel_delayed_work(&pTmpDev->irq_work);
+#endif
+                flush_scheduled_work();
+                destroy_workqueue(pTmpDev->workqueue);
+                pTmpDev->workqueue = NULL;
+
+                // set host power voltage as low as possible
+                // (still need despite "turn off host power" below, b/c
+                // hotplug can reactivate host power independently in HW)
+                MEM_WRITE_UCHAR((PSD_DEVICE_DATA) pTmp, SK_SLOT_0,
+                                FPGA_POWER_REG_DATA, FPGA_POWER_REG_0_7_V);
+                MEM_WRITE_UCHAR((PSD_DEVICE_DATA) pTmp, SK_SLOT_0,
+                                FPGA_POWER_REG_CMD, FPGA_POWER_REG_CMD_START);
+                DBGPRINT(DBG_LOAD, (KERN_DEBUG "wait for stable voltage\n"));
+                cnt = 0;
+                do {
+                    MEM_READ_UCHAR((PSD_DEVICE_DATA) pTmp, SK_SLOT_0,
+                                   FPGA_POWER_REG_STATUS, &ucValue);
+                    DBGPRINT(DBG_LOAD,
+                             (KERN_DEBUG "PowerRegulatorControl: 0x%x\n",
+                              ucValue));
+                } while (++cnt < 10000 &&
+                         (ucValue & FPGA_POWER_REG_STABLE) == 0);
+                DBGPRINT(DBG_LOAD, ("REMOVE_SET_VOLTAGE: cnt=%d\n", cnt));
+
+                // turn off host power
+                MEM_READ_UCHAR((PSD_DEVICE_DATA) pTmp, SK_SLOT_0,
+                               STDHOST_POWER_CTRL, &ucValue);
+                MEM_WRITE_UCHAR((PSD_DEVICE_DATA) pTmp, SK_SLOT_0,
+                                STDHOST_POWER_CTRL,
+                                ucValue & ~STDHOST_POWER_ON);
+
+                // give some time for host power off to settle
+                mdelay(200);
+
+                free_irq(pTmpDev->Interrupt, pTmpDev);
+                for (j = 0; j < pTmpDev->IOBaseIx; j++)
+                    iounmap(pTmpDev->IOBase[j]);
+                                /*--- mmoser 10/11/2006 ---*/
+                pci_release_regions(pTmpDev->dev);
+
+                list_del((struct list_head *) pTmpDev);
+                kfree(pTmpDev);
+
+#ifdef SDIO_MEM_TRACE
+                printk("<<< kfree(SD_DEVICE_DATA)\n");
+#endif
+
+                return;
+            }
+            pTmp = pNext;
+        }
+    }
+
+}
+
+BOOLEAN
+SDIOBus_CardRemoved(PSD_DEVICE_DATA SdData)
+{
+    SK_U32 ulVal;
+
+    ENTER();
+
+#ifdef USE_DEBOUNCE_CARD_IN
+
+                                                                                                                                                                        /*--- mmoser 12/21/2006 ---*/
+    mdelay(MAX_DEBOUNCE_TIME);
+
+    // Read present state register to check whether a SD card is present
+    MEM_READ_ULONG(SdData, SK_SLOT_0, STDHOST_PRESENT_STATE, &ulVal);
+    if ((ulVal & STDHOST_STATE_CARD_INSERTED) == 1) {
+        // There is probably still a card in the socket
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG
+                  "SDHost_isCardPresent(): Card is present. (%8.08X)\n",
+                  ulVal));
+        return SK_FALSE;
+    }
+#endif // USE_DEBOUNCE_CARD_IN
+
+    SdData->CardIn = SK_FALSE;
+
+    // mmoser 2005-11-29
+    queue_work(SdData->workqueue, &SdData->card_out_work);
+
+    LEAVE();
+    return SK_TRUE;
+}
+
+BOOLEAN
+SDIOBus_CardPluggedIn(PSD_DEVICE_DATA SdData)
+{
+    SK_U32 ulVal;
+
+    ENTER();
+
+#ifdef USE_DEBOUNCE_CARD_IN
+
+                                                                                                                                                                        /*--- mmoser 12/21/2006 ---*/
+    mdelay(MAX_DEBOUNCE_TIME);
+
+    // Read present state register to check whether a SD card is present
+    MEM_READ_ULONG(SdData, SK_SLOT_0, STDHOST_PRESENT_STATE, &ulVal);
+    if ((ulVal & STDHOST_STATE_CARD_INSERTED) == 0) {
+        // There is probably no card in the socket
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG
+                  "SDHost_isCardPresent(): Card is NOT present. (%8.08X)\n",
+                  ulVal));
+        return SK_FALSE;
+    }
+#endif // USE_DEBOUNCE_CARD_IN
+
+    SDHost_Init(SdData);
+
+    if (!SDHost_InitializeCard(SdData)) {
+        SDHost_EnableInterrupt(SdData, SdData->lastIRQSignalMask);
+        return SK_FALSE;
+    }
+    SdData->CardIn = SK_TRUE;
+    DBGPRINT(DBG_LOAD, (KERN_DEBUG "Device Name : %s\n", SdData->DeviceName));
+
+    // mmoser 2005-11-29
+    atomic_inc(&SdData->card_add_event);
+    LEAVE();
+    return SK_TRUE;
+}
+
+static int
+SDIOThread(void *data)
+{
+    SK_U16 usVal;
+    SK_U32 card_in = 0;
+    SK_U32 card_out = 0;
+    PSD_DEVICE_DATA pDev;
+    int clients_found;
+    int fn = 0;
+    int j;
+    struct list_head *pTmp;
+    PSD_CLIENT pClientTmp;
+    int fn_mask;
+    u8 attached_fn[MAX_SDIO_FUNCTIONS];
+
+    daemonize("SDIOThread");
+    allow_signal(SIGTERM);
+
+    DBGPRINT(DBG_LOAD, (KERN_DEBUG "SDIOThread() started ... \n"));
+
+    if (data == NULL) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "SDIOThread() data == NULL !\n"));
+        complete_and_exit(&on_exit, 0);
+        return 1;
+    }
+    pDev = (PSD_DEVICE_DATA) data;
+
+    LED_OFF(4);
+
+    if (!test_and_set_bit(0, &pDev->thread_started_evt.event)) {
+        wake_up(&pDev->thread_started_evt.wq);
+    }
+
+    while (pDev != NULL && !pDev->stop_thread) {
+        LED_ON(4);
+
+// mmoser 2005-11-21
+        // Read the Host Controller Version to check if SD Host adapter is
+        // available
+        MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_HOST_CONTROLLER_VERSION,
+                        &usVal);
+        if (usVal == 0xFFFF) {
+            // There is probably no SD Host Adapter available
+            printk("%s: SD Host Adapter is NOT present.\n", __FUNCTION__);
+            pDev->SurpriseRemoved = SK_TRUE;
+            pDev->CardIn = SK_FALSE;
+            pDev->thread_id = 0;
+            DBGPRINT(DBG_LOAD, (KERN_DEBUG "SDIOThread terminated ... \n"));
+            complete_and_exit(&on_exit, 0);
+            return -ENODEV;
+        }
+// mmoser 2005-11-29
+        card_in = atomic_read(&pDev->card_add_event);
+        card_out = atomic_read(&pDev->card_remove_event);
+
+        if (card_in == 0 && card_out == 0) {
+            LED_OFF(4);
+                                                                                                                                                                        /*--- mmoser 6/21/2006 ---*/
+            set_current_state(TASK_INTERRUPTIBLE);
+            schedule_timeout(10);
+            continue;
+        }
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "%s: card_in=%d card_out=%d\n", __FUNCTION__,
+                  card_in, card_out));
+
+        // mmoser 2005-11-29
+        if (card_in > 0) {
+
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG "%s: CARD_ADD_EVENT received.\n",
+                      __FUNCTION__));
+
+            // Check whether we have a client driver in the global list for
+            // this device
+            if (!list_empty(&sd_client_list)) {
+                spin_lock_irqsave(&sd_client_list_lock,
+                                  sd_client_list_lock_flags);
+
+                fn = pDev->number_of_functions + 1;
+
+                clients_found = 0;
+
+                // walk through the list of client drivers
+                list_for_each(pTmp, &sd_client_list) {
+                    pClientTmp = (PSD_CLIENT) pTmp;
+                    if ((fn_mask = sd_match_device(pClientTmp->drv, pDev)) > 0) {
+                        // Matching client driver found
+                        // Assign the client driver to the lowest supported
+                        // function
+                        for (fn = 1; fn <= pDev->number_of_functions; fn++) {
+                            if ((fn_mask & (1 << fn)) != 0) {
+                                pDev->sd_dev[fn].drv = pClientTmp->drv;
+                                pDev->sd_dev[fn].supported_functions = fn_mask;
+                                pDev->sd_dev[fn].cisptr = &pDev->cisptr[0];
+                                pDev->sd_dev[fn].sd_bus = pDev; // Backpointer
+                                                                // to bus
+                                                                // driver's
+                                                                // device
+                                                                // structure
+                                pDev->sd_dev[fn].dev = &pDev->dev->dev; // Generic 
+                                                                        // device 
+                                                                        // interface 
+                                                                        // for
+                                                                        // hotplug
+                                attached_fn[clients_found] = fn;
+                                clients_found++;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                spin_unlock_irqrestore(&sd_client_list_lock,
+                                       sd_client_list_lock_flags);
+
+                if (clients_found) {
+                    // Call probe() for each previously attached client driver
+                    for (j = 0; j < clients_found; j++) {
+                        fn = attached_fn[j];
+                        if (pDev->sd_dev[fn].drv->probe != NULL) {
+                            if (pDev->sd_dev[fn].probe_called == 0) {
+                                DBGPRINT(DBG_LOAD | DBG_ERROR,
+                                         (KERN_DEBUG
+                                          "%s: call probe() handler on fn=%d\n",
+                                          __FUNCTION__, fn));
+
+                                pDev->SurpriseRemoved = 0;
+                                pDev->sd_dev[fn].probe_called = 1;
+                                pDev->sd_dev[fn].remove_called = 0;
+                                call_client_probe(pDev, fn);
+                            }
+                        } else {
+                            // If we have no probe() handler at this point, we
+                            // will never get one. 
+                            // So discard the CARD_ADD_EVENT to avoid an
+                            // endless loop.
+                            // This situation is considered a bug in the client 
+                            // driver !!!!
+                            DBGPRINT(DBG_LOAD,
+                                     (KERN_DEBUG
+                                      "%s@%d: no probe() handler installed for fn=%d! Revise client driver!!!\n",
+                                      __FUNCTION__, __LINE__, fn));
+                        }
+                    }
+                } else {
+                    // There is at least one client driver registered with our
+                    // bus driver
+                    // but the sd_device_ids of this driver does not match the
+                    // ids of the inserted card.
+                    // We have to wait until a matching driver will be
+                    // installed.
+
+                    DBGPRINT(DBG_LOAD,
+                             (KERN_DEBUG
+                              "%s@%d: no matching client driver installed.\n",
+                              __FUNCTION__, __LINE__));
+                }
+            } else {
+                // Until there is no client driver registered with our bus
+                // driver.
+
+                DBGPRINT(DBG_LOAD,
+                         (KERN_DEBUG "%s@%d: no client driver installed.\n",
+                          __FUNCTION__, __LINE__));
+            }
+
+            // We can reset the card event here since the association with a
+            // matching client driver
+            // is already done or will be done in sd_register_driver()
+            atomic_set(&pDev->card_add_event, 0);
+
+        }
+        // mmoser 2005-11-29
+        else if (card_out > 0) {
+            DBGPRINT(DBG_LOAD,
+                     (KERN_DEBUG "%s: CARD_REMOVE_EVENT received.\n",
+                      __FUNCTION__));
+            for (j = 1; j <= pDev->number_of_functions; j++) {
+                if (down_interruptible(&sd_client_sema))
+                    return 0;
+                if (pDev->sd_dev[j].drv != NULL &&
+                    pDev->sd_dev[j].drv->remove != NULL) {
+                    if (pDev->sd_dev[j].remove_called == 0) {
+                        DBGPRINT(DBG_LOAD | DBG_ERROR,
+                                 (KERN_DEBUG
+                                  "%s: call remove() handler on fn=%d\n",
+                                  __FUNCTION__, j));
+
+                        pDev->sd_dev[j].probe_called = 0;
+                        pDev->sd_dev[j].remove_called = 1;
+                        pDev->sd_dev[j].dev = NULL;
+                        pDev->sd_dev[j].drv->remove(&pDev->sd_dev[j]);
+                    }
+                } else {
+                    // If we have no remove() handler at this point, we will
+                    // never get one. 
+                    // So discard the CARD_REMOVE_EVENT to avoid an endless
+                    // loop.
+                    // This situation is considered a bug in the client driver
+                    // !!!!
+                    DBGPRINT(DBG_LOAD,
+                             (KERN_DEBUG
+                              "%s: no remove() handler installed for fn=%d! Revise client driver!!!\n",
+                              __FUNCTION__, j));
+                }
+                up(&sd_client_sema);
+            }
+            atomic_set(&pDev->card_remove_event, 0);
+        } else {
+            DBGPRINT(DBG_LOAD, (KERN_DEBUG "SDIOThread terminated ... \n"));
+            pDev->thread_id = 0;
+            complete_and_exit(&on_exit, 0);
+            return 1;
+        }
+    }
+
+    DBGPRINT(DBG_LOAD, (KERN_DEBUG "SDIOThread terminated ... \n"));
+
+    if (pDev != NULL) {
+        pDev->thread_id = 0;
+    }
+
+    complete_and_exit(&on_exit, 0);
+
+    return 0;
+}
+
+/*************************  New SDIO Bus Driver API   ************************/
+
+/** 
+ *  @brief This function matches a client driver with a SDIO device
+ *  @param drv		pointer to client drivers device IDs
+ *  @param dev    pointer to SDIO device
+ *  @return				mask with supported functions  -> 0 means no match found
+ * 
+ * 								76543210
+ * 								||||||+-- fn 1 supported
+ * 								|||||+--- fn 2 supported
+ * 								||||+---- fn 3 supported
+ * 								|||+----- fn 4 supported
+ * 								||+------ fn 5 supported
+ * 								|+------- fn 6 supported
+ * 								+-------- fn 7 supported
+ * 
+ * 								0x02  -> fn 1 supported
+ * 								0x06  -> fn 1 and 2 supported
+ * 								0x12  -> fn 1 and 4 supported
+*/
+int
+sd_match_device(sd_driver * drv, PSD_DEVICE_DATA dev)
+{
+    psd_device_id pIds;
+    int i;
+    int matched_fn = 0;
+    int fn_mask = 0;
+
+    DBGPRINT(DBG_API,
+             (KERN_DEBUG
+              "%s: drv-name: %s device: vendor=0x%4.04X device=0x%4.04X\n",
+              __FUNCTION__, drv->name, dev->sd_ids[0].vendor,
+              dev->sd_ids[0].device));
+
+    for (pIds = drv->ids; pIds->device != 0 ||
+         pIds->vendor != 0 || pIds->class != 0 || pIds->fn != 0; pIds++) {
+        DBGPRINT(DBG_API,
+                 (KERN_DEBUG
+                  "vendor=0x%4.04X device=0x%4.04X class=0x%4.04X fn=0x%4.04X\n",
+                  pIds->vendor, pIds->device, pIds->class, pIds->fn));
+        if ((pIds->vendor != SD_VENDOR_ANY) &&
+            (pIds->vendor != dev->sd_ids[0].vendor)) {
+            continue;
+        }
+        if (pIds->device != SD_DEVICE_ANY) {
+            matched_fn = 0;
+            for (i = 0; i <= dev->number_of_functions; i++) {
+                if (pIds->device == dev->sd_ids[i].device) {
+                    matched_fn = i;
+                    fn_mask |= (1 << matched_fn);
+                    DBGPRINT(DBG_API,
+                             (KERN_DEBUG "driver matches with function %d\n",
+                              i));
+                    break;
+                }
+            }
+            if (matched_fn == 0) {
+                continue;
+            }
+        }
+        if (pIds->class != SD_CLASS_ANY) {
+            matched_fn = 0;
+            for (i = 1; i <= dev->number_of_functions; i++) {
+//                              printk("fn[%d] class-id=0x%4.04X\n",i,dev->sd_ids[i].class);
+                if (pIds->class == dev->sd_ids[i].class) {
+                    matched_fn = i;
+                    fn_mask |= (1 << matched_fn);
+                    DBGPRINT(DBG_API,
+                             (KERN_DEBUG "driver matches with function %d\n",
+                              i));
+                    break;
+                }
+            }
+            if (matched_fn == 0) {
+                continue;
+            }
+        } else {
+            // At this point vendor==ANY && device==ANY && class==ANY
+            // Now we have to check whether the card supports the desired
+            // function number
+            if (pIds->fn > 0 && pIds->fn <= dev->number_of_functions) {
+                matched_fn = pIds->fn;
+                fn_mask |= (1 << matched_fn);
+            }
+        }
+
+        if ((pIds->fn != SD_FUNCTION_ANY) && (pIds->fn != matched_fn)) {
+            continue;
+        }
+    }
+
+    printk("%s: supported function mask = 0x%2.02X\n", __FUNCTION__, fn_mask);
+    return (fn_mask);
+}
+
+/** 
+ *  @brief This function registers a client driver with the bus driver using device IDs
+ *  @param drv		pointer to client drivers device IDs and call backs
+ *  @return				0 : Success < 0: Failed  
+*/
+int
+sd_driver_register(sd_driver * drv)
+{
+    struct list_head *pTmp;
+    PSD_CLIENT pClientTmp;
+    PSD_DEVICE_DATA pDevTmp;
+    int fn_mask;
+    int fn;
+
+    GET_IF_SEMA();
+
+    ENTER();
+
+    pClientTmp = (PSD_CLIENT) kmalloc(sizeof(SD_CLIENT), GFP_KERNEL);
+
+    if (pClientTmp == NULL) {
+        REL_IF_SEMA();
+        LEAVE();
+        return -ENOMEM;
+    }
+#ifdef SDIO_MEM_TRACE
+    printk(">>> kmalloc(SD_CLIENT)\n");
+#endif
+
+    memset(pClientTmp, 0, sizeof(SD_CLIENT));
+
+    pClientTmp->drv = drv;
+
+    // Check whether there is a SDIO device available
+    if (!list_empty(&sd_dev_list)) {
+        list_for_each(pTmp, &sd_dev_list) {
+            pDevTmp = (PSD_DEVICE_DATA) pTmp;
+
+            spin_lock_irqsave(&pDevTmp->sd_dev_lock,
+                              pDevTmp->sd_dev_lock_flags);
+            if ((fn_mask = sd_match_device(drv, pDevTmp)) > 0) {
+                // Assign the client driver to the lowest supported function
+                for (fn = 1; fn <= pDevTmp->number_of_functions; fn++) {
+                    if ((fn_mask & (1 << fn)) != 0) {
+                        break;
+                    }
+                }
+                if (fn <=
+                    MIN(pDevTmp->number_of_functions, MAX_SDIO_FUNCTIONS - 1)) {
+                    if (pDevTmp->sd_dev[fn].drv == NULL) {
+                        pDevTmp->sd_dev[fn].drv = drv;
+                        pDevTmp->sd_dev[fn].supported_functions = fn_mask;
+                        pDevTmp->sd_dev[fn].cisptr = &pDevTmp->cisptr[0];
+                        pDevTmp->sd_dev[fn].sd_bus = pDevTmp;   // Backpointer
+                                                                // to bus
+                                                                // driver's
+                                                                // device
+                                                                // structure
+                        pDevTmp->sd_dev[fn].dev = &pDevTmp->dev->dev;   // Generic 
+                                                                        // device 
+                                                                        // interface 
+                                                                        // for
+                                                                        // hotplug
+
+                        spin_unlock_irqrestore(&pDevTmp->sd_dev_lock,
+                                               pDevTmp->sd_dev_lock_flags);
+                        DBGPRINT(DBG_API,
+                                 (KERN_DEBUG
+                                  "%s: Driver registered: %s for functions 0x%2.02X\n",
+                                  __FUNCTION__, pDevTmp->sd_dev[fn].drv->name,
+                                  fn_mask));
+
+                        if (pDevTmp->sd_dev[fn].drv->probe != NULL) {
+                            pDevTmp->sd_dev[fn].probe_called = 1;
+                            pDevTmp->sd_dev[fn].remove_called = 0;
+
+                            DBGPRINT(DBG_LOAD | DBG_ERROR,
+                                     (KERN_DEBUG
+                                      "%s: call probe() handler on fn=%d\n",
+                                      __FUNCTION__, fn));
+                            REL_IF_SEMA();
+                            call_client_probe(pDevTmp, fn);
+                            GET_IF_SEMA();
+                        } else {
+                            // If we have no probe() handler at this point, we
+                            // will never get one. 
+                            // This situation is considered a bug in the client 
+                            // driver !!!!
+                            DBGPRINT(DBG_LOAD,
+                                     (KERN_DEBUG
+                                      "%s@%d: no probe() handler installed for fn=%d! Revise client driver!!!\n",
+                                      __FUNCTION__, __LINE__, fn));
+                        }
+                        break;
+                    } else {
+                        spin_unlock_irqrestore(&pDevTmp->sd_dev_lock,
+                                               pDevTmp->sd_dev_lock_flags);
+                        continue;
+                    }
+                }
+            } else {
+                spin_unlock_irqrestore(&pDevTmp->sd_dev_lock,
+                                       pDevTmp->sd_dev_lock_flags);
+                continue;
+            }
+
+        }
+        DBGPRINT(DBG_API,
+                 (KERN_ERR
+                  "%s: There are already drivers registered for all devices!\n",
+                  __FUNCTION__));
+    }
+    // Add driver to global client list
+    spin_lock_irqsave(&sd_client_list_lock, sd_client_list_lock_flags);
+    list_add_tail((struct list_head *) pClientTmp, &sd_client_list);
+    spin_unlock_irqrestore(&sd_client_list_lock, sd_client_list_lock_flags);
+
+    REL_IF_SEMA();
+    LEAVE();
+    return 0;
+}
+
+/** 
+ *  @brief This function unregisters a client driver from the bus driver
+ *  @param drv		pointer to client drivers device IDs and call backs
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_driver_unregister(sd_driver * drv)
+{
+    struct list_head *pTmp;
+    PSD_CLIENT pClientTmp;
+    PSD_DEVICE_DATA pDevTmp;
+    int j;
+
+    ENTER();
+
+    if (drv == NULL) {
+        printk("%s INVALID ARGS: drv==NULL!\n", __FUNCTION__);
+        LEAVE();
+        return -1;
+    }
+
+    if (down_interruptible(&sd_client_sema))
+        return 0;
+    // Delete any association with this client driver
+    spin_lock_irqsave(&sd_dev_list_lock, sd_dev_list_lock_flags);
+    if (!list_empty(&sd_dev_list)) {
+        list_for_each(pTmp, &sd_dev_list) {
+            pDevTmp = (PSD_DEVICE_DATA) pTmp;
+            spin_unlock_irqrestore(&sd_dev_list_lock, sd_dev_list_lock_flags);
+            for (j = 0; j < MAX_SDIO_FUNCTIONS; j++) {
+                if (pDevTmp->sd_dev[j].drv == drv) {
+
+                    DBGPRINT(DBG_API,
+                             (KERN_DEBUG
+                              "%s: Driver unregistered: %s on fn = %d\n",
+                              __FUNCTION__, pDevTmp->sd_dev[j].drv->name, j));
+
+                    if (drv != NULL && drv->remove != NULL) {
+                        if (pDevTmp->sd_dev[j].remove_called == 0) {
+                            pDevTmp->sd_dev[j].probe_called = 0;
+                            pDevTmp->sd_dev[j].remove_called = 1;
+                            if (pDevTmp->SurpriseRemoved == SK_TRUE)
+                                pDevTmp->sd_dev[j].dev = NULL;
+                            pDevTmp->sd_dev[j].drv->remove(&pDevTmp->sd_dev[j]);
+                        }
+                    }
+
+                    spin_lock_irqsave(&pDevTmp->sd_dev_lock,
+                                      pDevTmp->sd_dev_lock_flags);
+                    pDevTmp->sd_dev[j].drv = NULL;
+                    spin_unlock_irqrestore(&pDevTmp->sd_dev_lock,
+                                           pDevTmp->sd_dev_lock_flags);
+                }
+            }
+        }
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: Driver %s is not registered!\n", __FUNCTION__,
+                  drv->name));
+    } else {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: SDIO Device List is empty!\n", __FUNCTION__));
+        spin_unlock_irqrestore(&sd_dev_list_lock, sd_dev_list_lock_flags);
+    }
+    up(&sd_client_sema);
+
+    GET_IF_SEMA();
+    // Remove the client driver from global client list
+    if (!list_empty(&sd_client_list)) {
+        spin_lock_irqsave(&sd_client_list_lock, sd_client_list_lock_flags);
+
+        list_for_each(pTmp, &sd_client_list) {
+            pClientTmp = (PSD_CLIENT) pTmp;
+            if (pClientTmp->drv != drv) {
+                continue;
+            }
+
+            list_del(pTmp);
+            kfree(pClientTmp);
+
+#ifdef SDIO_MEM_TRACE
+            printk("<<< kfree(SD_CLIENT)\n");
+#endif
+
+            break;
+        }
+
+        spin_unlock_irqrestore(&sd_client_list_lock, sd_client_list_lock_flags);
+    } else {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: SDIO Client Driver List is empty!\n",
+                  __FUNCTION__));
+        REL_IF_SEMA();
+        LEAVE();
+        return -1;
+    }
+
+    REL_IF_SEMA();
+    LEAVE();
+    return 0;
+}
+
+/** 
+ *  @brief Register an interrupt handler with a card function
+ *  @param dev				bus driver's device structure
+ *  @param id					sd_device_ids (contains function number)
+ *  @param function		interrupt handler
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_request_int(sd_device * dev, sd_device_id * id, sd_function * function)
+{
+    PSD_DEVICE_DATA pDev;
+
+    if (dev == NULL || id == NULL || function == NULL) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: missing parameters: dev=%p id=%p function=%p\n",
+                  __FUNCTION__, dev, id, function));
+        return -1;
+    }
+
+    if (id->fn < 1 || id->fn > 7) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: illegal function number: %d\n", __FUNCTION__,
+                  id->fn));
+        return -1;
+    }
+    if (dev->functions[id->fn].int_handler != NULL) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR
+                  "%s: There is already an interrupt handler registered with function %d\n",
+                  __FUNCTION__, id->fn));
+        return -1;
+    }
+
+    GET_IF_SEMA();
+
+    DBGPRINT(DBG_API,
+             (KERN_DEBUG "%s: FN%d handler=%p context=%p\n", __FUNCTION__,
+              id->fn, function->int_handler, function->context));
+
+    pDev = (PSD_DEVICE_DATA) dev->sd_bus;
+
+    SDHost_DisableInterrupt((PSD_DEVICE_DATA) dev->sd_bus,
+                            STDHOST_NORMAL_IRQ_CARD_ALL_ENA);
+    dev->functions[id->fn].int_handler = function->int_handler;
+    dev->functions[id->fn].context = function->context;
+
+    // cache the device to speed up irq response
+    pDev->irq_device_cache[id->fn] = dev;
+    SDHost_EnableInterrupt((PSD_DEVICE_DATA) dev->sd_bus,
+                           pDev->lastIRQSignalMask);
+
+    REL_IF_SEMA();
+    return 0;
+}
+
+/** 
+ *  @brief Remove an interrupt handler from a card function
+ *  @param dev				bus driver's device structure
+ *  @param id					sd_device_ids (contains function number)
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_release_int(sd_device * dev, sd_device_id * id)
+{
+    PSD_DEVICE_DATA pDev;
+
+    if (dev == NULL || id == NULL) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: missing parameters: dev=%p id=%p\n",
+                  __FUNCTION__, dev, id));
+        return -1;
+    }
+    if (id->fn < 1 || id->fn > 7) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: illegal function number: %d\n", __FUNCTION__,
+                  id->fn));
+        return -1;
+    }
+
+    GET_IF_SEMA();
+
+    pDev = (PSD_DEVICE_DATA) dev->sd_bus;
+
+    DBGPRINT(DBG_API, (KERN_DEBUG "%s: FN%d\n", __FUNCTION__, id->fn));
+
+    SDHost_DisableInterrupt((PSD_DEVICE_DATA) dev->sd_bus,
+                            STDHOST_NORMAL_IRQ_CARD_ALL_ENA);
+    dev->functions[id->fn].int_handler = NULL;
+    dev->functions[id->fn].context = NULL;
+
+    pDev->irq_device_cache[id->fn] = NULL;
+    SDHost_EnableInterrupt((PSD_DEVICE_DATA) dev->sd_bus,
+                           pDev->lastIRQSignalMask);
+
+    REL_IF_SEMA();
+    return 0;
+}
+
+/** 
+ *  @brief Enable interrupt of function id->fn
+ *  @param dev				bus driver's device structure
+ *  @param id					sd_device_ids (contains function number)
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_unmask(sd_device * dev, sd_device_id * id)
+{
+    PSD_DEVICE_DATA pDev;
+    if (dev == NULL || id == NULL) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: missing parameters: dev=%p id=%p\n",
+                  __FUNCTION__, dev, id));
+        return 1;
+    }
+    if (id->fn < 1 || id->fn > 7) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: illegal function number: %d\n", __FUNCTION__,
+                  id->fn));
+        return -1;
+    }
+
+    GET_IF_SEMA();
+
+    pDev = dev->sd_bus;
+    SDHost_EnableInterrupt(pDev, STDHOST_NORMAL_IRQ_CARD_ALL_ENA);
+    REL_IF_SEMA();
+    return 0;
+}
+
+/** 
+ *  @brief Enable interrupt of function id->fn
+ *  @param dev				bus driver's device structure
+ *  @param id					sd_device_ids (contains function number)
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_enable_int(sd_device * dev, sd_device_id * id)
+{
+    PSD_DEVICE_DATA pDev;
+    SK_U8 R;
+
+    if (dev == NULL || id == NULL) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: missing parameters: dev=%p id=%p\n",
+                  __FUNCTION__, dev, id));
+        return 1;
+    }
+    if (id->fn < 1 || id->fn > 7) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: illegal function number: %d\n", __FUNCTION__,
+                  id->fn));
+        return -1;
+    }
+
+    GET_IF_SEMA();
+
+    pDev = dev->sd_bus;
+
+    // Set global interrupt enable
+    if (!SDHost_CMD52_Read(pDev, INT_ENABLE_REG, 0, &R)) {
+        REL_IF_SEMA();
+        return -1;
+    }
+
+    R |= (1 << id->fn);
+    if (SDHost_CMD52_Write(pDev, INT_ENABLE_REG, 0, R)) {
+        if (!SDHost_CMD52_Read(pDev, INT_ENABLE_REG, 0, &R)) {
+            REL_IF_SEMA();
+            return -1;
+        }
+
+        DBGPRINT(DBG_API,
+                 (KERN_DEBUG "%s:FN0 : INT Enable Register: 0x%2.02X\n",
+                  __FUNCTION__, R));
+    } else {
+        REL_IF_SEMA();
+        return -1;
+    }
+
+    SDHost_EnableInterrupt(pDev, STDHOST_NORMAL_IRQ_CARD_ALL_ENA);
+    REL_IF_SEMA();
+    return 0;
+}
+
+/** 
+ *  @brief Disable interrupt of function id->fn
+ *  @param dev				bus driver's device structure
+ *  @param id					sd_device_ids (contains function number)
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_disable_int(sd_device * dev, sd_device_id * id)
+{
+    PSD_DEVICE_DATA pDev;
+    SK_U8 R;
+
+    if (dev == NULL || id == NULL) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: missing parameters: dev=%p id=%p\n",
+                  __FUNCTION__, dev, id));
+        return -1;
+    }
+    if (id->fn < 1 || id->fn > 7) {
+        DBGPRINT(DBG_API,
+                 (KERN_ERR "%s: illegal function number: %d\n", __FUNCTION__,
+                  id->fn));
+        return -1;
+    }
+
+    GET_IF_SEMA();
+
+    pDev = dev->sd_bus;
+
+    // Set global interrupt enable
+    if (!SDHost_CMD52_Read(pDev, INT_ENABLE_REG, 0, &R)) {
+        REL_IF_SEMA();
+        return -1;
+    }
+
+    R &= ~(1 << id->fn);
+    if (SDHost_CMD52_Write(pDev, INT_ENABLE_REG, 0, R)) {
+        if (!SDHost_CMD52_Read(pDev, INT_ENABLE_REG, 0, &R)) {
+            REL_IF_SEMA();
+            return -1;
+        }
+
+        DBGPRINT(DBG_API,
+                 (KERN_DEBUG "%s:FN0 : INT Disable Register: 0x%2.02X\n",
+                  __FUNCTION__, R));
+    } else {
+        REL_IF_SEMA();
+        return -1;
+    }
+
+    REL_IF_SEMA();
+    return 0;
+}
+
+/** 
+ *  @brief Set SDIO bus width
+ *  @param dev				bus driver's device structure
+ *  @param with				SDIO bus with 1 or 4
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_set_buswidth(sd_device * dev, int width)
+{
+    SK_BOOL rc;
+    GET_IF_SEMA();
+
+    if (width == 1 || width == 4) {
+        DBGPRINT(DBG_API, (KERN_DEBUG "%s: width = %d\n", __FUNCTION__, width));
+        rc = SDHost_SetBusWidth((PSD_DEVICE_DATA) dev->sd_bus, width);
+        REL_IF_SEMA();
+        return (rc ? 0 : -1);
+    } else {
+        REL_IF_SEMA();
+        return -1;
+    }
+}
+
+/** 
+ *  @brief Set GPO on or off
+ *  @param dev			bus driver's device structure
+ *  @param on				1: turn GPO on 0: turn GPO off
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_set_gpo(sd_device * dev, int on)
+{
+    SK_BOOL rc;
+
+    GET_IF_SEMA();
+    DBGPRINT(DBG_API, (KERN_DEBUG "%s: on = %d\n", __FUNCTION__, on));
+    rc = SDHost_SetGPO((PSD_DEVICE_DATA) dev->sd_bus, on);
+
+    REL_IF_SEMA();
+    return (rc ? 0 : -1);
+}
+
+/** 
+ *  @brief Set SDIO bus clock on
+ *  @param dev			bus driver's device structure
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_start_clock(sd_device * dev)
+{
+    GET_IF_SEMA();
+    DBGPRINT(DBG_API, (KERN_DEBUG "%s\n", __FUNCTION__));
+    SDHost_SetClock((PSD_DEVICE_DATA) dev->sd_bus, 1);
+    REL_IF_SEMA();
+    return 0;
+}
+
+/** 
+ *  @brief Set SDIO bus clock on
+ *  @param dev			bus driver's device structure
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_stop_clock(sd_device * dev)
+{
+    GET_IF_SEMA();
+    DBGPRINT(DBG_API, (KERN_DEBUG "%s\n", __FUNCTION__));
+    SDHost_SetClock((PSD_DEVICE_DATA) dev->sd_bus, 0);
+    REL_IF_SEMA();
+    return 0;
+}
+
+/** 
+ *  @brief Set SDIO bus clock
+ *  @param dev			bus driver's device structure
+ *  @param clock		SDIO bus clock frequency
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sd_set_busclock(sd_device * dev, int clock)
+{
+    GET_IF_SEMA();
+    DBGPRINT(DBG_API, (KERN_DEBUG "%s: clock = %d\n", __FUNCTION__, clock));
+    SDHost_SetClockSpeed((PSD_DEVICE_DATA) dev->sd_bus, clock);
+    REL_IF_SEMA();
+    return 0;
+}
+
+/** 
+ *  @brief Read a byte from SDIO device
+ *  @param dev			bus driver's device structure
+ *  @param fn				function number 0..7
+ *  @param reg 			register offset
+ *  @param dat  		pointer to return value
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sdio_read_ioreg(sd_device * dev, u8 fn, u32 reg, u8 * dat)
+{
+    GET_IF_SEMA();
+    if (SDHost_CMD52_Read((PSD_DEVICE_DATA) dev->sd_bus, reg, fn, dat)) {
+//              printk("%s: dev=%p fn=%d reg=0x%8.08X dat=0x%2.02x\n",__FUNCTION__,dev,fn,reg,*dat);
+        REL_IF_SEMA();
+        return 0;
+    } else {
+        printk("%s: dev=%p fn=%d reg=0x%8.08X FAILED!\n", __FUNCTION__, dev, fn,
+               reg);
+        REL_IF_SEMA();
+        return -1;
+    }
+
+}
+
+/** 
+ *  @brief Write a byte to SDIO device
+ *  @param dev			bus driver's device structure
+ *  @param fn				function number 0..7
+ *  @param reg 			register offset
+ *  @param dat  		value
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sdio_write_ioreg(sd_device * dev, u8 fn, u32 reg, u8 dat)
+{
+    GET_IF_SEMA();
+    if (SDHost_CMD52_Write((PSD_DEVICE_DATA) dev->sd_bus, reg, fn, dat)) {
+//              printk("%s: dev=%p fn=%d reg=0x%8.08X dat=0x%2.02x\n",__FUNCTION__,dev,fn,reg,dat);
+        REL_IF_SEMA();
+        return 0;
+    } else {
+        printk("%s: dev=%p fn=%d reg=0x%8.08X FAILED!\n", __FUNCTION__, dev, fn,
+               reg);
+        REL_IF_SEMA();
+        return -1;
+    }
+}
+
+/** 
+ *  @brief Read multiple bytes from SDIO device
+ *  @param dev			bus driver's device structure
+ *  @param fn				function number 0..7
+ *  @param address	offset
+ *  @param blkmode	block or byte mode
+ *  @param opcode		fixed or auto-inc address
+ *  @param blkcnt 	number of bytes or blocks (depends on blkmode)
+ *  @param blksz		size of block
+ *  @param buffer		pointer to data buffer
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sdio_read_iomem(sd_device * dev, u8 fn, u32 address, u8 blkmode, u8 opcode,
+                u32 blkcnt, u32 blksz, u8 * buffer)
+{
+//      printk("%s: dev=%p fn=%d address=0x%8.08X blockcnt=%d blocksize=%d\n",__FUNCTION__,dev,fn,address,blkcnt,blksz);
+
+    GET_IF_SEMA();
+    if (SDHost_CMD53_ReadEx
+        ((PSD_DEVICE_DATA) dev->sd_bus, address, fn, blkmode, opcode, buffer,
+         blkcnt, blksz)) {
+        REL_IF_SEMA();
+        return 0;
+    } else {
+        printk("%s: dev=%p fn=%d FAILED!\n", __FUNCTION__, dev, fn);
+        REL_IF_SEMA();
+        return -1;
+    }
+}
+
+/** 
+ *  @brief Write multiple bytes to SDIO device
+ *  @param dev			bus driver's device structure
+ *  @param fn				function number 0..7
+ *  @param address	offset
+ *  @param blkmode	block or byte mode
+ *  @param opcode		fixed or auto-inc address
+ *  @param blkcnt 	number of bytes or blocks (depends on blkmode)
+ *  @param blksz		size of block
+ *  @param buffer		pointer to data buffer
+ *  @return				0 : Success -1: Failed  
+*/
+int
+sdio_write_iomem(sd_device * dev, u8 fn, u32 address, u8 blkmode, u8 opcode,
+                 u32 blkcnt, u32 blksz, u8 * buffer)
+{
+//      printk("%s: dev=%p fn=%d address=0x%8.08X blockcnt=%d blocksize=%d\n",__FUNCTION__,dev,fn,address,blkcnt,blksz);
+    GET_IF_SEMA();
+    if (SDHost_CMD53_WriteEx
+        ((PSD_DEVICE_DATA) dev->sd_bus, address, fn, blkmode, opcode, buffer,
+         blkcnt, blksz)) {
+        REL_IF_SEMA();
+        return 0;
+    } else {
+        printk("%s: dev=%p fn=%d FAILED!\n", __FUNCTION__, dev, fn);
+        REL_IF_SEMA();
+        return -1;
+    }
+}
+
+// for filling the "/proc/mrvsdio" entry
+int
+mrvlsdio_read_procmem(char *buf,
+                      char **start,
+                      off_t offset, int count, int *eof, void *data)
+{
+    PSD_DEVICE_DATA pDevTmp;
+    int len = 0;
+
+    if (!list_empty(&sd_dev_list)) {
+        pDevTmp = (PSD_DEVICE_DATA) sd_dev_list.next;
+
+        // after probe-event, we have "good" data in /proc/mrvsdio
+        len =
+            sprintf(buf,
+                    "mrvlsdio is running with:\nbus_type     = 0x%x\nbus_with     = 0x%x\nclock_speed  = 0x%x\ndebug_flags  = 0x%x\nsdio_voltage = 0x%x\n",
+                    pDevTmp->bus_type, pDevTmp->bus_width, pDevTmp->ClockSpeed,
+                    pDevTmp->debug_flags, pDevTmp->sdio_voltage);
+    } else {
+        // not probed yet
+        len = sprintf(buf, "mrvlsdio is up and waiting for card\n");
+    }
+
+    *eof = 1;
+    return (len);
+}
+
+static void
+call_client_probe(PSD_DEVICE_DATA pDev, int fn)
+{
+
+    if (down_interruptible(&sd_client_sema))
+        return;
+    if (pDev->sd_dev[fn].drv->probe != NULL) {
+        pDev->sd_dev[fn].drv->probe(&pDev->sd_dev[fn], &pDev->sd_ids[fn]);
+    }
+    up(&sd_client_sema);
+}
+
+static int
+mrvlsdio_init_module(void)
+{
+    int ret;
+
+    ENTER();
+
+    // generate /proc/ entry
+    create_proc_read_entry("mrvlsdio",  // entry in "/proc/mrvlsdio"
+                           0,   // file attributes
+                           NULL,        // parent dir
+                           mrvlsdio_read_procmem,       // name of function
+                           NULL);       // client data
+
+    DBGPRINT(DBG_ALL, ("*** mrvlsdio ***\n"));
+    DBGPRINT(DBG_ALL, ("*** multifunction API ***\n"));
+    DBGPRINT(DBG_ALL, ("*** Built on %s %s ***\n", __DATE__, __TIME__));
+
+                                                                                                                                                                                /*--- mmoser 6/21/2007 ---*/
+    INIT_LIST_HEAD(&sd_dev_list);
+    spin_lock_init(&sd_dev_list_lock);
+
+    INIT_LIST_HEAD(&sd_client_list);
+    spin_lock_init(&sd_client_list_lock);
+
+    ret = register_chrdev(sdio_major, "mrvlsdio", &mrvlsdio_fops);
+    if (ret < 0) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_WARNING "mrvlsdio: can't get major %d  ret=%d\n",
+                  sdio_major, ret));
+    } else {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "mrvlsdio: major %d\n", ret));
+    }
+    if (sdio_major == 0)
+        sdio_major = ret;       /* dynamic */
+
+        /** from 2.4 kernel source:
+	 * pci_register_driver - register a new pci driver
+	 *
+	 * Adds the driver structure to the list of registered drivers
+	 * Returns the number of pci devices which were claimed by the driver
+	 * during registration.  The driver remains registered even if the
+	 * return value is zero.
+	 */
+
+    ret = pci_register_driver(&mrvlsdio);
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "%s: pci_register_driver with %d\n", __FILE__, ret));
+
+    LEAVE();
+//      return (ret);
+    return 0;
+}
+
+static void
+mrvlsdio_exit_module(void)
+{
+    PSD_DEVICE_DATA pTmpDev;
+    PSD_CLIENT pTmpClient;
+
+    // remove proc entry
+    remove_proc_entry("mrvlsdio", NULL);
+    DBGPRINT(DBG_LOAD, (KERN_DEBUG "Module mrvlsdio exit\n"));
+
+    unregister_chrdev(sdio_major, "mrvlsdio");
+    pci_unregister_driver(&mrvlsdio);
+
+    // Clean up device list
+
+    while (!list_empty(&sd_dev_list)) {
+        pTmpDev = (PSD_DEVICE_DATA) sd_dev_list.next;
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "%s@%d: pTmpDev=%p\n", __FUNCTION__, __LINE__,
+                  pTmpDev));
+        list_del((struct list_head *) pTmpDev);
+        kfree(pTmpDev);
+
+#ifdef SDIO_MEM_TRACE
+        printk("<<< kfree(SD_DEVICE_DATA)\n");
+#endif
+
+    }
+
+    // Clean up client list
+    while (!list_empty(&sd_client_list)) {
+        pTmpClient = (PSD_CLIENT) sd_client_list.next;
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "%s@%d: pTmpClient=%p\n", __FUNCTION__, __LINE__,
+                  pTmpClient));
+        list_del((struct list_head *) pTmpClient);
+        kfree(pTmpClient);
+#ifdef SDIO_MEM_TRACE
+        printk("<<< kfree(SD_CLIENT)\n");
+#endif
+
+    }
+}
+
+module_init(mrvlsdio_init_module);
+module_exit(mrvlsdio_exit_module);
+
+EXPORT_SYMBOL(sd_driver_register);
+EXPORT_SYMBOL(sd_driver_unregister);
+EXPORT_SYMBOL(sd_request_int);
+EXPORT_SYMBOL(sd_release_int);
+EXPORT_SYMBOL(sd_unmask);
+EXPORT_SYMBOL(sd_enable_int);
+EXPORT_SYMBOL(sd_disable_int);
+EXPORT_SYMBOL(sd_set_buswidth);
+EXPORT_SYMBOL(sd_set_busclock);
+EXPORT_SYMBOL(sd_start_clock);
+EXPORT_SYMBOL(sd_stop_clock);
+EXPORT_SYMBOL(sd_set_gpo);
+EXPORT_SYMBOL(sdio_read_ioreg);
+EXPORT_SYMBOL(sdio_write_ioreg);
+EXPORT_SYMBOL(sdio_read_iomem);
+EXPORT_SYMBOL(sdio_write_iomem);
+
+MODULE_DESCRIPTION("Marvell SDIO Bus Driver");
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_LICENSE("GPL");
diff --git a/io/sdio/syskt/skisr.c b/io/sdio/syskt/skisr.c
new file mode 100644
index 0000000..934720a
--- /dev/null
+++ b/io/sdio/syskt/skisr.c
@@ -0,0 +1,290 @@
+/**
+ *
+ * Name:	skisr.c
+ * Project:	Wireless LAN, Bus driver for SDIO interface
+ * Version:	$Revision: 1.1 $
+ * Date:	$Date: 2007/01/18 09:21:35 $
+ * Purpose:	This module handles the interrupts.
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd. 
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************************************
+ *
+ * History:
+ *
+ *	$Log: skisr.c,v $
+ *	Revision 1.1  2007/01/18 09:21:35  pweber
+ *	Put under CVS control
+ *	
+ *
+ ******************************************************************************/
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+static void (*gpio_int_callback) (void *) = NULL;
+static void *gpio_int_callback_arg = NULL;
+
+int
+request_gpio_irq_callback(void (*callback) (void *), void *arg)
+{
+    if (!gpio_int_callback && !gpio_int_callback_arg) {
+        gpio_int_callback = callback;
+        gpio_int_callback_arg = arg;
+        return 0;
+    }
+    return -1;
+}
+
+EXPORT_SYMBOL(request_gpio_irq_callback);
+
+int
+release_gpio_irq_callback(void (*callback) (void *), void *arg)
+{
+    if ((callback == gpio_int_callback)
+        && (arg == gpio_int_callback_arg)) {
+        gpio_int_callback = NULL;
+        gpio_int_callback_arg = NULL;
+        return 0;
+    }
+    return -1;
+}
+
+EXPORT_SYMBOL(release_gpio_irq_callback);
+
+DECLARE_TASKLET(SDIOBus_tasklet, SDIOBus_Dpc, 0);
+
+void
+SDIOBus_Dpc(unsigned long arg)
+{
+    SK_U32 irq_status, status;
+    SK_U16 errorIRQ_status = 0;
+    PSD_DEVICE_DATA pDev;
+
+    DBGPRINT(DBG_IRQ, (KERN_DEBUG "SDIOBUS_Dpc startet ....\n"));
+
+    if (arg == 0) {
+        DBGPRINT(DBG_ERROR, (KERN_DEBUG "SDIOBUS_Dpc : arg == NULL !\n"));
+        return;
+    }
+
+    pDev = (PSD_DEVICE_DATA) arg;
+
+    if (pDev == NULL) {
+        DBGPRINT(DBG_ERROR, (KERN_DEBUG "SDIOBUS_Dpc : pDev == NULL !\n"));
+        return;
+    }
+
+    irq_status = pDev->lastIntStatus;
+
+    if ((irq_status & STDHOST_NORMAL_IRQ_ERROR) != 0) {
+        MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS,
+                        &errorIRQ_status);
+        if ((errorIRQ_status & STDHOST_ERROR_IRQ_GPI_0) != 0) {
+            if ((pDev->lastErrorIRQSignalMask & STDHOST_ERROR_IRQ_GPI_0) != 0) {
+                // clear irq bit
+                MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS,
+                                 STDHOST_ERROR_IRQ_GPI_0);
+                // Fake a SDIO card interrupt
+                irq_status |= STDHOST_NORMAL_IRQ_CARD;
+            }
+        }
+        if ((errorIRQ_status & STDHOST_ERROR_IRQ_GPI_1) != 0) {
+            if ((pDev->lastErrorIRQSignalMask & STDHOST_ERROR_IRQ_GPI_1) != 0) {
+                printk("GPI-1 interrupt fired (0x%4.04X)\n", errorIRQ_status);
+                                /*--- mmoser 3/12/2007 ---*/
+                // clear irq bit
+                MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS,
+                                 STDHOST_ERROR_IRQ_GPI_1);
+
+                SDHost_SetClock(pDev, 1);
+                if (gpio_int_callback && gpio_int_callback_arg)
+                    gpio_int_callback(gpio_int_callback_arg);
+            }
+        }
+    }
+
+    if ((irq_status & STDHOST_NORMAL_IRQ_CARD_OUT) ==
+        STDHOST_NORMAL_IRQ_CARD_OUT) {
+        // clear irq bit
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                         STDHOST_NORMAL_IRQ_CARD_OUT);
+
+                /*--- mmoser 14.09.2005 ---*/
+        if (pDev->initialized) {
+            DBGPRINT(DBG_IRQ | DBG_W528D,
+                     (KERN_DEBUG "SDIOBUS_Dpc : NORMAL_IRQ_CARD_OUT\n"));
+
+            /*--- mmoser 10.08.2005 ---*/
+            DBGPRINT(DBG_IRQ, (KERN_DEBUG "CARD REMOVED\n"));
+            SDIOBus_CardRemoved(pDev);
+
+                        /*--- mmoser 3/31/2006 ---*/
+            pDev->SurpriseRemoved = SK_TRUE;
+        }
+        SDHost_EnableInterrupt(pDev, pDev->lastIRQSignalMask);
+        DBGPRINT(DBG_IRQ,
+                 (KERN_DEBUG "SDIOBUS_Dpc finished.(line=%d)\n", __LINE__));
+        return;
+    }
+    if ((irq_status & STDHOST_NORMAL_IRQ_CARD_IN) == STDHOST_NORMAL_IRQ_CARD_IN) {
+        // clear irq bit
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                         STDHOST_NORMAL_IRQ_CARD_IN);
+
+        DBGPRINT(DBG_IRQ, (KERN_DEBUG "SDIOBUS_Dpc : NORMAL_IRQ_CARD_IN\n"));
+        DBGPRINT(DBG_IRQ, (KERN_DEBUG "CARD PLUGGED IN\n"));
+        SDIOBus_CardPluggedIn(pDev);
+        SDHost_EnableInterrupt(pDev, pDev->lastIRQSignalMask);
+        DBGPRINT(DBG_IRQ,
+                 (KERN_DEBUG "SDIOBUS_Dpc finished.(line=%d)\n", __LINE__));
+        return;
+    }
+
+    if ((irq_status & STDHOST_NORMAL_IRQ_CARD) == STDHOST_NORMAL_IRQ_CARD) {
+        status = (irq_status << 16);
+        if (pDev->number_of_functions > 1) {
+            queue_work(pDev->workqueue, &pDev->irq_work);
+        } else {
+            if (pDev->irq_device_cache[1]->functions[1].int_handler != NULL) {
+                pDev->irq_device_cache[1]->functions[1].int_handler(pDev->
+                                                                    irq_device_cache
+                                                                    [1],
+                                                                    pDev->
+                                                                    irq_device_cache
+                                                                    [1]->
+                                                                    pCurrent_Ids,
+                                                                    pDev->
+                                                                    irq_device_cache
+                                                                    [1]->
+                                                                    functions
+                                                                    [1].
+                                                                    context);
+            } else {
+                DBGPRINT(DBG_IRQ,
+                         (KERN_DEBUG "No interrupt handler registered.\n"));
+                SDHost_EnableInterrupt(pDev, STDHOST_NORMAL_IRQ_CARD_ALL_ENA);
+                DBGPRINT(DBG_IRQ, (KERN_DEBUG "SDIOBUS_Dpc finished.\n"));
+                return;
+            }
+        }
+        DBGPRINT(DBG_IRQ,
+                 (KERN_DEBUG "SDIOBUS_Dpc finished.(line=%d)\n", __LINE__));
+        return;
+    }
+
+    if (irq_status & (STDHOST_NORMAL_IRQ_ERROR |
+                      STDHOST_NORMAL_IRQ_TRANS_COMPLETE |
+                      STDHOST_NORMAL_IRQ_CMD_COMPLETE)) {
+        if (((irq_status & STDHOST_NORMAL_IRQ_TRANS_COMPLETE) &&
+             (pDev->lastIRQSignalMask & STDHOST_NORMAL_IRQ_TRANS_COMPLETE)) ||
+            ((irq_status & STDHOST_NORMAL_IRQ_CMD_COMPLETE) &&
+             (pDev->lastIRQSignalMask & STDHOST_NORMAL_IRQ_CMD_COMPLETE)) ||
+            ((errorIRQ_status & STDHOST_ERROR_IRQ_GPI_1) &&
+             (pDev->lastErrorIRQSignalMask & STDHOST_ERROR_IRQ_GPI_1))
+
+            )
+        {
+            SDHost_EnableInterrupt(pDev, pDev->lastIRQSignalMask);
+        }
+        DBGPRINT(DBG_IRQ,
+                 (KERN_DEBUG "SDIOBUS_Dpc finished.(line=%d)\n", __LINE__));
+        return;
+    } else {
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, 0xFFFF);
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS, 0xFFFF);
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG "SDIOBus_Dpc(): Unhandled IRQ : 0x%8.08X.\n",
+                  irq_status));
+    }
+
+    SDHost_EnableInterrupt(pDev, pDev->lastIRQSignalMask);
+    DBGPRINT(DBG_IRQ,
+             (KERN_DEBUG "SDIOBUS_Dpc finished.(line=%d)\n", __LINE__));
+}
+
+irqreturn_t
+SDIOBus_Isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+    SK_U32 tmp;
+    SK_U16 tmpsig;
+    PSD_DEVICE_DATA pDev;
+
+    if (dev_id == NULL) {
+        DBGPRINT(DBG_IRQ, (KERN_DEBUG "SDIOBUS_Isr : dev_id == NULL !\n"));
+        return IRQ_HANDLED;
+    }
+
+    pDev = (PSD_DEVICE_DATA) dev_id;
+
+    if (pDev == NULL) {
+        DBGPRINT(DBG_IRQ, (KERN_DEBUG "SDIOBUS_Isr : pDev == NULL !\n"));
+        return IRQ_HANDLED;
+    }
+
+    MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, &tmp);
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE, &tmpsig);
+
+    // Check if interrupt came from our device
+    if (((((tmp & STDHOST_NORMAL_IRQ_ERROR) != 0) &&
+          ((tmpsig & (STDHOST_ERROR_IRQ_GPI_1 | STDHOST_ERROR_IRQ_GPI_0)) != 0))
+         || ((tmp & pDev->currentIRQSignalMask) != 0)) && tmp != 0xFFFFFFFF)
+    {
+                                                                                                                                                                /*--- mmoser 8/29/2006 ---*/
+        if (tmp & STDHOST_NORMAL_IRQ_TRANS_COMPLETE) {
+            if (pDev->currentIRQSignalMask & STDHOST_NORMAL_IRQ_TRANS_COMPLETE) {
+                // clear irq bit
+                MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                                 STDHOST_NORMAL_IRQ_TRANS_COMPLETE);
+
+                if (!test_and_set_bit(0, &pDev->trans_complete_evt.event)) {
+                    wake_up(&pDev->trans_complete_evt.wq);
+                }
+            }
+        }
+
+        if (tmp & STDHOST_NORMAL_IRQ_CMD_COMPLETE) {
+            if (pDev->currentIRQSignalMask & STDHOST_NORMAL_IRQ_CMD_COMPLETE) {
+                // clear irq bit
+                MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                                 STDHOST_NORMAL_IRQ_CMD_COMPLETE);
+
+                if (!test_and_set_bit(0, &pDev->cmd_complete_evt.event)) {
+                    wake_up(&pDev->cmd_complete_evt.wq);
+                }
+            }
+        }
+
+        MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                        &pDev->lastErrorIRQSignalMask);
+        pDev->lastIntStatus = tmp;
+        DBGPRINT(DBG_IRQ,
+                 (KERN_DEBUG "SDIOBUS_Isr (0x%4.04X)\n", pDev->lastIntStatus));
+        SDHost_DisableInterrupt(pDev, STDHOST_NORMAL_IRQ_ALL_SIG_ENA);
+
+        SDIOBus_tasklet.data = (unsigned long) pDev;
+        tasklet_schedule(&SDIOBus_tasklet);
+
+    } else {
+        if (tmp == 0xFFFFFF)
+            pDev->SurpriseRemoved = SK_TRUE;
+        return IRQ_NONE;
+    }
+    return IRQ_HANDLED;
+
+}
diff --git a/io/sdio/syskt/stdhost.c b/io/sdio/syskt/stdhost.c
new file mode 100644
index 0000000..cd79884
--- /dev/null
+++ b/io/sdio/syskt/stdhost.c
@@ -0,0 +1,3974 @@
+/**
+ *
+ * Name: stdhost.c
+ * Project: Wireless LAN, Bus driver for SDIO interface
+ * Version: $Revision: 1.1 $
+ * Date: $Date: 2007/01/18 09:21:35 $
+ * Purpose: This module handles the SDIO Standard Host Interface.
+ *
+ * Copyright (C) 2003-2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/******************************************************************************
+ *
+ * History:
+ *
+ * $Log: stdhost.c,v $
+ * Revision 1.1  2007/01/18 09:21:35  pweber
+ * Put under CVS control
+ *
+ * Revision 1.4  2005/12/08 12:00:27  ebauer
+ * Driver ckecks AND update voltage registry value if not correct
+ * 
+ * Revision 1.3  2005/12/07 13:40:19  ebauer
+ * Modify check of registry voltage value
+ * 
+ * Revision 1.2  2005/10/31 10:34:59  jschmalz
+ * Bugfixes Chariot (Interface hang)
+ * 
+ * Revision 1.1  2005/10/07 08:43:47  jschmalz
+ * Put SDIO with FPGA under CVS control
+ * 
+ * 
+ ******************************************************************************/
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+//define the SD Block Size
+//for SD8381-B0 chip, it could be 32,64,128,256,512
+//for all other chips including SD8381-A0, it must be 32
+#define POLLING_TIMES 2000
+
+#define USE_FPGA_POWER_RAMP
+//  #define DMA_SUPPORT_RD
+// #define DMA_SUPPORT_WR
+// #define FIFO_CMD52_DEBUG
+
+SK_U8 ena_func[8] = { 0, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0x7E, 0xFE };
+
+SK_BOOL SDHost_DumpCIS(PSD_DEVICE_DATA pDev, SK_U8 function_number,
+                       SK_U32 length);
+
+extern int block_size, dma_support;
+
+/******************************************************************************
+ *
+ * SDHost_InitializeCard  - Initialize the plugged in SDIO card
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ * TRUE on success
+ */
+SK_BOOL
+SDHost_InitializeCard(PSD_DEVICE_DATA pDev)
+{
+    SK_U8 OCR[3];
+    SK_U8 RCA[2];
+    SK_U8 Cis[DEVICE_NAME_LENGTH];
+    SK_U16 usVal, ucPowerCurr[FPGA_POWER_STEPS] = FPGA_POWER_VAL_ENUM;
+    SK_U8 ucValue;
+    SK_U8 ucConfigId;
+    SK_U8 ucPowerValue = 0;
+    SK_U8 R;
+    SK_U32 ulArg;
+    SK_U32 j, i, ulValue, ulResponse, cnt;
+    SK_U32 cislength;
+    SK_U32 RegVal;
+    SK_U32 u32Val;
+
+    SDHost_DisableInterrupt(pDev, STDHOST_NORMAL_IRQ_ALL_SIG_ENA);
+
+    _SLEEP_MS(pDev, 100);
+
+    DBGPRINT(DBG_W528D, (KERN_DEBUG "SDHost_InitializeCard()\n"));
+               /*--- mmoser 3/7/2006 ---*/
+    cnt = 0;
+
+    pDev->crc_len = 0;
+
+    ZERO_MEMORY(OCR, 3);
+    ZERO_MEMORY(RCA, 2);
+    ZERO_MEMORY(Cis, DEVICE_NAME_LENGTH);
+
+    // Setup the SD clock
+    if (pDev->baseClockFreq == 0) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG "Base clock frequency not available!\n"));
+        return SK_FALSE;
+    }
+    if (pDev->ClockSpeed != 0) {
+        usVal = MK_CLOCK((SK_U16) pDev->ClockSpeed) | STDHOST_INTERNAL_CLK_ENA;
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, usVal);
+    } else {
+        SK_U32 ClockSpeed = 1;  // set the clock initially to 25MHz
+        usVal = MK_CLOCK((SK_U16) ClockSpeed) | STDHOST_INTERNAL_CLK_ENA;
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, usVal);
+    }
+    /* Set the Rx Clock to Rising Edge */
+
+    MEM_READ_ULONG(pDev, SK_SLOT_0, FPGA_CORE_CTRL_REG, &u32Val);
+    u32Val |= FPGA_RAISING_EDGE;
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, FPGA_CORE_CTRL_REG, u32Val);
+
+    for (j = 0; j < MAX_WAIT_CLOCK_STABLE; j++) {
+        MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, &usVal);
+        if ((usVal & STDHOST_INTERNAL_CLK_STABLE) ==
+            STDHOST_INTERNAL_CLK_STABLE) {
+            break;
+        }
+    }
+    if (j >= MAX_WAIT_CLOCK_STABLE) {
+        DBGPRINT(DBG_ERROR, (KERN_DEBUG "SD clock remains unstable!\n"));
+        return SK_FALSE;
+    }
+    // Enable clock to card
+    usVal |= STDHOST_CLOCK_ENA;
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, usVal);
+
+    // enable DMA support depending on ChipRev
+    MEM_READ_UCHAR(pDev, SK_SLOT_0, FPGA_CHIP_REVISION, &ucValue);
+    DBGPRINT(DBG_ERROR, (KERN_DEBUG "ChipRevision: 0x%x\n", ucValue));
+    {
+        SK_U8 hi, lo;
+        lo = ucValue & 0x0F;
+        hi = (ucValue >> 4) & 0x0F;
+        printk("\n****************************************************\n");
+        printk("*********   FPGA-ChipRevision: %x.%x (0x%2.02X)  *********\n",
+               hi, lo, ucValue);
+        printk("****************************************************\n");
+    }
+
+    pDev->dma_support = 0;
+    if ((ucValue >= FPGA_CHIP_REV_2_0) && dma_support) {
+        if ((pDev->debug_flags & DEBUG_USE_RD_DMA) == DEBUG_USE_RD_DMA)
+            pDev->dma_support |= DMA_RD_SUPPORT;
+
+        if ((pDev->debug_flags & DEBUG_USE_WR_DMA) == DEBUG_USE_WR_DMA)
+            pDev->dma_support |= DMA_WR_SUPPORT;
+
+        // pDev->dma_support = DMA_WR_SUPPORT | DMA_RD_SUPPORT;
+        // pDev->dma_support = DMA_RD_SUPPORT;
+        // pDev->dma_support = 0;
+    } else {
+        pDev->dma_support = 0;
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "***************************************************\n"));
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "* CardBus-to-SDIO Adapter FPGA Rev: V0x%x         *\n",
+                  ucValue));
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "* This FPGA revision does NOT support DMA mode,   *\n"));
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "* please update your adapter to Rev 20 or higher  *\n"));
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "***************************************************\n"));
+    }
+    DBGPRINT(DBG_ERROR, (KERN_DEBUG "DMA_SUPPORT: 0x%x\n", pDev->dma_support));
+    printk
+        ("**************++ DMA_SUPPORT: 0x%x debug_flags=0x%8.08X ++************************\n",
+         pDev->dma_support, pDev->debug_flags);
+    // pweber / tschrobenhauser 03.08.2005
+    // check the power regulator output voltage is stable
+    // WAIT UNTIL ADDR 0x20E, Bit 0 == 1
+
+    MEM_READ_UCHAR(pDev, SK_SLOT_0, FPGA_CARD_REVISION, &ucValue);
+    DBGPRINT(DBG_ERROR, (KERN_DEBUG "CardRevision: 0x%x\n", ucValue));
+    if (ucValue == FPGA_CARD_REV_1_1) {
+//  SK_U8 ucConfigId;
+//  SK_U8 ucPowerValue=0;
+        // LINUX: get voltage value from module parameter 'sdio_voltage'
+        RegVal = pDev->sdio_voltage;
+
+        MEM_READ_UCHAR(pDev, SK_SLOT_0, FPGA_CONFIG_ID, &ucConfigId);
+        if (ucConfigId & FPGA_CONFIG_3_3_V) {
+            DBGPRINT(DBG_ERROR, (KERN_DEBUG "Configuration ID : 3.3V\n"));
+            // Check if registry value is ok
+            if ((RegVal >= FPGA_POWER_REG_3_3_V_MIN) &&
+                (RegVal <= FPGA_POWER_REG_3_3_V_MAX)) {
+                ucPowerValue = (SK_U8) RegVal;
+            } else {
+                ucPowerValue = FPGA_POWER_REG_3_3_V;
+            }
+        } else if (ucConfigId & FPGA_CONFIG_2_5_V) {
+            DBGPRINT(DBG_ERROR, (KERN_DEBUG "Configuration ID : 2.5V\n"));
+            // Check if registry value is ok
+            if ((RegVal >= FPGA_POWER_REG_2_5_V_MIN) &&
+                (RegVal <= FPGA_POWER_REG_2_5_V_MAX)) {
+                ucPowerValue = (SK_U8) RegVal;
+            } else {
+                ucPowerValue = FPGA_POWER_REG_2_5_V;
+            }
+        } else if (ucConfigId & FPGA_CONFIG_1_8_V) {
+            DBGPRINT(DBG_ERROR, (KERN_DEBUG "Configuration ID : 1.8V\n"));
+            // Check if registry value is ok
+            if ((RegVal >= FPGA_POWER_REG_1_8_V_MIN) &&
+                (RegVal <= FPGA_POWER_REG_1_8_V_MAX)) {
+                ucPowerValue = (SK_U8) RegVal;
+            } else {
+                ucPowerValue = FPGA_POWER_REG_1_8_V;
+            }
+        }
+    }
+#ifndef USE_FPGA_POWER_RAMP     // [fhm] ramp-up SDIO port voltage
+
+    MEM_WRITE_UCHAR(pDev, SK_SLOT_0, FPGA_POWER_REG_DATA, ucPowerValue);
+    MEM_WRITE_UCHAR(pDev, SK_SLOT_0, FPGA_POWER_REG_CMD,
+                    FPGA_POWER_REG_CMD_START);
+
+    DBGPRINT(DBG_ERROR, (KERN_DEBUG "wait for stable voltage\n"));
+    cnt = 0;
+    do {
+        MEM_READ_UCHAR(pDev, SK_SLOT_0, FPGA_POWER_REG_STATUS, &ucValue);
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG "PowerRegulatorControl: 0x%x\n", ucValue));
+    } while (++cnt < 10000 && (ucValue & FPGA_POWER_REG_STABLE) == 0);
+    DBGPRINT(DBG_ERROR, ("wait for stable voltage: cnt=%d\n", cnt));
+
+    // Turn on highest supplied voltage 
+    ucValue = MK_VOLTAGE(pDev->maxSupplyVoltage);
+    MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_POWER_CTRL, ucValue);
+
+    DBGPRINT(DBG_ERROR,
+             (KERN_DEBUG "MaxSupplyVoltage: %d\n", pDev->maxSupplyVoltage));
+
+    ucValue = MK_VOLTAGE(pDev->maxSupplyVoltage) | STDHOST_POWER_ON;
+    MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_POWER_CTRL, ucValue);
+
+#else
+    _SLEEP_MS(pDev, 100);       // [mb] for de-bounce 
+    for (i = 0; i < FPGA_POWER_STEPS; i++) {
+        MEM_WRITE_UCHAR(pDev, SK_SLOT_0, FPGA_POWER_REG_DATA,
+                        (SK_U8) ucPowerCurr[i]);
+        MEM_WRITE_UCHAR(pDev, SK_SLOT_0, FPGA_POWER_REG_CMD,
+                        FPGA_POWER_REG_CMD_START);
+
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG "wait for stable voltage (0x%x)\n",
+                  ucPowerCurr[i]));
+        cnt = 0;
+        do {
+            MEM_READ_UCHAR(pDev, SK_SLOT_0, FPGA_POWER_REG_STATUS, &ucValue);
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG "PowerRegulatorControl: 0x%x\n", ucValue));
+        } while (++cnt < 10000 && (ucValue & FPGA_POWER_REG_STABLE) == 0);
+        DBGPRINT(DBG_ERROR, ("wait for stable voltage: cnt=%d\n", cnt));
+        if (cnt == 10000)
+            return SK_FALSE;
+
+        // switch on SDIO port voltage if lowest voltage is stable
+        if (ucPowerCurr[i] == FPGA_POWER_REG_0_7_V) {
+            ucValue = MK_VOLTAGE(pDev->maxSupplyVoltage);
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_POWER_CTRL, ucValue);
+            ucValue = MK_VOLTAGE(pDev->maxSupplyVoltage) | STDHOST_POWER_ON;
+//[mb]
+            _SLEEP_MS(pDev, 50);        // wait until voltage has reached the
+                                        // set level 
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_POWER_CTRL, ucValue);
+        }
+        // leave for loop, if desired power level has been set
+        if (ucPowerCurr[i] == (SK_U16) ucPowerValue)
+            break;
+//[mb]
+        if ((ucPowerCurr[i] < FPGA_POWER_REG_1_2_V) &&
+            (ucPowerCurr[i] > FPGA_POWER_REG_1_0_V))
+            udelay(FPGA_POWER_RAMP_DELAY * 6);
+        else
+            udelay(FPGA_POWER_RAMP_DELAY);
+        if (i < FPGA_POWER_STEPS - 1) {
+            if (ucPowerCurr[i + 1] > (SK_U16) ucPowerValue)
+                ucPowerCurr[i + 1] = (SK_U16) ucPowerValue;
+        }
+    }
+
+#endif // [fhm]
+
+    _SLEEP_MS(pDev, 100);       // pweber 03.08.2005
+
+    if (pDev->bus_type == SDIO_SPI_TYPE) {
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG "-------------->   SPI-Mode : Send CMD0\n"));
+        MEM_READ_ULONG(pDev, SK_SLOT_0, 0x200, &ulValue);
+        ulValue |= 0x00000001;
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, 0x200, ulValue);
+
+        SDHost_SendCmd(pDev, 0, 0, 0, &ulResponse);     // CMD0 for transit to
+                                                        // SPI mode
+        SDHost_SendCmd(pDev, 59, 0, 0, &ulResponse);    // CMD59 turn off CRC
+    }
+// _SLEEP_MS( pDev, 100);  pweber 03.08.2005
+
+    if (!SDHost_ReadOCR(pDev, OCR)) {
+        DBGPRINT(DBG_W528D | DBG_ERROR, (KERN_DEBUG "ReadOCR failed!\n"));
+        return SK_FALSE;
+    }
+    // check if our supply voltage is supported
+
+    if ((OCR[0] & 0xE0) == 0)   // Support for 3.3 - 3.6 V
+    {
+        DBGPRINT(DBG_W528D | DBG_ERROR,
+                 (KERN_DEBUG "Card does not support our supply voltage!\n"));
+        return SK_FALSE;
+    }
+
+    if (!SDHost_WriteOCR(pDev, OCR)) {
+        DBGPRINT(DBG_W528D | DBG_ERROR, (KERN_DEBUG "WriteOCR failed!\n"));
+        return SK_FALSE;
+    }
+
+    if (pDev->bus_type == SDIO_BUS_TYPE) {
+        // Send CMD3 ident -> standby
+        if (!SDHost_ReadRCA(pDev, RCA)) {
+            return SK_FALSE;
+        }
+
+        if (RCA[0] == 0 && RCA[1] == 0) {
+            // Try to get new RCA
+            if (!SDHost_ReadRCA(pDev, RCA)) {
+                return SK_FALSE;
+            }
+            if (RCA[0] == 0 && RCA[1] == 0) {
+                // Failed to get a valid RCA
+                return SK_FALSE;
+            }
+        }
+        ulArg = RCA[0] << 24 | RCA[1] << 16;
+        // CMD7 to select card and go to transfer state.
+        if (!SDHost_SendCmd(pDev, 7, ulArg, 0, &ulResponse)) {
+            if (++pDev->bus_errors > MAX_BUS_ERRORS) {
+                SDHost_SetCardOutEvent(pDev);
+            }
+            return SK_FALSE;
+        }
+    }
+
+    j = 0;
+    while (j++ < 5) {
+        // IO Enable all supported functions
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG "IO Enable all supported functions: 0x%2.02X\n",
+                  ena_func[pDev->number_of_functions]));
+        SDHost_CMD52_Write(pDev, IO_ENABLE_REG, 0,
+                           ena_func[pDev->number_of_functions]);
+        if (SDHost_CMD52_Read(pDev, IO_ENABLE_REG, 0, &R)) {
+            break;
+        }
+    }
+
+    if (j >= 5) {
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG "FN0 : I/O Enable FAILED!!!!!!!!!!!!\n"));
+        return SK_FALSE;
+    }
+
+                     /*--- mmoser 3/22/2006 ---*/
+    j = 0;
+    while (j++ < 5) {
+        // INT Enable function 0
+        if (SDHost_CMD52_Write
+            (pDev, INT_ENABLE_REG, 0,
+             ena_func[pDev->number_of_functions] | IENM)) {
+            SDHost_CMD52_Read(pDev, INT_ENABLE_REG, 0, &R);
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "FN0 : INT Enable 0x%2.02X\n", R));
+            break;
+        }
+    }
+
+    if (j >= 5) {
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG "FN0 : INT Enable FAILED!!!!!!!!!!!!\n"));
+        return SK_FALSE;
+    }
+
+    // IO Ready function 1
+    if (SDHost_CMD52_Read(pDev, IO_READY_REG, 0, &R)) {
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "I/O Ready(R/O) 0x%2.02X\n", R));
+    }
+    // Read Card Capability
+    if (SDHost_CMD52_Read(pDev, CARD_CAPABILITY_REG, 0, &R)) {
+#ifdef DBG
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "Card Capability\n"));
+        if (R & 0x01) {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       SDC:CMD52 supported\n"));
+        } else {
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG "       SDC:CMD52 not supported\n"));
+        }
+        if (R & 0x02) {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       SMB:CMD53 supported\n"));
+        } else {
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG "       SMB:CMD53 not supported\n"));
+        }
+        if (R & 0x04) {
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG "       SRW:Read Wait supported\n"));
+        } else {
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG "       SRW:Read Wait not supported\n"));
+        }
+        if (R & 0x08) {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       SBS supported\n"));
+        } else {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       SBD not supported\n"));
+        }
+        if (R & 0x10) {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       S4MI supported\n"));
+        } else {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       S4MI not supported\n"));
+        }
+        if (R & 0x20) {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       E4MI supported(R/W)\n"));
+        } else {
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG "       E4MI not supported(R/W)\n"));
+        }
+        if (R & 0x40) {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       LSC supported\n"));
+        } else {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       LSC not supported\n"));
+        }
+        if (R & 0x80) {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       4BLS supported\n"));
+        } else {
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "       4BLS not supported\n"));
+        }
+#endif
+    }
+    if (SDHost_CMD52_Read(pDev, FUNCTION_SELECT_REG, 0, &R)) {
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG
+                  "Card Function Selected for Suspend/Resume(R/W) 0x%2.02X!\n",
+                  R));
+    }
+    // Exec Flags
+    if (SDHost_CMD52_Read(pDev, EXEC_FLAGS_REG, 0, &R)) {
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "Exec Flags(R/O)0x%2.02X\n", R));
+    }
+    // Ready Flags
+    if (SDHost_CMD52_Read(pDev, READY_FLAGS_REG, 0, &R)) {
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "Ready Flags(R/O)0x%2.02X\n", R));
+    }
+
+    if (pDev->bus_width == SDIO_4_BIT) {
+        SDHost_CMD52_Write(pDev, BUS_INTERFACE_CONTROL_REG, 0, 0x82);   // 0x80:CD 
+                                                                        // disable,1 
+                                                                        // bit;0x82:CD 
+                                                                        // disable,4 
+                                                                        // bit
+    } else {
+        SDHost_CMD52_Write(pDev, BUS_INTERFACE_CONTROL_REG, 0, 0x80);   // 0x80:CD 
+                                                                        // disable,1 
+                                                                        // bit;0x82:CD 
+                                                                        // disable,4 
+                                                                        // bit
+    }
+
+    SDHost_CMD52_Read(pDev, BUS_INTERFACE_CONTROL_REG, 0, &R);
+
+    switch (R & 0x0F) {
+    case 0x02:
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "4 bit mode,"));
+        break;
+    case 0x00:
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "1 bit mode,"));
+        break;
+    default:
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "1 or 4 bit mode error,"));
+    }
+    if ((R & 0xF0) == 0x80) {
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "CD Disable!\n"));
+    } else {
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "CD Enable!\n"));
+    }
+
+    SDHost_Enable_HighSpeedMode(pDev);
+
+    // set function 0-7 block size
+    for (i = 0; i <= pDev->number_of_functions; i++) {
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_0_REG(i), 0,
+                           (SK_U8) (block_size & 0x00ff));
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_1_REG(i), 0,
+                           (SK_U8) (block_size >> 8));
+        pDev->sd_ids[i].blocksize = block_size;
+    }
+
+/*
+ for (i=0;i<8;i++)
+ {
+	 SDHost_DumpCIS(pDev, i, 512 );
+ }
+*/
+
+    for (i = 0; i <= pDev->number_of_functions; i++) {
+        if (!SDHost_CMD52_Read(pDev, FN_CIS_POINTER_0_REG(i), 0, &R)) {
+            break;
+        }
+        pDev->cisptr[i] = R;
+        if (!SDHost_CMD52_Read(pDev, FN_CIS_POINTER_1_REG(i), 0, &R)) {
+            pDev->cisptr[i] = 0;
+        }
+        pDev->cisptr[i] |= (R << 8);
+    }
+
+    cislength = DEVICE_NAME_LENGTH;
+    if (!SDHost_ReadCIS(pDev, 0, CISTPL_VERS_1, Cis, &cislength)) {
+        return SK_FALSE;
+    }
+    if (cislength > 0) {
+        memcpy(pDev->DeviceName, "SDIOBus\\", 8);
+        for (i = 0, j = 8; i < cislength; i++) {
+            pDev->DeviceName[j++] = (Cis[i] == ' ' ? '_' : Cis[i]);
+        }
+        pDev->DeviceName[j++] = 0;
+        pDev->DeviceNameLength = j;
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG "       DeviceName (len=%d): %s\n",
+                  pDev->DeviceNameLength, pDev->DeviceName));
+    }
+
+    cislength = 4;
+    if (!SDHost_ReadCIS(pDev, 0, CISTPL_MANFID, Cis, &cislength)) {
+        return SK_FALSE;
+    }
+    if (cislength > 0) {
+        unsigned short vendor, device;
+        vendor = *((short *) Cis);
+        device = *((short *) &Cis[2]);
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "%s: vendor=0x%4.04X device=0x%4.04X\n",
+                  __FUNCTION__, vendor, device));
+        for (i = 0; i <= pDev->number_of_functions; i++) {
+            pDev->sd_ids[i].vendor = vendor;
+            pDev->sd_ids[i].device = device;
+            pDev->sd_ids[i].fn = i;
+            if (i > 0) {
+                if (SDHost_ReadCIS(pDev, i, CISTPL_MANFID, Cis, &cislength)) {
+                    if (cislength > 0) {
+                        pDev->sd_ids[i].vendor = *((short *) Cis);
+                        pDev->sd_ids[i].device = *((short *) &Cis[2]);
+                    }
+                }
+                SDHost_CMD52_Read(pDev, FN_CSA_REG(i), 0, &R);
+                pDev->sd_ids[i].class = R;
+                DBGPRINT(DBG_LOAD,
+                         (KERN_DEBUG
+                          "fn%d: class=0x%4.04X vendor=0x%4.04X,device=0x%4.04X\n",
+                          i, pDev->sd_ids[i].class, pDev->sd_ids[i].vendor,
+                          pDev->sd_ids[i].device));
+            } else {
+                pDev->sd_ids[i].class = 0;
+            }
+        }
+    }
+    // Clear irq status bits
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, 0xFFFF);
+
+                     /*--- mmoser 08.09.2005 ---*/
+    pDev->initialized = SK_TRUE;
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *  SDHost_Init - Initialize the FPGA SDIO/CardBus interface
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+void
+SDHost_Init(PSD_DEVICE_DATA pDev)
+{
+    SK_U32 ulVal;
+    SK_U8 ucHostCtrl = 0;
+    SK_U16 usVal;
+
+    ENTER();
+
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "SDHost_Init(pDev=0x%p, IOBase=0x%p)\n", pDev,
+              pDev->IOBase[0]));
+
+                      /*--- mmoser 4/4/2006 ---*/
+    pDev->SurpriseRemoved = 0;
+
+    // issue software reset
+    MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_SW_RESET, STDHOST_SW_RESET_ALL);
+
+    DBGPRINT(DBG_LOAD, (KERN_DEBUG "SDHost_Init() line=%d\n", __LINE__));
+
+    // Read the Host Controller Version
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_HOST_CONTROLLER_VERSION, &usVal);
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG
+              "SD Host Spec Version 0x%2.02X - Vendor Version 0x%2.02x\n",
+              GET_SPEC_VERSION_NR(usVal), GET_VENDOR_VERSION_NR(usVal)));
+
+    if (pDev->bus_type == SDIO_BUS_TYPE && pDev->bus_width == SDIO_4_BIT) {
+        ucHostCtrl |= STDHOST_4_BIT_ENA;
+    }
+    // Read capabilities 
+    MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_CAPABILITIES, &ulVal);
+
+    if ((ulVal & STDHOST_CAP_VOLTAGE_1_8) == STDHOST_CAP_VOLTAGE_1_8) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "1.8V supported\n"));
+        pDev->maxSupplyVoltage = STDHOST_VOLTAGE_1_8_V;
+    }
+    if ((ulVal & STDHOST_CAP_VOLTAGE_3_0) == STDHOST_CAP_VOLTAGE_3_0) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "3.0V supported\n"));
+        pDev->maxSupplyVoltage = STDHOST_VOLTAGE_3_0_V;
+    }
+    if ((ulVal & STDHOST_CAP_VOLTAGE_3_3) == STDHOST_CAP_VOLTAGE_3_3) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "3.3V supported\n"));
+        pDev->maxSupplyVoltage = STDHOST_VOLTAGE_3_3_V;
+    }
+    if ((ulVal & STDHOST_CAP_SUSPENSE_RESUME) == STDHOST_CAP_SUSPENSE_RESUME) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "Suspense/resume supported\n"));
+    }
+    if ((ulVal & STDHOST_CAP_DMA) == STDHOST_CAP_DMA) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "DMA supported\n"));
+    }
+    if ((ulVal & STDHOST_CAP_HIGH_SPEED) == STDHOST_CAP_HIGH_SPEED) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "High speed supported\n"));
+        ucHostCtrl |= STDHOST_HIGH_SPEED_ENA;
+    }
+    pDev->max_block_size = SD_BLOCK_SIZE;
+    if ((ulVal & STDHOST_CAP_MAX_BLOCK_512) == STDHOST_CAP_MAX_BLOCK_512) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "Max Block Length : 512\n"));
+        pDev->max_block_size = 512;
+    } else if ((ulVal & STDHOST_CAP_MAX_BLOCK_1024) ==
+               STDHOST_CAP_MAX_BLOCK_1024) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "Max Block Length : 1024\n"));
+        pDev->max_block_size = 1024;
+    } else if ((ulVal & STDHOST_CAP_MAX_BLOCK_2048) ==
+               STDHOST_CAP_MAX_BLOCK_2048) {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "Max Block Length : 2048\n"));
+        pDev->max_block_size = 2048;
+    }
+    if (block_size > pDev->max_block_size)
+        block_size = pDev->max_block_size;
+
+    pDev->baseClockFreq = GET_CAP_BASE_CLOCK_FREQ(ulVal);
+
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "Base clock : %d MHz\n", pDev->baseClockFreq));
+
+    if ((ulVal & STDHOST_CAP_TIMEOUT_CLOCK_UNIT_MHZ) ==
+        STDHOST_CAP_TIMEOUT_CLOCK_UNIT_MHZ) {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "Timeout clock : %d MHz\n",
+                  (ulVal & STDHOST_CAP_TIMEOUT_CLOCK_FREQ)));
+    } else {
+        DBGPRINT(DBG_LOAD, (KERN_DEBUG "Timeout clock : %d kHz\n",
+                            (ulVal & STDHOST_CAP_TIMEOUT_CLOCK_FREQ)));
+    }
+
+    // Read the max current capabilities
+    MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_MAX_CURRENT_CAP, &ulVal);
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "Max. current @1.8V=%dmA @3.0V=%dmA @3.3V=%dmA\n",
+              CALC_MAX_CURRENT_IN_MA(GET_MAX_CURRENT_CAP_1_8_V(ulVal)),
+              CALC_MAX_CURRENT_IN_MA(GET_MAX_CURRENT_CAP_3_0_V(ulVal)),
+              CALC_MAX_CURRENT_IN_MA(GET_MAX_CURRENT_CAP_3_3_V(ulVal))));
+
+    // Setup host control register
+    MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_HOST_CTRL, ucHostCtrl);
+
+                     /*--- mmoser 14.09.2005 ---*/
+    // Reset all pending irq bits 
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, 0xFFFF);
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS, 0xFFFF);
+
+    // Enable error irq status
+    usVal = 0xFFFF;
+    // usVal = STDHOST_ERROR_IRQ_VENDOR_SIG_ENA;
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS_ENABLE, usVal);
+
+                                                                                                                                                                                        /*--- mmoser 1/2/2007 ---*/
+    // Enable GPI interrupts
+
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                     STDHOST_ERROR_IRQ_VENDOR_SIG_ENA);
+
+    // Enable card detect
+    usVal = 0xFFFF;
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE, usVal);
+    usVal = STDHOST_NORMAL_IRQ_CARD_ALL_ENA;
+    usVal &= ~STDHOST_NORMAL_IRQ_CARD_SIG_ENA;  // Don't enable card interrupt
+                                                // at this point!
+    pDev->lastIRQSignalMask = 0;
+    pDev->currentIRQSignalMask = usVal;
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_SIGNAL_ENABLE, usVal);
+
+    MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_PRESENT_STATE, &ulVal);
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "SDHost_Init() : present state=0x%8.08X\n", ulVal));
+
+                     /*--- mmoser 12.09.2005 ---*/
+    pDev->initialized = SK_TRUE;
+
+    LEAVE();
+
+}
+
+/******************************************************************************
+ *
+ * SDHost_isCardPresent  - checks whether a SDIO card is in the SDIO socket
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE   card is in socket
+ *     SK_FALSE  no card in socket
+ *
+ */
+SK_BOOL
+SDHost_isCardPresent(PSD_DEVICE_DATA pDev)
+{
+    SK_U32 ulVal;
+    SK_U16 usVal;
+
+// mmoser 2005-11-21 
+                        /*--- mmoser 13.09.2005 ---*/
+    if (pDev->SurpriseRemoved) {
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG
+                  "SDHost_isCardPresent: Surprise Removal of Card!\n"));
+        return SK_FALSE;
+    }
+
+    if (pDev->initialized == SK_FALSE) {
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG
+                  "SDHost_isCardPresent(): SD Host Adapter is NOT initialized. (%d)\n",
+                  pDev->initialized));
+        return SK_FALSE;
+    }
+    // Read the Host Controller Version to check if SD Host adapter is
+    // available
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_HOST_CONTROLLER_VERSION, &usVal);
+    if (usVal == 0xFFFF) {
+        // There is probably no SD Host Adapter available
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG
+                  "SDHost_isCardPresent(): SD Host Adapter is NOT present. (%4.04X)\n",
+                  usVal));
+        return SK_FALSE;
+    }
+    // Read present state register to check whether a SD card is present
+    MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_PRESENT_STATE, &ulVal);
+    if ((ulVal & STDHOST_STATE_CARD_INSERTED) == 0) {
+        // There is probably no card in the socket
+        DBGPRINT(DBG_W528D,
+                 (KERN_DEBUG
+                  "SDHost_isCardPresent(): Card is NOT present. (%8.08X)\n",
+                  ulVal));
+        return SK_FALSE;
+    }
+
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *  SDHost_SendCmd - Send a SDIO command to the card
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ */
+SK_BOOL
+SDHost_SendCmd(PSD_DEVICE_DATA pDev, SK_U8 cmd, SK_U32 arg, SK_U16 transferMode,
+               SK_U32 * pulResp)
+{
+    SK_U32 retry, max_retry;
+    SK_U32 ulVal;
+    SK_U16 usCmd;
+    SK_U32 ulIrq;
+    SK_U16 usSigEna;
+
+    // max_retry depends on actual bus clock speed
+    max_retry =
+        MAX_WAIT_COMMAND_INHIBIT * (pDev->ClockSpeed ==
+                                    0 ? 1 : pDev->ClockSpeed);
+
+    // Read present state register to check whether Command Inhibit (CMD) = 0
+    for (retry = 0; retry < max_retry; retry++) {
+        MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_PRESENT_STATE, &ulVal);
+        if (cmd == 53) {
+            if ((ulVal & STDHOST_STATE_CMD_INHIB_DAT) == 0) {
+                break;
+            }
+        } else {
+            if ((ulVal & STDHOST_STATE_CMD_INHIB_CMD) == 0) {
+                break;
+            }
+        }
+  /*--- mmoser 3/7/2006 ---*/
+        if (retry & 0xFFFFFFFE)
+            UDELAY(1);
+    }
+    if (retry >= max_retry) {
+        if (cmd == 53) {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "SDHost_SendCmd() : Command Inhibit DAT remains busy! (max_retry=%d)\n",
+                      max_retry));
+            // reset the data line and FIFO
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                            STDHOST_SW_RESET, STDHOST_SW_RESET_DAT_LINE);
+            UDELAY(10);         // wait until reset is complete
+
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_SW_RESET, 0);
+        } else {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "SDHost_SendCmd() : Command Inhibit CMD remains busy! (max_retry=%d)\n",
+                      max_retry));
+            // reset the cmd line
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                            STDHOST_SW_RESET, STDHOST_SW_RESET_CMD_LINE);
+            UDELAY(10);         // wait until reset is complete
+
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_SW_RESET, 0);
+        }
+        return SK_FALSE;
+    }
+    // clear irq bit
+
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, 0xFFFF0000 |    // ERROR_IRQ_STATUS
+                    STDHOST_NORMAL_IRQ_ERROR |
+                    STDHOST_NORMAL_IRQ_TRANS_COMPLETE |
+                    STDHOST_NORMAL_IRQ_CMD_COMPLETE);
+
+    usCmd = MK_CMD(cmd) | MK_CMD_TYPE(STDHOST_CMD_TYPE_NORMAL);
+
+    switch (cmd) {
+    case 0:
+        {
+            usCmd |= STDHOST_RESP_TYPE_NONE;
+            break;
+        }
+    case 3:
+        {
+            usCmd |= STDHOST_CMD_INDEX_CHK_ENA |
+                STDHOST_CMD_CRC_CHK_ENA | STDHOST_RESP_TYPE_R6;
+            break;
+        }
+    case 5:
+        {
+            usCmd |= STDHOST_RESP_TYPE_R4;
+            break;
+        }
+    case 7:
+        {
+            usCmd |= STDHOST_CMD_INDEX_CHK_ENA |
+                STDHOST_CMD_CRC_CHK_ENA | STDHOST_RESP_TYPE_R1b;
+            break;
+        }
+    case 52:
+    case 53:
+        {
+            usCmd |= STDHOST_CMD_INDEX_CHK_ENA |
+                STDHOST_CMD_CRC_CHK_ENA | STDHOST_RESP_TYPE_R5;
+            break;
+        }
+    case 59:
+        {
+            usCmd |= STDHOST_RESP_TYPE_NONE;
+            break;
+        }
+    default:
+        {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "SDHost_SendCmd() : Command 0x%2.02X not supported!\n",
+                      cmd));
+            return SK_FALSE;
+        }
+    }
+
+    MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, &ulVal);
+
+    clear_bit(0, &pDev->cmd_complete_evt.event);
+
+    // mmoser 2007-06-08 : Ensure that CMD_COMPLETE signal is enabled
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                    &usSigEna);
+    usSigEna |= STDHOST_NORMAL_IRQ_CMD_COMPLETE_ENA;
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                     usSigEna);
+
+    pDev->errorOccured = 0;
+
+    // initiate the cmd
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_CMD_ARGUMENT, arg);
+    ulVal = (usCmd << 16) | transferMode;
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_TRANSFER_MODE, ulVal);
+
+#ifdef DBG
+    if ((pDev->debug_flags & DEBUG_SHOW_REG_10_14) == DEBUG_SHOW_REG_10_14) {
+        if (cmd == 53) {
+            for (retry = 0; retry < 10; retry++) {
+                SK_U32 ulR1, ulR2;
+                MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_RESP_BITS_31_0, &ulR1);
+                MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_RESP_BITS_63_32, &ulR2);
+                DBGPRINT(DBG_W528D,
+                         (KERN_DEBUG
+                          "retry=%d 63-32 : 0x%8.08X 31-0 : 0x%8.08X\n", retry,
+                          ulR2, ulR1));
+            }
+        }
+    }
+#endif
+
+     /**/ if (pDev->currentIRQSignalMask & STDHOST_NORMAL_IRQ_CMD_COMPLETE) {
+//printk("%s @ %d: Wait CMD complete\n",__FUNCTION__,__LINE__);
+        if (SDHost_wait_event(pDev, &pDev->cmd_complete_evt, 100)) {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG "%s @ %d: Wait CMD complete ---> FAILED !\n",
+                      __FUNCTION__, __LINE__));
+            return SK_FALSE;
+        }
+        clear_bit(0, &pDev->cmd_complete_evt.event);
+    } else
+        /**/ {
+        max_retry =
+            MAX_WAIT_COMMAND_COMPLETE * 10 * (pDev->ClockSpeed ==
+                                              0 ? 1 : pDev->ClockSpeed);
+        // Wait for end of command 
+        for (retry = 0; retry < max_retry; retry++) {
+            MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, &ulIrq);
+            if ((ulIrq & STDHOST_NORMAL_IRQ_CMD_COMPLETE) ==
+                STDHOST_NORMAL_IRQ_CMD_COMPLETE) {
+                MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                                STDHOST_NORMAL_IRQ_CMD_COMPLETE);
+
+                break;
+            }
+   /*--- mmoser 3/7/2006 ---*/
+            if (retry & 0xFFFFFFFE)
+                UDELAY(1);
+        }
+        if (retry >= max_retry) {
+
+            MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                            &usCmd);
+//              printk("status_enable=0x%4.04X\n",usCmd);
+            if ((usCmd & STDHOST_NORMAL_IRQ_CMD_COMPLETE_ENA) == 0) {
+                usCmd |= STDHOST_NORMAL_IRQ_CMD_COMPLETE_ENA;
+                MEM_WRITE_USHORT(pDev, SK_SLOT_0,
+                                 STDHOST_NORMAL_IRQ_STATUS_ENABLE, usCmd);
+                MEM_READ_USHORT(pDev, SK_SLOT_0,
+                                STDHOST_NORMAL_IRQ_STATUS_ENABLE, &usCmd);
+//                      printk("RESTORED:status_enable=0x%4.04X\n",usCmd);
+            }
+
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "SDHost_SendCmd() : Command not completed! (max_retry=%d)\n",
+                      max_retry));
+//       printk("#");
+            return SK_FALSE;
+        }
+
+        }
+    MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_RESP_BITS_31_0, pulResp);
+
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *  SDHost_SendAbort - Aborts an SDIO CMD53 block transfer
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ */
+SK_BOOL
+SDHost_SendAbort(PSD_DEVICE_DATA pDev)
+{
+
+//      return SDHost_CMD52_Write(pDev, IO_ABORT_REG, 0, 0x03); 
+
+//#ifdef __XXX__
+    SK_U32 retry, max_retry;
+    SK_U32 ulVal;
+    SK_U32 ulArg;
+    SK_U16 usCmd;
+// SK_U32 ulIrq;
+
+    ulArg = MAKE_SDIO_OFFSET(IO_ABORT_REG) | MAKE_SDIO_FUNCTION(0x00) | 0x07;
+
+    // max_retry depends on actual bus clock speed
+    max_retry =
+        MAX_WAIT_COMMAND_INHIBIT * (pDev->ClockSpeed ==
+                                    0 ? 1 : pDev->ClockSpeed);
+
+    // clear irq bit
+
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                    STDHOST_NORMAL_IRQ_TRANS_COMPLETE |
+                    STDHOST_NORMAL_IRQ_CMD_COMPLETE);
+
+                     /*--- mmoser 3/7/2006 ---*/
+    MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, &ulVal);
+
+    usCmd = MK_CMD(52) |
+        MK_CMD_TYPE(STDHOST_CMD_TYPE_ABORT) |
+        STDHOST_CMD_INDEX_CHK_ENA |
+        STDHOST_CMD_CRC_CHK_ENA | STDHOST_RESP_TYPE_R5;
+
+    // initiate the cmd
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_CMD_ARGUMENT, ulArg);
+
+    ulVal = (usCmd << 16) | STDHOST_READ_DIR_SELECT;
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_TRANSFER_MODE, ulVal);
+
+    // Read present state register to check whether Command Inhibit (CMD) = 0
+    for (retry = 0; retry < max_retry; retry++) {
+        MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_PRESENT_STATE, &ulVal);
+        if (((ulVal & STDHOST_STATE_CMD_INHIB_DAT) == 0) &&
+            ((ulVal & STDHOST_STATE_CMD_INHIB_CMD) == 0)) {
+            break;
+        }
+        UDELAY(1);
+    }
+    if (retry >= max_retry) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "SDHost_SendAbort() : Command Inhibit (CMD/DAT) remains busy! (max_retry=%d)\n",
+                  max_retry));
+        return SK_FALSE;
+    }
+
+    return SK_TRUE;
+//#endif
+}
+
+/******************************************************************************
+ *
+ *   isCmdFailed - checks whether the FPGA reports an error condition
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+isCmdFailed(PSD_DEVICE_DATA pDev)
+{
+    SK_U16 errStatus;
+
+    // Read error status register
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS, &errStatus);
+
+    if ((errStatus & 0x00FF) != 0) {
+        printk("%s: 0x%4.04X: ", __FUNCTION__, errStatus);
+        if (errStatus & STDHOST_ERROR_IRQ_CURRENT_LIMIT) {
+            printk("CURRENT_LIMIT ");
+        }
+        if (errStatus & STDHOST_ERROR_IRQ_DATA_END_BIT) {
+            printk("DATA_END_BIT ");
+        }
+        if (errStatus & STDHOST_ERROR_IRQ_DATA_CRC) {
+            printk("DATA_CRC ");
+        }
+        if (errStatus & STDHOST_ERROR_IRQ_DATA_TIMEOUT) {
+            printk("DATA_TIMEOUT ");
+        }
+        if (errStatus & STDHOST_ERROR_IRQ_CMD_INDEX) {
+            printk("CMD_INDEX ");
+        }
+        if (errStatus & STDHOST_ERROR_IRQ_CMD_END_BIT) {
+            printk("CMD_END_BIT ");
+        }
+        if (errStatus & STDHOST_ERROR_IRQ_CMD_CRC) {
+            printk("CMD_CRC ");
+        } else if (errStatus & STDHOST_ERROR_IRQ_CMD_TIMEOUT) {
+            printk("CMD_TIMEOUT ");
+        }
+        printk("\n");
+
+        // Reset the error status irq register
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS, 0x00FF);
+        return SK_TRUE;
+    } else {
+        return SK_FALSE;
+    }
+}
+
+/******************************************************************************
+ *
+ *   SDHost_CMD52_Read - Read one byte from the SDIO card
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_CMD52_Read(PSD_DEVICE_DATA pDev, SK_U32 Offset, SK_U8 function_number,
+                  SK_U8 * pReturnData)
+{
+    SK_U8 Resp;
+    SK_U32 ulResponse;
+    SK_U8 D8, D16;
+    SK_U32 retry, Arg;
+
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+    SK_U16 lastIRQMask;
+    SK_U16 lastErrorIRQMask;
+
+                      /*--- mmoser 3/31/2006 ---*/
+    if (pDev->SurpriseRemoved == SK_TRUE) {
+        printk
+            ("CMD52 READ FAILED : Surprise Removed !!!  fn=%2.02X reg=%8.08X (bus_errors=%d)\n",
+             function_number, Offset, pDev->bus_errors);
+        return SK_FALSE;
+    }
+
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                    &lastIRQMask);
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                    &lastErrorIRQMask);
+
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                     (lastIRQMask & (~STDHOST_NORMAL_IRQ_CARD)));
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                     (lastErrorIRQMask & (~STDHOST_ERROR_IRQ_VENDOR_ENA)));
+
+#ifdef FIFO_CMD52_DEBUG
+    MEM_READ_ULONG(pDev, SK_SLOT_0, 0x0204, &ulResponse);
+    DBGPRINT(DBG_ERROR,
+             (KERN_DEBUG "(3)RD Fifo Stat   : 0x%x  \n", ulResponse));
+
+    if (ulResponse != 0x40010000) {
+        SK_U32 tmp;
+        SK_U16 i;
+        printk("(3)RD Fifo Stat   : 0x%x  \n", ulResponse);
+        for (i = 0; i < (ulResponse & 0x3ff); i++)
+            MEM_READ_ULONG(pDev, SK_SLOT_0, 0x20, &tmp);
+    }
+
+    MEM_READ_ULONG(pDev, SK_SLOT_0, 0x0208, &ulResponse);
+    DBGPRINT(DBG_ERROR,
+             (KERN_DEBUG "(3)WR Fifo Stat   : 0x%x  \n", ulResponse));
+    if (ulResponse != 0x40000000)
+        printk("(3)WR Fifo Stat   : 0x%x  \n", ulResponse);
+#endif
+
+    Arg = MAKE_SDIO_OFFSET(Offset) | MAKE_SDIO_FUNCTION(function_number);
+
+    retry = 0;
+    while (1) {
+        if (SDHost_SendCmd(pDev, 52, Arg, STDHOST_READ_DIR_SELECT, &ulResponse)) {
+            break;
+        }
+        if (retry++ > 5) {
+/*
+		 if (++pDev->bus_errors > MAX_BUS_ERRORS )
+		 {
+			 SDHost_SetCardOutEvent(pDev);
+		 }
+*/
+            if (!SDHost_isCardPresent(pDev)) {
+                pDev->SurpriseRemoved = SK_TRUE;
+                SDHost_SetCardOutEvent(pDev);
+            }
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD52 READ FAILED : fn=%2.02X reg=%8.08X (bus_errors=%d)\n",
+                      function_number, Offset, pDev->bus_errors));
+            return SK_FALSE;
+        }
+// mmoser 2006-02-22
+        if (retry > 1) {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD52 READ FAILED : fn=%2.02X reg=%8.08X (bus_errors=%d) retry=%d\n",
+                      function_number, Offset, pDev->bus_errors, retry));
+        }
+
+        UDELAY(200);
+    }
+
+    D16 = GET_BITS_23_16(ulResponse);
+
+    Resp = D16;
+
+    if (pDev->bus_type == SDIO_BUS_TYPE) {
+        // SDIO bus
+
+        // mask 11001011
+        if (Resp & 0xCB) {
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD52 READ fn=%2.02X reg=%8.08X RESP Error:0x%2.02X (0x%8.08X)\n",
+                      function_number, Offset, Resp, ulResponse));
+            UDELAY(100);
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            return SK_FALSE;
+        } else if ((Resp & 0x30) == 0) {
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD52 READ fn=%2.02X reg=%8.08X RESP Error,card not selected!:0x%2.02X (0x%8.08X)\n",
+                      function_number, Offset, Resp, ulResponse));
+            UDELAY(100);
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            return SK_FALSE;
+        }
+    } else {
+        // SPI bus
+
+        if (Resp & 0x5C) {
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG "CMD52 READ RESP Error:0x%.2X\n", Resp));
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            return SK_FALSE;
+        }
+    }
+    if (isCmdFailed(pDev)) {
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                         lastIRQMask);
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                         lastErrorIRQMask);
+        return SK_FALSE;
+    }
+
+    D8 = GET_BITS_15_08(ulResponse);
+    *pReturnData = D8;
+
+    if (pDev->bus_errors > 0) {
+        pDev->bus_errors--;
+    }
+
+    DBGPRINT(DBG_W528D_CMD52,
+             (KERN_DEBUG
+              "CMD52 READ  : fn=%2.02X reg=%8.08X data=%2.02X (%2.02X %2.02X/%8.08X)\n",
+              function_number, Offset, *pReturnData, D16, D8, ulResponse));
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                     lastIRQMask);
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                     lastErrorIRQMask);
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *   SDHost_CMD52_Write - Write one byte from the SDIO card
+ *   -
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_CMD52_Write(PSD_DEVICE_DATA pDev, SK_U32 Offset, SK_U8 function_number,
+                   SK_U8 Data)
+{
+    SK_U8 Resp;
+    SK_U32 ulResponse;
+    SK_U32 Arg, retry;
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+    SK_U16 lastIRQMask;
+    SK_U16 lastErrorIRQMask;
+
+                      /*--- mmoser 3/31/2006 ---*/
+    if (pDev->SurpriseRemoved == SK_TRUE) {
+        printk
+            ("CMD52 WRITE : Surprise Removed !!!! fn=%2.02X reg=%8.08X data=%2.02X (bus_errors=%d)\n",
+             function_number, Offset, Data, pDev->bus_errors);
+        return SK_FALSE;
+    }
+
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                    &lastIRQMask);
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                    &lastErrorIRQMask);
+
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                     (lastIRQMask & (~STDHOST_NORMAL_IRQ_CARD)));
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                     (lastErrorIRQMask & (~STDHOST_ERROR_IRQ_VENDOR_ENA)));
+
+    DBGPRINT(DBG_W528D_CMD52,
+             (KERN_DEBUG
+              "CMD52 WRITE : fn=%2.02X reg=%8.08X data=%2.02X (bus_errors=%d)\n",
+              function_number, Offset, Data, pDev->bus_errors));
+
+#ifdef FIFO_CMD52_DEBUG
+    MEM_READ_ULONG(pDev, SK_SLOT_0, 0x0204, &ulResponse);
+    DBGPRINT(DBG_ERROR,
+             (KERN_DEBUG "(4)RD Fifo Stat   : 0x%x  \n", ulResponse));
+
+    if (ulResponse != 0x40010000) {
+        SK_U32 tmp;
+        SK_U16 i;
+        printk("(4)RD Fifo Stat   : 0x%x  \n", ulResponse);
+        for (i = 0; i < (ulResponse & 0x3ff); i++)
+            MEM_READ_ULONG(pDev, SK_SLOT_0, 0x20, &tmp);
+    }
+
+    MEM_READ_ULONG(pDev, SK_SLOT_0, 0x0208, &ulResponse);
+    DBGPRINT(DBG_ERROR,
+             (KERN_DEBUG "(4)WR Fifo Stat   : 0x%x  \n", ulResponse));
+
+    if (ulResponse != 0x40000000)
+        printk("(4)WR Fifo Stat   : 0x%x  \n", ulResponse);
+#endif
+
+    Arg = MAKE_SDIO_OFFSET(Offset) |
+        MAKE_SDIO_FUNCTION(function_number) | MAKE_SDIO_DIR(1) | (SK_U8) Data;
+    retry = 0;
+    while (1) {
+
+        if (SDHost_SendCmd(pDev, 52, Arg, STDHOST_READ_DIR_SELECT, &ulResponse)) {
+            break;
+        }
+        if (retry++ > 5) {
+            if (!SDHost_isCardPresent(pDev)) {
+                pDev->SurpriseRemoved = SK_TRUE;
+                SDHost_SetCardOutEvent(pDev);
+            }
+
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD52 WRITE FAILED : fn=%2.02X reg=%8.08X data=%2.02X\n",
+                      function_number, Offset, Data));
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            return SK_FALSE;
+        }
+        UDELAY(200);
+    }
+
+    Resp = GET_BITS_23_16(ulResponse);
+
+    if (pDev->bus_type == SDIO_BUS_TYPE) {
+        // SDIO bus
+
+        // mask 11001011
+        if (Resp & 0xCB) {
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD52 READ fn=%2.02X reg=%8.08X RESP Error:0x%2.02X (0x%8.08X)\n",
+                      function_number, Offset, Resp, ulResponse));
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            return SK_FALSE;
+        } else if ((Resp & 0x30) == 0) {
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD52 READ fn=%2.02X reg=%8.08X RESP Error,card not selected!:0x%2.02X (0x%8.08X)\n",
+                      function_number, Offset, Resp, ulResponse));
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            return SK_FALSE;
+        }
+    } else {
+        // SPI bus
+
+        if (Resp & 0x5C) {
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG "CMD52 READ RESP Error:0x%.2X\n", Resp));
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            return SK_FALSE;
+        }
+    }
+
+    if (isCmdFailed(pDev)) {
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                         lastIRQMask);
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                         lastErrorIRQMask);
+        return SK_FALSE;
+    }
+    if (pDev->bus_errors > 0) {
+        pDev->bus_errors--;
+    }
+
+                                                                                                                                                                        /*--- mmoser 8/8/2007 ---*/
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                     lastIRQMask);
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                     lastErrorIRQMask);
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *  SDHost_ReadRCA - Read the RCA from SDIO card
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_ReadRCA(PSD_DEVICE_DATA pDev, SK_U8 * pRca)
+{
+    SK_U8 ucStatus1, ucStatus2;
+    SK_U32 ulResponse;
+
+    // CMD3 to read card RCA.
+    if (!SDHost_SendCmd(pDev, 3, 0, 0, &ulResponse)) {
+        if (++pDev->bus_errors > MAX_BUS_ERRORS) {
+            SDHost_SetCardOutEvent(pDev);
+        }
+        return SK_FALSE;
+    }
+
+    MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_RESP_BITS_31_0, &ulResponse);
+
+    pRca[0] = GET_BITS_39_32(ulResponse);
+    pRca[1] = GET_BITS_31_24(ulResponse);
+
+    ucStatus1 = GET_BITS_23_16(ulResponse);
+    ucStatus2 = GET_BITS_15_08(ulResponse);
+
+    DBGPRINT(DBG_W528D,
+             (KERN_DEBUG
+              "SDHost_ReadRCA: %2.02X%2.02X - CardStatus=%2.02X%2.02X\n",
+              pRca[0], pRca[1], ucStatus1 &= 0xE0, ucStatus2));
+    return SK_TRUE;
+}
+
+SK_BOOL
+is_ValidCISTuple(SK_U8 cistpl)
+{
+    switch (cistpl) {
+    case CISTPL_VERS_1:
+    case CISTPL_MANFID:
+    case CISTPL_FUNCID:
+    case CISTPL_FUNCE:
+    case CISTPL_END:
+        {
+            return SK_TRUE;
+        }
+    default:
+        {
+            return SK_FALSE;
+        }
+    }
+}
+
+/******************************************************************************
+ *
+ * SDHost_ReadCIS  - Read element 'cistpl' from the card's CIS
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_ReadCIS(PSD_DEVICE_DATA pDev, SK_U8 function_number, SK_U8 cistpl,
+               SK_U8 * pBuf, SK_U32 * length)
+{
+    SK_U8 R;
+    SK_U8 tuple;
+    SK_U8 tuple_len;
+    SK_U8 tuple_end = 0;
+    SK_U32 _cis = 0;
+
+    if (pBuf == NULL || length == NULL || *length == 0) {
+        DBGPRINT(DBG_W528D | DBG_ERROR,
+                 (KERN_DEBUG
+                  "SDHost_ReadCIS : Illegal Parameters pBuf=%p length=%d\n",
+                  pBuf, *length));
+        return SK_FALSE;
+    }
+
+    if (!SDHost_CMD52_Read(pDev, FN_CIS_POINTER_0_REG(function_number), 0, &R)) {
+        return SK_FALSE;
+    }
+    _cis = R;
+    if (!SDHost_CMD52_Read(pDev, FN_CIS_POINTER_1_REG(function_number), 0, &R)) {
+        return SK_FALSE;
+    }
+    _cis |= (R << 8);
+    if (!SDHost_CMD52_Read(pDev, FN_CIS_POINTER_2_REG(function_number), 0, &R)) {
+        return SK_FALSE;
+    }
+    _cis |= (R << 16);
+
+    // Search for CISTPL
+    if (_cis != 0) {
+        SK_U32 i = 0;
+        SK_U32 j = 0;
+
+        DBGPRINT(DBG_W528D, (KERN_DEBUG "SDHost_ReadCIS : CIS=%8.08X\n", _cis));
+
+        R = 0;
+        tuple_len = 0;
+        while (R != CISTPL_END) {
+            // Read Tuple
+            SDHost_CMD52_Read(pDev, _cis + j, function_number, &tuple);
+            j++;
+
+            R = tuple;
+            if (!is_ValidCISTuple(R)) {
+                continue;
+            }
+            // Read Tuple Length
+            SDHost_CMD52_Read(pDev, _cis + j, function_number, &tuple_len);
+            j++;
+            R = tuple;
+
+//                      printk("cistpl=0x%2.02X tuple=0x%2.02X tuple_length=%d j=%d\n",cistpl,tuple,tuple_len,j);
+            if (R != CISTPL_NULL && R != CISTPL_END) {
+                tuple_end = j + tuple_len;
+            }
+
+            if (tuple == cistpl) {
+                switch (cistpl) {
+                case CISTPL_VERS_1:
+                    {
+                        j += 2;
+                        i = 0;
+
+                        while (j < tuple_end && i < *length - 1) {
+                            SDHost_CMD52_Read(pDev, _cis + j, function_number,
+                                              &R);
+                            j++;
+//                                                      printk("%2.02X ",R);
+                            pBuf[i++] = (R == 0 ? ' ' : R);
+                        }
+                        i -= 3;
+                        pBuf[i] = 0;
+                        *length = i;
+
+                        DBGPRINT(DBG_W528D,
+                                 (KERN_DEBUG
+                                  "SDHost_ReadCIS : fn=%d cistpl=%2.02X |%s| len=%d\n",
+                                  function_number, cistpl, pBuf, *length));
+//                                              printk("\nCISTPL_VERS_1 found!\n");
+                        return SK_TRUE;
+                        break;
+                    }
+                case CISTPL_MANFID:
+                case CISTPL_FUNCID:
+                case CISTPL_FUNCE:
+                    {
+                        i = 0;
+                        DBGPRINT(DBG_W528D,
+                                 ("SDHost_ReadCIS : fn=%d cistpl=%2.02X |",
+                                  function_number, cistpl));
+                        while (j <= tuple_end && i < *length) {
+                            SDHost_CMD52_Read(pDev, _cis + j, function_number,
+                                              &R);
+                            j++;
+                            pBuf[i++] = R;
+//                                                      printk("%2.02X ",R);
+
+                            DBGPRINT(DBG_W528D, ("%2.02x ", R));
+                        }
+                        *length = i;
+
+                        DBGPRINT(DBG_W528D, ("| len=%d\n", *length));
+
+//                                              printk("\ncistpl=0x%2.02X found!\n",cistpl);
+
+                        return SK_TRUE;
+
+                        break;
+                    }
+                }
+            } else {
+                j = tuple_end;
+            }
+        }
+    }
+    DBGPRINT(DBG_W528D,
+             (KERN_DEBUG "SDHost_ReadCIS : fn=%d cistpl=%2.02X |%s| len=%d\n",
+              function_number, cistpl, pBuf, *length));
+
+    *length = 0;
+    return SK_FALSE;
+}
+
+/******************************************************************************
+ *
+ *  SDHost_ReadOCR - Read the OCR (supported voltages) from the SDIO card
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_ReadOCR(PSD_DEVICE_DATA pDev, SK_U8 * pOcr)
+{
+    SK_U32 i, j;
+    SK_U32 ulResponse;
+    SK_U8 ucValue = 0;
+// SK_U8  R1,R2,R3,R4,R5,R6;
+    SK_U8 R2, R3, R4, R5;
+
+    R2 = R3 = R4 = R5 = 0;
+    j = 0;
+    while (j++ < 5) {
+        // Wait until power cycle is complete
+        for (i = 0; i < 100; i++) {
+            if (!SDHost_SendCmd(pDev, 5, 0, 0, &ulResponse)) {
+                if (++pDev->bus_errors > MAX_BUS_ERRORS) {
+                    SDHost_SetCardOutEvent(pDev);
+                    return SK_FALSE;
+                }
+                DBGPRINT(DBG_W528D,
+                         (KERN_DEBUG "SDHost_ReadOCR() retry=%d\n", j));
+
+                continue;
+            }
+
+            R2 = GET_BITS_15_08(ulResponse);
+            R3 = GET_BITS_23_16(ulResponse);
+            R4 = GET_BITS_31_24(ulResponse);
+            R5 = GET_BITS_39_32(ulResponse);
+
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG
+                      "SDHost_ReadOCR(31-0) retry=%d  : 0x%2.02X %2.02X %2.02X %2.02X\n",
+                      j, R5, R4, R3, R2));
+
+            pDev->number_of_functions = (R5 >> 4) & 0x07;
+            ucValue = GET_BITS_39_32(ulResponse);
+
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG "SDHost_ReadOCR(%d) : 0x%2.02X\n",
+                      pDev->bus_type, ucValue));
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG "SDHost_ReadOCR() : 0x%8.08X\n", ulResponse));
+
+            if (ucValue & 0x80) {
+                // power cycle is complete
+                DBGPRINT(DBG_W528D,
+                         (KERN_DEBUG
+                          "SDHost_ReadOCR() : power cycle is complete\n"));
+                break;
+            }
+        }
+        if (i == 100) {
+            DBGPRINT(DBG_W528D | DBG_ERROR,
+                     (KERN_DEBUG
+                      "SDHost_ReadOCR() FAILED : Power cycle not complete after %d retries (0x%2.02X)!\n",
+                      i, ucValue));
+            return SK_FALSE;
+        }
+
+        pOcr[0] = R4;
+        pOcr[1] = R3;
+        pOcr[2] = R2;
+
+        if (R4 != 0 || R3 != 0) {
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG
+                      "SDHost_ReadOCR() : PwrCycle:%X,IO_n:%X,Mem_p:%X,OCR:[0x%2.02X%2.02X%2.02X]\n",
+                      ucValue & 0x80, ucValue & 0x70, ucValue & 0x40, pOcr[0],
+                      pOcr[1], pOcr[2]));
+
+            return SK_TRUE;
+        }
+    }
+
+    DBGPRINT(DBG_ERROR,
+             (KERN_DEBUG "SDHost_ReadOCR() FAILED : Cannot read OCR!\n"));
+    return SK_FALSE;
+}
+
+/******************************************************************************
+ *
+ *  SDHost_WriteOCR - Write the OCR (supported voltages) to the SDIO card
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *					SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_WriteOCR(PSD_DEVICE_DATA pDev, SK_U8 * pOcr)
+{
+    SK_U32 ulArg;
+    SK_U32 ulResponse;
+    SK_U8 ucValue;
+    SK_U32 i;
+
+    ulArg = pOcr[0] << 16 | pOcr[1] << 8 | pOcr[2];
+    // Wait until power cycle is complete
+    for (i = 0; i < 100; i++) {
+        if (!SDHost_SendCmd(pDev, 5, ulArg, 0, &ulResponse)) {
+            if (++pDev->bus_errors > MAX_BUS_ERRORS) {
+                SDHost_SetCardOutEvent(pDev);
+            }
+            return SK_FALSE;
+        }
+
+        MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_RESP_BITS_31_0, &ulResponse);
+
+        ucValue = GET_BITS_39_32(ulResponse);
+
+        if (ucValue & 0x80) {
+            // power cycle is complete
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG
+                      "I/O Power up status is ready and set new voltage ok!\n"));
+            break;
+        }
+    }
+    if (i == 100) {
+        DBGPRINT(DBG_W528D | DBG_ERROR,
+                 (KERN_DEBUG
+                  "SDHost_WriteOCR() FAILED : Power cycle not complete after %d retries!\n",
+                  i));
+        return SK_FALSE;
+    }
+    DBGPRINT(DBG_W528D,
+             (KERN_DEBUG "SDHost_WriteOCR() : PwrCycle:%X,IO_n:%X,Mem_p:%X\n",
+              ucValue & 0x80, ucValue & 0x70, ucValue & 0x40));
+
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *   SDHost_CMD53_Read - Read a block of data from the SDIO card
+ *   -
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_CMD53_Read(PSD_DEVICE_DATA pDev,
+                  SK_U32 Offset,
+                  SK_U8 function_number,
+                  SK_U8 mode,
+                  SK_U8 opcode, SK_U8 * pData, SK_U32 Count, SK_U32 blksz)
+{
+    SK_U16 uwTransferMode;
+    SK_U32 size;
+    SK_U32 i, blkCnt, Arg;
+    SK_U32 ulResponse, retry, max_retry;
+    SK_U32 *pSrc32;
+    SK_U32 *pDest32;
+    SK_U8 RESP;
+
+    DBGPRINT(DBG_ERROR,
+             (KERN_DEBUG "CMD53 READ fn=%2.02X reg=%8.08X data=0x%2.0X\n",
+              function_number, Offset, *(pData)));
+                      /*--- mmoser 3/31/2006 ---*/
+    if (pDev->SurpriseRemoved == SK_TRUE) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "CMD53 READ FAILED : Surprise Removed !!!  fn=%2.02X reg=%8.08X (bus_errors=%d)\n",
+                  function_number, Offset, pDev->bus_errors));
+        return SK_FALSE;
+    }
+
+    if (Count > 0x1FF) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "CMD53 %s READ : fn=%2.02X reg=%8.08X len=%d > 512 ERROR!!!!!!\n",
+                  (mode ? "BLOCK" : "BYTE"), function_number, Offset, Count));
+        return SK_FALSE;
+    }
+    DBGPRINT(DBG_W528D_CMD53,
+             (KERN_DEBUG "CMD53 %s READ : fn=%2.02X reg=%8.08X len=%d\n",
+              (mode ? "BLOCK" : "BYTE"), function_number, Offset, Count));
+
+    if (mode && (blksz != pDev->sd_ids[function_number].blocksize))     // block 
+                                                                        // mode
+    {
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_0_REG(function_number), 0,
+                           (SK_U8) (blksz & 0x00ff));
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_1_REG(function_number), 0,
+                           (SK_U8) (blksz >> 8));
+        pDev->sd_ids[function_number].blocksize = blksz;
+    }
+
+    uwTransferMode = STDHOST_READ_DIR_SELECT;
+
+    if (mode == BYTE_MODE) {
+        size = Count;
+
+        blkCnt = 1 << 16 | Count;
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_BLOCK_SIZE, blkCnt);
+    } else {
+        size = blksz * Count;
+
+/* 20050630 mmoser HW-Workaround */
+        if ((pDev->debug_flags & DEBUG_DISABLE_HW_WORKAROUND_RD) ==
+            DEBUG_DISABLE_HW_WORKAROUND_RD) {
+            uwTransferMode |= STDHOST_MULTI_BLOCK_SELECT;
+        } else {
+            if (Count > 1) {
+                uwTransferMode |= STDHOST_MULTI_BLOCK_SELECT;
+            }
+        }
+        uwTransferMode |= STDHOST_BLOCK_COUNT_ENA;
+
+        blkCnt = Count << 16 | blksz | DMA_16K_BOUNDARY;
+
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_BLOCK_SIZE, blkCnt);
+    }
+
+    Arg = MAKE_SDIO_OFFSET(Offset) |
+        MAKE_SDIO_OP_CODE(opcode) |
+        MAKE_SDIO_BLOCK_MODE(mode) |
+        MAKE_SDIO_FUNCTION(function_number) | (Count & 0x01FF);
+
+    retry = 0;
+    while (1) {
+        if (SDHost_SendCmd(pDev, 53, Arg, uwTransferMode, &ulResponse)) {
+            break;
+        }
+        if (retry++ > 5) {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG "CMD53 READ FAILED : fn=%2.02X reg=%8.08X\n",
+                      function_number, Offset));
+            return SK_FALSE;
+        }
+        UDELAY(5);
+    }
+
+    RESP = GET_BITS_23_16(ulResponse);
+    if (pDev->bus_type == SDIO_BUS_TYPE) {
+        if (RESP & 0xCB) {
+            DBGPRINT(DBG_W528D_CMD53,
+                     (KERN_DEBUG "CMD53 Read RESP Error:0x%.2X\n", RESP));
+            return SK_FALSE;
+        } else if ((RESP & 0x30) == 0) {
+            DBGPRINT(DBG_W528D_CMD53 | DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD53 Read RESP Error,card not selected!:0x%.2X\n",
+                      RESP));
+            return SK_FALSE;
+        }
+    } else {
+        if (RESP & 0x5C) {
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG "CMD53 READ RESP Error:0x%.2X\n", RESP));
+            return SK_FALSE;
+        }
+    }
+
+    pSrc32 =
+        (SK_U32 *) (((SK_U32) (SK_BAR((pDev), (SK_SLOT_0)))) +
+                    (STDHOST_DATA_PORT));
+    pDest32 = (SK_U32 *) pData;
+
+    retry = 0;
+    max_retry =
+        MAX_WAIT_COMMAND_COMPLETE * (pDev->ClockSpeed ==
+                                     0 ? 1 : pDev->ClockSpeed);
+
+    i = 0;
+    while (i < size) {
+        if (i % blksz == 0) {
+            retry = 0;
+
+            do {
+                MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_PRESENT_STATE,
+                               &ulResponse);
+                if ((ulResponse & STDHOST_STATE_BUFFER_RD_ENABLE) ==
+                    STDHOST_STATE_BUFFER_RD_ENABLE) {
+                    break;
+                }
+
+    /*--- mmoser 3/13/2006 ---*/
+                UDELAY(1);
+            } while (++retry < max_retry);
+   /*--- mmoser 3/3/2006 ---*/
+            if (retry >= max_retry) {
+                DBGPRINT(DBG_ERROR,
+                         (KERN_DEBUG
+                          "CMD53 READ FAILED : STDHOST_STATE_BUFFER_RD_ENABLE remains 0\nfn=%2.02X reg=%8.08X\n",
+                          function_number, Offset));
+                if (mode) {
+                    SDHost_SendAbort(pDev);
+                }
+                return SK_FALSE;
+            }
+        }
+        *pDest32 = *pSrc32;
+        pDest32++;
+        i += 4;
+    }
+
+/*
+ {
+  SK_U16 i;
+  
+  printk( KERN_DEBUG "\n%s\n", __FUNCTION__ );
+  for( i=0; i<size; i++ ) {
+   if( i % 16 ==0 )
+    printk( "\n");
+
+   printk( "%2.02X ", pData[i] );
+   
+  }
+ }
+*/
+
+    if (mode) {
+        SDHost_SendAbort(pDev);
+    }
+ /*--- mmoser 1/5/2007 ---*/
+// STDHOST_NORMAL_IRQ_ERROR is used for GPI interrupts !!!!
+//
+/*
+ MEM_READ_ULONG (pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, &ulVal);
+ if (ulVal&STDHOST_NORMAL_IRQ_ERROR)
+ {
+  SDHost_ErrorRecovery(pDev);
+  DBGPRINT(DBG_ERROR,( KERN_DEBUG "SDHost_CMD53_Read() : Command Error 0x%8.08X\n",ulVal));
+  return SK_FALSE; 
+ }
+*/
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *   SDHost_CMD53_Read_DMA - Read a block of data from the SDIO card
+ *   -
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_CMD53_Read_DMA(PSD_DEVICE_DATA pDev,
+                      SK_U32 Offset,
+                      SK_U8 function_number,
+                      SK_U8 mode,
+                      SK_U8 opcode, SK_U8 * pData, SK_U32 Count, SK_U32 blksz)
+{
+    SK_U16 uwTransferMode;
+    SK_U32 size;
+    SK_U32 blkCnt, Arg;
+    SK_U32 ulResponse, retry, max_retry;
+    SK_U8 RESP;
+    SK_U64 PhysAddr;
+    SK_U32 ulResp;
+
+                                                                                                                                                                         /*--- mmoser 1/10/2007 ---*/
+    SK_U16 lastIRQMask;
+    SK_U16 lastErrorIRQMask;
+
+ /*--- mmoser 3/31/2006 ---*/
+    if (pDev->SurpriseRemoved == SK_TRUE) {
+        printk
+            ("CMD53 READ FAILED : Surprise Removed !!!  fn=%2.02X reg=%8.08X (bus_errors=%d)\n",
+             function_number, Offset, pDev->bus_errors);
+        return SK_FALSE;
+    }
+
+    if (Count > 0x1FF) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "CMD53 %s READ : fn=%2.02X reg=%8.08X len=%d > 512 ERROR!!!!!!\n",
+                  (mode ? "BLOCK" : "BYTE"), function_number, Offset, Count));
+        return SK_FALSE;
+    }
+    clear_bit(0, &pDev->trans_complete_evt.event);
+                                                                                                                                                                         /*--- mmoser 1/10/2007 ---*/
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                    &lastIRQMask);
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                    &lastErrorIRQMask);
+
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                     (lastIRQMask & (~STDHOST_NORMAL_IRQ_CARD)));
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                     (lastErrorIRQMask & (~STDHOST_ERROR_IRQ_VENDOR_ENA)));
+
+    DBGPRINT(DBG_W528D_CMD53,
+             (KERN_DEBUG "CMD53 %s READ : fn=%2.02X reg=%8.08X len=%d\n",
+              (mode ? "BLOCK" : "BYTE"), function_number, Offset, Count));
+
+    if (mode && (blksz != pDev->sd_ids[function_number].blocksize))     // block 
+                                                                        // mode
+    {
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_0_REG(function_number), 0,
+                           (SK_U8) (blksz & 0x00ff));
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_1_REG(function_number), 0,
+                           (SK_U8) (blksz >> 8));
+        pDev->sd_ids[function_number].blocksize = blksz;
+    }
+
+    uwTransferMode = STDHOST_READ_DIR_SELECT;
+
+    if (mode == BYTE_MODE) {
+        size = Count;
+        blkCnt = 1 << 16 | Count;
+        uwTransferMode |= STDHOST_DMA_ENA;
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_BLOCK_SIZE, blkCnt);
+    } else {
+        size = blksz * Count;
+
+        /* 20050630 mmoser HW-Workaround */
+        if ((pDev->debug_flags & DEBUG_DISABLE_HW_WORKAROUND_RD) ==
+            DEBUG_DISABLE_HW_WORKAROUND_RD) {
+            uwTransferMode |= STDHOST_MULTI_BLOCK_SELECT;
+        } else {
+            if (Count > 1) {
+                uwTransferMode |= STDHOST_MULTI_BLOCK_SELECT;
+            }
+        }
+
+        uwTransferMode |= STDHOST_BLOCK_COUNT_ENA | STDHOST_DMA_ENA;
+
+        blkCnt = Count << 16 | blksz | DMA_16K_BOUNDARY;
+
+        DBGPRINT(DBG_ERROR, (KERN_DEBUG "blkCnt:   0x%x  \n", blkCnt));
+
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_BLOCK_SIZE, blkCnt);
+    }
+
+    Arg = MAKE_SDIO_OFFSET(Offset) |
+        MAKE_SDIO_OP_CODE(opcode) |
+        MAKE_SDIO_BLOCK_MODE(mode) |
+        MAKE_SDIO_FUNCTION(function_number) | (Count & 0x01FF);
+
+#ifdef SYSKT_DMA_MALIGN_TEST
+    // set the DMA address
+    PhysAddr = (SK_U64) pci_map_page(pDev->dev,
+                                     virt_to_page(pDev->dma_rbuff),
+                                     ((unsigned long) (pDev->
+                                                       dma_rbuff) & ~PAGE_MASK),
+                                     8192, PCI_DMA_FROMDEVICE);
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_SYSTEM_ADDRESS,
+                    (SK_U32) (PhysAddr + pDev->dma_start_malign +
+                              pDev->dma_rx_malign));
+// MEM_READ_ULONG (pDev, SK_SLOT_0, STDHOST_SYSTEM_ADDRESS,&ulResp); 
+// printk("dma_abuf:0x%p phys:0x%x rx_malign:%d (read-back=0x%x)\n", pDev->dma_rbuff, (SK_U32)PhysAddr, pDev->dma_rx_malign, ulResp );
+#else // SYSKT_DMA_MALIGN_TEST
+
+    // set the DMA address
+    PhysAddr = (SK_U64) pci_map_page(pDev->dev, virt_to_page(pData),
+                                     ((unsigned long) pData & ~PAGE_MASK),
+                                     size, PCI_DMA_FROMDEVICE);
+
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_SYSTEM_ADDRESS, (SK_U32) PhysAddr);
+    // printk("\n\nCMD53 READ PhysAddr: 0x%x (virt:0x%x)\n",(SK_U32) PhysAddr,
+    // (SK_U32) pData );
+#endif // SYSKT_DMA_MALIGN_TEST
+
+/*
+  DBGPRINT(DBG_ERROR,( KERN_DEBUG "\n\nCMD53 READ PhysAddr: 0x%x (virt:0x%x)\n",(SK_U32) PhysAddr, (SK_U32) pData ) ); 
+  MEM_READ_ULONG (pDev, SK_SLOT_0, 0x0204,  &ulResp);
+  DBGPRINT(DBG_ERROR, (KERN_DEBUG "(1)RD Fifo Stat   : 0x%x  \n", ulResp ));
+  MEM_READ_ULONG (pDev, SK_SLOT_0, 0x0208,  &ulResp);
+  DBGPRINT(DBG_ERROR, (KERN_DEBUG "(1)WR Fifo Stat   : 0x%x  \n", ulResp ));
+*/
+    pDev->CmdInProgress = 1;
+    clear_bit(0, &pDev->trans_complete_evt.event);
+
+    retry = 0;
+    while (1) {
+
+        if (SDHost_SendCmd(pDev, 53, Arg, uwTransferMode, &ulResponse)) {
+            break;
+        }
+        if (retry++ > 5) {
+            if (!SDHost_isCardPresent(pDev)) {
+                pDev->SurpriseRemoved = SK_TRUE;
+                SDHost_SetCardOutEvent(pDev);
+            }
+        /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG "CMD53 READ FAILED : fn=%2.02X reg=%8.08X\n",
+                      function_number, Offset));
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, size,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        }
+        UDELAY(5);
+    }
+
+    RESP = GET_BITS_23_16(ulResponse);
+    if (pDev->bus_type == SDIO_BUS_TYPE) {
+        if (RESP & 0xCB) {
+            DBGPRINT(DBG_W528D_CMD53,
+                     (KERN_DEBUG "CMD53 Read RESP Error:0x%.2X\n", RESP));
+   /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, size,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        } else if ((RESP & 0x30) == 0) {
+        /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+
+            DBGPRINT(DBG_W528D_CMD53 | DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD53 Read RESP Error,card not selected!:0x%.2X\n",
+                      RESP));
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, size,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        }
+    } else {
+        if (RESP & 0x5C) {
+        /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG "CMD53 READ RESP Error:0x%.2X\n", RESP));
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, size,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        }
+    }
+    if (isCmdFailed(pDev)) {
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                         lastIRQMask);
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                         lastErrorIRQMask);
+        pDev->CmdInProgress = 0;
+#ifdef SYSKT_DMA_MALIGN_TEST
+        pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                       PCI_DMA_FROMDEVICE);
+#else
+        pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, size,
+                       PCI_DMA_FROMDEVICE);
+#endif
+        return SK_FALSE;
+    }
+
+    retry = 0;
+    max_retry =
+        MAX_WAIT_COMMAND_COMPLETE * (pDev->ClockSpeed ==
+                                     0 ? 1 : pDev->ClockSpeed);
+
+    // wait for DMA to complete
+    if (pDev->currentIRQSignalMask & STDHOST_NORMAL_IRQ_TRANS_COMPLETE) {
+        if (SDHost_wait_event(pDev, &pDev->trans_complete_evt, 1000)) {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "%s -> SDHost_wait_event trans_complete failed\n",
+                      __FUNCTION__));
+          /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, size,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        }
+        clear_bit(0, &pDev->trans_complete_evt.event);
+    } else {
+        retry = 0;
+        if (test_bit(0, &pDev->trans_complete_evt.event) == 0) {
+            // if ( SDHost_wait_event(pDev, &pDev->trans_complete_evt, 1 ) ) {
+            do {
+                MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                               &ulResp);
+                if ((ulResp & STDHOST_NORMAL_IRQ_TRANS_COMPLETE) ==
+                    STDHOST_NORMAL_IRQ_TRANS_COMPLETE) {
+                    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                                     STDHOST_NORMAL_IRQ_TRANS_COMPLETE);
+                    break;
+                }
+                  /*--- mmoser 3/14/2006 ---*/
+                UDELAY(1);
+            } while (++retry < max_retry);
+        } else {
+            clear_bit(0, &pDev->trans_complete_evt.event);
+        }
+        if (retry >= max_retry) {
+            DBGPRINT(DBG_WARNING | DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD53 Read : STDHOST_NORMAL_IRQ_TRANS_COMPLETE not set!(count=%d max_retry=%d)\n",
+                      Count, max_retry));
+            // reset the data line and FIFO
+        }
+    }
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_TRANSFER_MODE, 0);
+
+#ifdef SYSKT_DMA_MALIGN_TEST
+    {
+        memcpy(pData,
+               (void *) (pDev->dma_rbuff + pDev->dma_start_malign +
+                         pDev->dma_rx_malign), size);
+        // pDev->dma_rx_malign++;
+        pDev->dma_rx_malign %= 64;
+    }
+    pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192, PCI_DMA_FROMDEVICE);
+#else
+    pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, size, PCI_DMA_FROMDEVICE);
+#endif
+
+#ifdef WAR_SEND_ABORT
+// Needed for FPGA workaround
+    if (mode) {
+        SDHost_SendAbort(pDev);
+    }
+#endif // WAR_SEND_ABORT
+
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                     lastIRQMask);
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                     lastErrorIRQMask);
+    pDev->CmdInProgress = 0;
+/*
+ {
+	 int j;
+	 for (j=0; j < 64 && j < size; j++)
+	 {
+		 printk("%2.02X ",pData[j]);
+		 if ((j+1)%16 == 0)
+		 {
+			 printk("\n");
+		 }
+	 }
+	 printk("\n");
+ }
+*/
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *   SDHost_CMD53_Write - Write a block of data to the SDIO card
+ *   -
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_CMD53_Write(PSD_DEVICE_DATA pDev,
+                   SK_U32 Offset,
+                   SK_U8 function_number,
+                   SK_U8 mode,
+                   SK_U8 opcode, SK_U8 * pData, SK_U32 Count, SK_U32 blksz)
+{
+    SK_U16 uwTransferMode;
+    SK_U32 Arg;
+    SK_U32 ulResponse;
+    SK_U32 blk_cnt, cnt;
+    SK_U32 *pSrc32, *pEnd32;
+    SK_U32 *pDest32;
+    SK_U8 RESP;
+    SK_U32 retry, max_retry;
+    SK_U32 i;
+
+    DBGPRINT(DBG_ERROR,
+             (KERN_DEBUG "CMD53 WRITE fn=%2.02X reg=%8.08X data=0x%2.0X\n",
+              function_number, Offset, *(pData)));
+
+ /*--- mmoser 3/31/2006 ---*/
+    if (pDev->SurpriseRemoved == SK_TRUE) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "CMD53 WRITE FAILED : Surprise Removed !!!  fn=%2.02X reg=%8.08X (bus_errors=%d)\n",
+                  function_number, Offset, pDev->bus_errors));
+        return SK_FALSE;
+    }
+    clear_bit(0, &pDev->trans_complete_evt.event);
+
+    if (Count >= 512) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "CMD53 WRITE : fn=%2.02X reg=%8.08X len=%d > 512 ERROR!!!!!!\n",
+                  function_number, Offset, Count));
+        return SK_FALSE;
+    }
+
+    DBGPRINT(DBG_W528D_CMD53,
+             (KERN_DEBUG
+              "CMD53 WRITE %s MODE : fn=%2.02X reg=%8.08X %s=%d block_size=%d\n",
+              (mode ? "BLOCK" : "BYTE"), function_number, Offset,
+              (mode ? "blocks" : "length"), Count, blksz));
+
+    if ((*(pData + 4) == 0x03) && (Count == 2)) {
+        SK_U32 x;
+        DBGPRINT(DBG_ERROR, (KERN_DEBUG "\n**** TRIGGER *****\n"));
+        MEM_READ_ULONG(pDev, SK_SLOT_0, 0x200, &x);
+        x |= ((1 << 24) | (1 << 16));
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, 0x200, x);
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG "**** pData 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n",
+                  *(pData + 0), *(pData + 1), *(pData + 2), *(pData + 3),
+                  *(pData + 4), *(pData + 5)));
+    }
+
+    if (mode && (blksz != pDev->sd_ids[function_number].blocksize))     // block 
+                                                                        // mode
+    {
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_0_REG(function_number), 0,
+                           (SK_U8) (blksz & 0x00ff));
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_1_REG(function_number), 0,
+                           (SK_U8) (blksz >> 8));
+        pDev->sd_ids[function_number].blocksize = blksz;
+    }
+    uwTransferMode = 0;
+
+    if (mode == BYTE_MODE) {
+        cnt = Count;
+
+        blk_cnt = 1 << 16 | Count;
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_BLOCK_SIZE, blk_cnt);
+    } else {
+        cnt = Count * blksz;
+
+/* 20050630 mmoser HW-Workaround */
+        if ((pDev->debug_flags & DEBUG_DISABLE_HW_WORKAROUND_WR) ==
+            DEBUG_DISABLE_HW_WORKAROUND_WR) {
+            uwTransferMode |= STDHOST_MULTI_BLOCK_SELECT;
+        } else {
+            if (Count > 1) {
+                uwTransferMode |= STDHOST_MULTI_BLOCK_SELECT;
+            }
+        }
+
+        uwTransferMode |= STDHOST_BLOCK_COUNT_ENA;
+
+        blk_cnt = Count << 16 | blksz | DMA_16K_BOUNDARY;
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_BLOCK_SIZE, blk_cnt);
+    }
+
+    pSrc32 = (SK_U32 *) pData;
+    pDest32 =
+        (SK_U32 *) (((SK_U32) (SK_BAR((pDev), (SK_SLOT_0)))) +
+                    (STDHOST_DATA_PORT));
+
+    Arg = MAKE_SDIO_OFFSET(Offset) |
+        MAKE_SDIO_OP_CODE(opcode) |
+        MAKE_SDIO_BLOCK_MODE(mode) |
+        MAKE_SDIO_FUNCTION(function_number) |
+        MAKE_SDIO_DIR(1) | (Count & 0x01FF);
+
+    max_retry =
+        MAX_WAIT_COMMAND_COMPLETE * (pDev->ClockSpeed ==
+                                     0 ? 1 : pDev->ClockSpeed);
+
+    pEnd32 = (SK_U32 *) ((SK_U32) pSrc32 + cnt);
+
+// #define PREFILL_FIFO
+
+/*** mmoser 2006-03-03 **/
+#ifdef PREFILL_FIFO
+    // --> The whole message is always written to the FIFO! each FIFO has 2K
+    // Fill the FIFO before issuing the command
+    i = 0;
+    while (i < 2000 && pSrc32 < pEnd32) {
+        if (i % blksz == 0) {
+            retry = 0;
+
+            do {
+                MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_PRESENT_STATE,
+                               &ulResponse);
+                if ((ulResponse & STDHOST_STATE_BUFFER_WR_ENABLE) ==
+                    STDHOST_STATE_BUFFER_WR_ENABLE) {
+                    break;
+                }
+
+                     /*--- mmoser 3/13/2006 ---*/
+                UDELAY(1);
+            } while (++retry < max_retry);
+
+                     /*--- mmoser 3/3/2006 ---*/
+            if (retry >= max_retry) {
+                DBGPRINT(DBG_ERROR,
+                         (KERN_DEBUG
+                          "CMD53 WRITE FAILED : STDHOST_STATE_BUFFER_WR_ENABLE remains 0\nfn=%2.02X reg=%8.08X\n",
+                          function_number, Offset));
+                return SK_FALSE;
+            }
+        }
+
+        *pDest32 = *pSrc32;
+        pSrc32++;
+        i += 4;
+    }
+#endif // PREFILL_FIFO
+
+                     /*--- mmoser 8/29/2006 ---*/
+    clear_bit(0, &pDev->trans_complete_evt.event);
+
+    retry = 0;
+    while (1) {
+
+        if (SDHost_SendCmd(pDev, 53, Arg, uwTransferMode, &ulResponse)) {
+            break;
+        }
+        if (retry++ > 5) {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG "CMD53 WRITE FAILED : fn=%2.02X reg=%8.08X\n",
+                      function_number, Offset));
+            return SK_FALSE;
+        }
+        UDELAY(5);
+    }
+
+    RESP = GET_BITS_23_16(ulResponse);
+
+    if (pDev->bus_type == SDIO_BUS_TYPE) {
+        if (RESP & 0xCB) {
+            DBGPRINT(DBG_W528D_CMD53 | DBG_ERROR,
+                     (KERN_DEBUG "CMD53 WRITE RESP Error:0x%.2X\n", RESP));
+            // reset the data line and FIFO
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                            STDHOST_SW_RESET, STDHOST_SW_RESET_DAT_LINE);
+            return SK_FALSE;
+        } else if ((RESP & 0x30) == 0) {
+            DBGPRINT(DBG_W528D | DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD53 WRITE RESP Error,card not selected!:0x%.2X\n",
+                      RESP));
+            // reset the data line and FIFO
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                            STDHOST_SW_RESET, STDHOST_SW_RESET_DAT_LINE);
+            return SK_FALSE;
+        }
+
+    } else {
+        if (RESP & 0x5C) {
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG "CMD53 WRITE RESP Error:0x%.2X\n", RESP));
+            // reset the data line and FIFO
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                            STDHOST_SW_RESET, STDHOST_SW_RESET_DAT_LINE);
+            return SK_FALSE;
+        }
+    }
+
+#ifndef PREFILL_FIFO
+    i = 0;
+#endif
+
+    // Fill FIFO with remaining data, if any ...
+    while (pSrc32 < pEnd32) {
+        if (i % blksz == 0) {
+            retry = 0;
+
+            do {
+                MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_PRESENT_STATE,
+                               &ulResponse);
+                if ((ulResponse & STDHOST_STATE_BUFFER_WR_ENABLE) ==
+                    STDHOST_STATE_BUFFER_WR_ENABLE) {
+                    break;
+                }
+
+                     /*--- mmoser 3/13/2006 ---*/
+                UDELAY(1);
+            } while (++retry < max_retry);
+                     /*--- mmoser 3/3/2006 ---*/
+            if (retry >= max_retry) {
+                DBGPRINT(DBG_ERROR,
+                         (KERN_DEBUG
+                          "CMD53 WRITE FAILED : STDHOST_STATE_BUFFER_WR_ENABLE remains 0\nfn=%2.02X reg=%8.08X\n",
+                          function_number, Offset));
+                if (mode) {
+                    SDHost_SendAbort(pDev);
+                }
+                return SK_FALSE;
+            }
+        }
+
+        *pDest32 = *pSrc32;
+        pSrc32++;
+        i += 4;
+    }
+
+    if (pDev->currentIRQSignalMask & STDHOST_NORMAL_IRQ_TRANS_COMPLETE) {
+        if (SDHost_wait_event(pDev, &pDev->trans_complete_evt, 1000)) {
+            return SK_FALSE;
+        }
+        clear_bit(0, &pDev->trans_complete_evt.event);
+    } else {
+        retry = 0;
+        do {
+            SK_U32 ulResp;
+            MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, &ulResp);
+            if ((ulResp & STDHOST_NORMAL_IRQ_TRANS_COMPLETE) ==
+                STDHOST_NORMAL_IRQ_TRANS_COMPLETE) {
+                MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                                STDHOST_NORMAL_IRQ_TRANS_COMPLETE);
+                break;
+            }
+
+                        /*--- mmoser 3/14/2006 ---*/
+            UDELAY(1);
+        } while (++retry < max_retry);
+        if (retry >= max_retry) {
+            DBGPRINT(DBG_WARNING,
+                     (KERN_DEBUG
+                      "CMD53 Write : STDHOST_NORMAL_IRQ_TRANS_COMPLETE not set!(count=%d max_retry=%d)\n",
+                      Count, max_retry));
+            // reset the data line and FIFO
+        }
+    }
+
+    if (mode) {
+        SDHost_SendAbort(pDev);
+    }
+
+ /*--- mmoser 1/5/2007 ---*/
+// STDHOST_NORMAL_IRQ_ERROR is used for GPI interrupts !!!!
+/*
+ MEM_READ_ULONG (pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS, &ulVal);
+ if (ulVal&STDHOST_NORMAL_IRQ_ERROR)
+ {
+  SDHost_ErrorRecovery(pDev);
+  DBGPRINT(DBG_ERROR,( KERN_DEBUG "SDHost_CMD53_Write() : Command Error 0x%8.08X\n",ulVal));
+  return SK_FALSE; 
+ }
+*/
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *   SDHost_CMD53_Write_DMA - Write a block of data to the SDIO card
+ *   -
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_CMD53_Write_DMA(PSD_DEVICE_DATA pDev,
+                       SK_U32 Offset,
+                       SK_U8 function_number,
+                       SK_U8 mode,
+                       SK_U8 opcode, SK_U8 * pData, SK_U32 Count, SK_U32 blksz)
+{
+    SK_U16 uwTransferMode;
+    SK_U32 Arg;
+    SK_U32 ulResponse;
+    SK_U32 blk_cnt, cnt;
+    SK_U32 *pSrc32;
+    SK_U32 *pDest32;
+    SK_U8 RESP;
+    SK_U32 retry, max_retry;
+    SK_U32 ulResp;
+    SK_U64 PhysAddr;
+ /*--- mmoser 1/10/2007 ---*/
+    SK_U16 lastIRQMask;
+    SK_U16 lastErrorIRQMask;
+
+ /*--- mmoser 3/31/2006 ---*/
+    if (pDev->SurpriseRemoved == SK_TRUE) {
+ /*--- mmoser 1/10/2007 ---*/
+        printk
+            ("CMD53 WRITE FAILED : Surprise Removed !!!  fn=%2.02X reg=%8.08X (bus_errors=%d)\n",
+             function_number, Offset, pDev->bus_errors);
+        return SK_FALSE;
+    }
+    clear_bit(0, &pDev->trans_complete_evt.event);
+
+    if (Count >= 512) {
+ /*--- mmoser 1/10/2007 ---*/
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "CMD53 WRITE : fn=%2.02X reg=%8.08X len=%d > 512 ERROR!!!!!!\n",
+                  function_number, Offset, Count));
+        return SK_FALSE;
+    }
+
+/*
+ if(( *(pData) == 0x3C) && (Count == 2) ) {
+   SK_U32 x;
+   DBGPRINT(DBG_ERROR,( KERN_DEBUG "\n**** TRIGGER *****\n"));
+   MEM_READ_ULONG (pDev, SK_SLOT_0, 0x200, &x);
+   x |= ((1 << 24) | (1 << 16)); 
+   MEM_WRITE_ULONG (pDev, SK_SLOT_0, 0x200, x);
+   DBGPRINT(DBG_ERROR,( KERN_DEBUG "**** pData 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n",
+          *(pData+0),*(pData+1),*(pData+2),*(pData+3), *(pData+4), *(pData+5)));
+ }
+*/
+                                                                                                                                                                         /*--- mmoser 1/10/2007 ---*/
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                    &lastIRQMask);
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                    &lastErrorIRQMask);
+
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                     (lastIRQMask & (~STDHOST_NORMAL_IRQ_CARD)));
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                     (lastErrorIRQMask & (~STDHOST_ERROR_IRQ_VENDOR_ENA)));
+
+    DBGPRINT(DBG_W528D_CMD53,
+             (KERN_DEBUG
+              "CMD53 WRITE %s MODE : fn=%2.02X reg=%8.08X %s=%d block_size=%d\n",
+              (mode ? "BLOCK" : "BYTE"), function_number, Offset,
+              (mode ? "blocks" : "length"), Count, blksz));
+
+    if (mode && (blksz != pDev->sd_ids[function_number].blocksize))     // block 
+                                                                        // mode
+    {
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_0_REG(function_number), 0,
+                           (SK_U8) (blksz & 0x00ff));
+        SDHost_CMD52_Write(pDev, FN_BLOCK_SIZE_1_REG(function_number), 0,
+                           (SK_U8) (blksz >> 8));
+        pDev->sd_ids[function_number].blocksize = blksz;
+    }
+    uwTransferMode = 0;
+
+    if (mode == BYTE_MODE) {
+        cnt = Count;
+
+        blk_cnt = 1 << 16 | Count;
+        uwTransferMode |= STDHOST_DMA_ENA;
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_BLOCK_SIZE, blk_cnt);
+    } else {
+        cnt = Count * blksz;
+
+/* 20050630 mmoser HW-Workaround */
+        if ((pDev->debug_flags & DEBUG_DISABLE_HW_WORKAROUND_WR) ==
+            DEBUG_DISABLE_HW_WORKAROUND_WR) {
+            uwTransferMode |= STDHOST_MULTI_BLOCK_SELECT;
+        } else {
+            if (Count > 1) {
+                uwTransferMode |= STDHOST_MULTI_BLOCK_SELECT;
+            }
+        }
+
+/*
+	{
+		int j;
+		for (j=0; j < 64 && j < cnt; j++)
+		{
+			printk("%2.02X ",pData[j]);
+			if ((j+1)%16 == 0)
+			{
+				printk("\n");
+			}
+		}
+		printk("\n");
+	}
+*/
+        // enable DMA transfer
+        uwTransferMode |= (STDHOST_BLOCK_COUNT_ENA | STDHOST_DMA_ENA);
+
+        blk_cnt = Count << 16 | blksz | DMA_16K_BOUNDARY;
+        MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_BLOCK_SIZE, blk_cnt);
+    }
+
+    pSrc32 = (SK_U32 *) pData;
+    pDest32 =
+        (SK_U32 *) (((SK_U32) (SK_BAR((pDev), (SK_SLOT_0)))) +
+                    (STDHOST_DATA_PORT));
+
+    Arg = MAKE_SDIO_OFFSET(Offset) |
+        MAKE_SDIO_OP_CODE(opcode) |
+        MAKE_SDIO_BLOCK_MODE(mode) |
+        MAKE_SDIO_FUNCTION(function_number) |
+        MAKE_SDIO_DIR(1) | (Count & 0x01FF);
+
+    max_retry =
+        MAX_WAIT_COMMAND_COMPLETE * (pDev->ClockSpeed ==
+                                     0 ? 1 : pDev->ClockSpeed);
+
+    // max_retry = MAX_WAIT_COMMAND_COMPLETE * 100 * (pDev->ClockSpeed == 0 ? 1 
+    // : pDev->ClockSpeed);
+                      /*--- mmoser 8/29/2006 ---*/
+
+#ifdef SYSKT_DMA_MALIGN_TEST
+    // set the DMA address
+    PhysAddr = (SK_U64) pci_map_page(pDev->dev,
+                                     virt_to_page(pDev->dma_tbuff),
+                                     ((unsigned long) (pDev->
+                                                       dma_tbuff) & ~PAGE_MASK),
+                                     8192, PCI_DMA_FROMDEVICE);
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_SYSTEM_ADDRESS,
+                    (SK_U32) (PhysAddr + pDev->dma_start_malign +
+                              pDev->dma_tx_malign));
+
+//  MEM_READ_ULONG (pDev, SK_SLOT_0, STDHOST_SYSTEM_ADDRESS,&ulResp); 
+// printk("dma_abuf:0x%p phys:0x%x tx_malign:%d (read-back=0x%x)\n", pDev->dma_tbuff, (SK_U32)PhysAddr, pDev->dma_tx_malign, ulResp );
+    memcpy((void *) (pDev->dma_tbuff + pDev->dma_start_malign +
+                     pDev->dma_tx_malign), pData, cnt);
+//printk("TX org: %2.02X %2.02X %2.02X %2.02X ...\n",pData[0],pData[1],pData[2],pData[3]);
+//pTmp = (SK_U8 *)(pDev->dma_tbuff+pDev->dma_start_malign+pDev->dma_tx_malign);
+//printk("TX cp : %2.02X %2.02X %2.02X %2.02X ...\n",pTmp[0],pTmp[1],pTmp[2],pTmp[3]);
+    pDev->dma_tx_malign++;
+    pDev->dma_tx_malign %= 64;
+
+#else // SYSKT_DMA_MALIGN_TEST
+    // set the DMA address
+    PhysAddr = (SK_U64) pci_map_page(pDev->dev, virt_to_page(pData),
+                                     ((unsigned long) pData & ~PAGE_MASK),
+                                     cnt, PCI_DMA_TODEVICE);
+
+    MEM_WRITE_ULONG(pDev, SK_SLOT_0, STDHOST_SYSTEM_ADDRESS, (SK_U32) PhysAddr);
+#endif
+
+    pDev->CmdInProgress = 1;
+    clear_bit(0, &pDev->trans_complete_evt.event);
+
+    retry = 0;
+    while (1) {
+
+        if (SDHost_SendCmd(pDev, 53, Arg, uwTransferMode, &ulResponse)) {
+            break;
+        }
+        if (retry++ > 5) {
+            if (!SDHost_isCardPresent(pDev)) {
+                pDev->SurpriseRemoved = SK_TRUE;
+                SDHost_SetCardOutEvent(pDev);
+            }
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG "CMD53 WRITE FAILED : fn=%2.02X reg=%8.08X\n",
+                      function_number, Offset));
+                                                                                                                                                                         /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, cnt,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        }
+        UDELAY(5);
+    }
+    RESP = GET_BITS_23_16(ulResponse);
+
+    if (pDev->bus_type == SDIO_BUS_TYPE) {
+        if (RESP & 0xCB) {
+            DBGPRINT(DBG_W528D_CMD53 | DBG_ERROR,
+                     (KERN_DEBUG "CMD53 WRITE RESP Error:0x%.2X\n", RESP));
+            // reset the data line and FIFO
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                            STDHOST_SW_RESET, STDHOST_SW_RESET_DAT_LINE);
+   /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, cnt,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        } else if ((RESP & 0x30) == 0) {
+            DBGPRINT(DBG_W528D | DBG_ERROR,
+                     (KERN_DEBUG
+                      "CMD53 WRITE RESP Error,card not selected!:0x%.2X\n",
+                      RESP));
+            // reset the data line and FIFO
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                            STDHOST_SW_RESET, STDHOST_SW_RESET_DAT_LINE);
+   /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, cnt,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        }
+
+    } else {
+        if (RESP & 0x5C) {
+            DBGPRINT(DBG_W528D_CMD52 | DBG_ERROR,
+                     (KERN_DEBUG "CMD53 WRITE RESP Error:0x%.2X\n", RESP));
+            // reset the data line and FIFO
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                            STDHOST_SW_RESET, STDHOST_SW_RESET_DAT_LINE);
+   /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, cnt,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        }
+    }
+    if (isCmdFailed(pDev)) {
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                         lastIRQMask);
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                         lastErrorIRQMask);
+        pDev->CmdInProgress = 0;
+#ifdef SYSKT_DMA_MALIGN_TEST
+        pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                       PCI_DMA_FROMDEVICE);
+#else
+        pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, cnt,
+                       PCI_DMA_FROMDEVICE);
+#endif
+        return SK_FALSE;
+    }
+    // wait for DMA to complete
+    if (pDev->currentIRQSignalMask & STDHOST_NORMAL_IRQ_TRANS_COMPLETE) {
+        if (SDHost_wait_event(pDev, &pDev->trans_complete_evt, 1000)) {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG
+                      "%s -> SDHost_wait_event trans_complete failed\n",
+                      __FUNCTION__));
+         /*--- mmoser 1/10/2007 ---*/
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                             lastIRQMask);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                             lastErrorIRQMask);
+            pDev->CmdInProgress = 0;
+#ifdef SYSKT_DMA_MALIGN_TEST
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192,
+                           PCI_DMA_FROMDEVICE);
+#else
+            pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, cnt,
+                           PCI_DMA_FROMDEVICE);
+#endif
+            return SK_FALSE;
+        }
+        clear_bit(0, &pDev->trans_complete_evt.event);
+    } else {
+        retry = 0;
+        ulResp = 0;
+        if (test_bit(0, &pDev->trans_complete_evt.event) == 0) {
+            do {
+
+                MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                               &ulResp);
+                if ((ulResp & STDHOST_NORMAL_IRQ_TRANS_COMPLETE) ==
+                    STDHOST_NORMAL_IRQ_TRANS_COMPLETE) {
+                    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                                     STDHOST_NORMAL_IRQ_TRANS_COMPLETE);
+                    break;
+                }
+                 /*--- mmoser 3/14/2006 ---*/
+                UDELAY(1);
+            } while (++retry < max_retry);
+
+        }                       // check event
+        else {
+            clear_bit(0, &pDev->trans_complete_evt.event);
+            printk("%s xxx event instead of polling\n", __FUNCTION__);
+        }
+        if (retry >= max_retry) {
+            DBGPRINT(DBG_WARNING,
+                     (KERN_DEBUG
+                      "CMD53 Write : STDHOST_NORMAL_IRQ_TRANS_COMPLETE not set!(count=%d max_retry=%d)0x%x\n",
+                      Count, max_retry, ulResp));
+            // reset the data line and FIFO
+        }
+    }
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_TRANSFER_MODE, 0);
+
+#ifdef SYSKT_DMA_MALIGN_TEST
+    pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, 8192, PCI_DMA_FROMDEVICE);
+#else
+    pci_unmap_page(pDev->dev, (dma_addr_t) PhysAddr, cnt, PCI_DMA_FROMDEVICE);
+#endif
+
+#ifdef WAR_SEND_ABORT
+// Needed for FPGA workaround
+    if (mode) {
+        SDHost_SendAbort(pDev);
+    }
+#endif // WAR_SEND_ABORT
+
+        /*--- mmoser 1/5/2007 ---*/
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE,
+                     lastIRQMask);
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                     lastErrorIRQMask);
+    pDev->CmdInProgress = 0;
+
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *   SDHost_CMD53_Read - Read a block of data from the SDIO card
+ *   -
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *					SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_CMD53_ReadEx(PSD_DEVICE_DATA pDev,
+                    SK_U32 Offset,
+                    SK_U8 function_number,
+                    SK_U8 mode,
+                    SK_U8 opcode, SK_U8 * pData, SK_U32 Count, SK_U32 blksz)
+{
+    SK_BOOL rc;
+
+    if (pDev->dma_support & DMA_RD_SUPPORT) {
+        // printk("SDHost_CMD53_ReadEx (DMA): Count=%d
+        // blksz=%d\n",Count,blksz);
+        rc = SDHost_CMD53_Read_DMA(pDev, Offset, function_number, mode, opcode,
+                                   pData, Count, blksz);
+    } else {
+        // printk("SDHost_CMD53_ReadEx: Count=%d blksz=%d\n",Count,blksz);
+        rc = SDHost_CMD53_Read(pDev, Offset, function_number, mode, opcode,
+                               pData, Count, blksz);
+    }
+
+    return rc;
+}
+
+/******************************************************************************
+ *
+ *   SDHost_CMD53_Write - Write a block of data to the SDIO card
+ *   -
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *     SK_TRUE on success
+ *
+ */
+SK_BOOL
+SDHost_CMD53_WriteEx(PSD_DEVICE_DATA pDev,
+                     SK_U32 Offset,
+                     SK_U8 function_number,
+                     SK_U8 mode,
+                     SK_U8 opcode, SK_U8 * pData, SK_U32 Count, SK_U32 blksz)
+{
+
+    if (pDev->dma_support & DMA_WR_SUPPORT) {
+        // printk("SDHost_CMD53_WriteEx (DMA): Count=%d
+        // blksz=%d\n",Count,blksz);
+        return SDHost_CMD53_Write_DMA(pDev, Offset, function_number, mode,
+                                      opcode, pData, Count, blksz);
+    } else {
+        // printk("SDHost_CMD53_WriteEx: Count=%d blksz=%d\n",Count,blksz);
+        return SDHost_CMD53_Write(pDev, Offset, function_number, mode, opcode,
+                                  pData, Count, blksz);
+    }
+}
+
+/******************************************************************************
+ *
+ * SDHost_EnableInterrupt  - Enable the interrupts on the FPGA
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_EnableInterrupt(PSD_DEVICE_DATA pDev, SK_U16 mask)
+{
+//      SK_U16 usSigEna;
+    pDev->currentIRQSignalMask |= mask;
+
+/*
+	MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE, &usSigEna);			
+	if ( (usSigEna & STDHOST_NORMAL_IRQ_CMD_COMPLETE_ENA) == 0 )
+	{
+		printk("@%d ####################################################################################################\n",__LINE__);
+	}
+*/
+
+    DBGPRINT(DBG_IRQ, (KERN_DEBUG "Enable PCI Interrupt (0x%4.04X)\n",
+                       pDev->currentIRQSignalMask));
+
+        /*--- mmoser 1/2/2007 ---*/
+    if (pDev->CmdInProgress == 0) {
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE,
+                         STDHOST_ERROR_IRQ_VENDOR_SIG_ENA);
+/*	
+		MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE, &usSigEna);			
+		if ( (usSigEna & STDHOST_NORMAL_IRQ_CMD_COMPLETE_ENA) == 0 )
+		{
+			printk("@%d ####################################################################################################\n",__LINE__);
+		}
+*/
+    }
+    // save last irq mask
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_SIGNAL_ENABLE,
+                    &pDev->lastIRQSignalMask);
+
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_SIGNAL_ENABLE,
+                     pDev->currentIRQSignalMask);
+/*
+	MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE, &usSigEna);			
+
+	if ( (usSigEna & STDHOST_NORMAL_IRQ_CMD_COMPLETE_ENA) == 0 )
+	{
+		printk("@%d #################################################################################################### (mask=0x%4.04X)\n",__LINE__,pDev->currentIRQSignalMask);
+	}
+*/
+}
+
+/******************************************************************************
+ *
+ * SDHost_DisableInterrupt  - Disable the interrupts on the FPGA
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_DisableInterrupt(PSD_DEVICE_DATA pDev, SK_U16 mask)
+{
+
+/*
+{
+	SK_U16 usSigEna;
+
+	MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE, &usSigEna);			
+	if ( (usSigEna & STDHOST_NORMAL_IRQ_CMD_COMPLETE_ENA) == 0 )
+	{
+		printk("@%d ####################################################################################################\n",__LINE__);
+	}
+
+}
+*/
+
+    // save current irq mask
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_SIGNAL_ENABLE,
+                    &pDev->currentIRQSignalMask);
+
+    pDev->lastIRQSignalMask = pDev->currentIRQSignalMask;
+
+    DBGPRINT(DBG_IRQ, (KERN_DEBUG "Disable PCI Interrupt (0x%4.04X)\n",
+                       pDev->currentIRQSignalMask & ~mask));
+
+        /*--- mmoser 1/2/2007 ---*/
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_SIGNAL_ENABLE, 0);
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_SIGNAL_ENABLE,
+                     pDev->currentIRQSignalMask & ~mask);
+/*
+{
+	SK_U16 usSigEna;
+
+	MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS_ENABLE, &usSigEna);			
+	if ( (usSigEna & STDHOST_NORMAL_IRQ_CMD_COMPLETE_ENA) == 0 )
+	{
+		printk("@%d #################################################################################################### (mask=0x%4.04X)\n",__LINE__,pDev->currentIRQSignalMask & ~mask);
+	}
+}
+*/
+    pDev->currentIRQSignalMask &= ~mask;
+
+}
+
+/******************************************************************************
+ *
+ * SDHost_if_EnableInterrupt  - Exported interface function 
+ *
+ * Description:
+ *							Exported interface function : Enable only card related interrupts
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_if_EnableInterrupt(PSD_DEVICE_DATA pDev)
+{
+    SDHost_EnableInterrupt(pDev, STDHOST_NORMAL_IRQ_CARD_ALL_ENA);
+}
+
+/******************************************************************************
+ *
+ * SDHost_if_DisableInterrupt  - Exported interface function 
+ *
+ * Description:
+ *							Exported interface function : Disable only card related interrupts
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_if_DisableInterrupt(PSD_DEVICE_DATA pDev)
+{
+    SDHost_DisableInterrupt(pDev, STDHOST_NORMAL_IRQ_CARD_ALL_ENA);
+}
+
+/******************************************************************************
+ *
+ *  SDHost_SetCardOutEvent - Set the card out event
+ *
+ * Description:
+ *
+ * Notes:	WINDOWS only 
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_SetCardOutEvent(PSD_DEVICE_DATA pDev)
+{
+    DBGPRINT(DBG_W528D,
+             (KERN_DEBUG "SDHost_SetCardOutEvent() ---> CARD REMOVED\n"));
+    if (!pDev->isRemoving) {
+        queue_work(pDev->workqueue, &pDev->card_out_work);
+    }
+}
+
+/******************************************************************************
+ *
+ * SDHost_lockInterface  - Lock the SDIO interface
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+SK_BOOL
+SDHost_lockInterface(PSD_DEVICE_DATA pDev)
+{
+#ifdef SK_SDIO_LOCK_INTERFACE
+    if (INTERLOCKED_INC(&pDev->if_lock) > 1) {
+        INTERLOCKED_DEC(&pDev->if_lock);
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG "SDHost_lockInterface() FAILED !!! if_lock=%d\n",
+                  pDev->if_lock));
+        return SK_FALSE;
+    }
+#endif
+
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ * SDHost_unlockInterface  - unlock the SDIO interface
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_unlockInterface(PSD_DEVICE_DATA pDev)
+{
+#ifdef SK_SDIO_LOCK_INTERFACE
+    if (INTERLOCKED_DEC(&pDev->if_lock) < 0) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "SDHost_unlockInterface() was already zero !!!! --> ignore.\n",
+                  pDev->if_lock));
+        INTERLOCKED_INC(&pDev->if_lock);
+    }
+#endif
+}
+
+/******************************************************************************
+ *
+ *  SDHost_SetLed - Set the LED on the FPGA interface
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_SetLed(PSD_DEVICE_DATA pDev, SK_U8 led, SK_U8 on)
+{
+    if (on) {
+        LED_ON(led);
+    } else {
+        LED_OFF(led);
+    }
+}
+
+/******************************************************************************
+ *
+ *  SDHost_SetClockSpeed - Set the SDIO bus clock speed
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_SetClockSpeed(PSD_DEVICE_DATA pDev, SK_U32 bus_freq)
+{
+    SK_U32 freq = 0;
+
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "%s: set clock to %d\n", __FUNCTION__,
+              bus_freq == 0 ? 25 : bus_freq));
+
+    if (bus_freq == 50) {
+        freq = 0;               /* 50 MHz */
+    } else if (bus_freq == 0 || bus_freq == 25) {
+        freq = 1;               /* default: 25 MHz */
+    } else if (bus_freq == 12) {
+        freq = 2;               /* 12 MHz */
+    } else if (bus_freq == 6) {
+        freq = 4;               /* 6 MHz */
+    } else if (bus_freq == 3) {
+        freq = 8;               /* 3 MHz */
+    } else if (bus_freq == 2) {
+        freq = 16;              /* 1,5 MHz */
+    } else if (bus_freq == 800) {
+        freq = 32;              /* 800 kHz */
+    } else if (bus_freq == 300) {
+        freq = 64;              /* 300 kHz */
+    } else if (bus_freq == 200) {
+        freq = 128;             /* 200 kHz */
+    } else {
+        DBGPRINT(DBG_LOAD,
+                 (KERN_DEBUG "%s: illegal clock %d\n", __FUNCTION__, bus_freq));
+        return;
+    }
+    pDev->ClockSpeed = freq;
+
+    if (!pDev->ClockSpeed) {
+        SDHost_Enable_HighSpeedMode(pDev);
+    } else {
+
+        SDHost_Disable_HighSpeedMode(pDev);
+    }
+}
+
+/******************************************************************************
+ *
+ *  SDHost_SetClock - Set the SDIO bus clock on/off
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_SetClock(PSD_DEVICE_DATA pDev, SK_U8 on)
+{
+    SK_U16 usVal;
+    int j;
+
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, &usVal);
+
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "%s: turn clock %s\n", __FUNCTION__,
+              (on == 1 ? "ON" : "OFF")));
+
+    if (on) {
+        if (usVal & STDHOST_INTERNAL_CLK_ENA) {
+            if (usVal & STDHOST_INTERNAL_CLK_STABLE) {
+                if (usVal & STDHOST_CLOCK_ENA) {
+                    // clock is already stable and running
+                    return;
+                } else {
+                    // Enable clock to card
+                    usVal |= STDHOST_CLOCK_ENA;
+                    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL,
+                                     usVal);
+                    return;
+                }
+            }
+            // there is something fishy with the clock. 
+            // -> disable internal clock first
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG "%s: SD internal clock is unstable!\n",
+                      __FUNCTION__));
+            usVal &= ~STDHOST_INTERNAL_CLK_ENA;
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, usVal);
+        }
+
+        usVal |= STDHOST_INTERNAL_CLK_ENA;
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, usVal);
+        for (j = 0; j < MAX_WAIT_CLOCK_STABLE; j++) {
+            MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, &usVal);
+            if ((usVal & STDHOST_INTERNAL_CLK_STABLE) ==
+                STDHOST_INTERNAL_CLK_STABLE) {
+                break;
+            }
+        }
+        if (j >= MAX_WAIT_CLOCK_STABLE) {
+            DBGPRINT(DBG_ERROR,
+                     (KERN_DEBUG "%s: SD clock remains unstable!\n",
+                      __FUNCTION__));
+            return;
+        }
+        // Enable clock to card
+        usVal |= STDHOST_CLOCK_ENA;
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, usVal);
+    } else {
+        // Disable clock to card
+        usVal &= ~(STDHOST_CLOCK_ENA | STDHOST_INTERNAL_CLK_ENA);
+        MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, usVal);
+    }
+}
+
+/******************************************************************************
+ *
+ *  SDHost_SetBusWidth - Set the SDIO bus width
+ *
+ * Description:
+ *
+ * Notes: see Part_A2_Host_Controller.pdf  p.61
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+SK_BOOL
+SDHost_SetBusWidth(PSD_DEVICE_DATA pDev, SK_U8 width)
+{
+    SK_U16 usValue, usOrgValue;
+    SK_U8 ucHostCtrl = 0;
+    SK_U8 orgIntEnable;
+
+    if (pDev->bus_type != SDIO_BUS_TYPE) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG "%s: not possible in current bus mode (%d)\n",
+                  __FUNCTION__, pDev->bus_type));
+        return SK_FALSE;
+    }
+
+    DBGPRINT(DBG_LOAD,
+             (KERN_DEBUG "%s: bus width = %d\n", __FUNCTION__, width));
+    // save current irq mask
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_SIGNAL_ENABLE,
+                    &usOrgValue);
+
+    // disable card interrupt
+    usValue = usOrgValue;
+    usValue &= ~STDHOST_NORMAL_IRQ_CARD_SIG_ENA;
+
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_SIGNAL_ENABLE,
+                     usValue);
+
+    // Disable Host Interrupt on card
+    if (!SDHost_CMD52_Read(pDev, INT_ENABLE_REG, 0, &orgIntEnable)) {
+        return SK_FALSE;
+    }
+    if (!SDHost_CMD52_Write(pDev, INT_ENABLE_REG, 0, 0)) {
+        return SK_FALSE;
+    }
+    // Read current host control register
+    MEM_READ_UCHAR(pDev, SK_SLOT_0, STDHOST_HOST_CTRL, &ucHostCtrl);
+
+    if (width == SDIO_4_BIT) {
+        pDev->bus_width = SDIO_4_BIT;
+        if (!SDHost_CMD52_Write(pDev, BUS_INTERFACE_CONTROL_REG, 0, 0x82))      // 0x80:CD 
+                                                                                // disable,1 
+                                                                                // bit;0x82:CD 
+                                                                                // disable,4 
+                                                                                // bit
+        {
+            return SK_FALSE;
+        }
+        ucHostCtrl |= STDHOST_4_BIT_ENA;
+    } else {
+        pDev->bus_width = SDIO_1_BIT;
+        if (!SDHost_CMD52_Write(pDev, BUS_INTERFACE_CONTROL_REG, 0, 0x80))      // 0x80:CD 
+                                                                                // disable,1 
+                                                                                // bit;0x80:CD 
+                                                                                // disable,1 
+                                                                                // bit
+        {
+            return SK_FALSE;
+        }
+        ucHostCtrl &= ~STDHOST_4_BIT_ENA;
+    }
+
+    // Setup host control register
+    MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_HOST_CTRL, ucHostCtrl);
+
+    // Re-enable Host Interrupt on card
+    if (!SDHost_CMD52_Write(pDev, INT_ENABLE_REG, 0, orgIntEnable)) {
+        return SK_FALSE;
+    }
+    // Re-enable card interrupt
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_SIGNAL_ENABLE,
+                     usOrgValue);
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *  SDHost_SetGPO - Set the GPO on/off
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+SK_BOOL
+SDHost_SetGPO(PSD_DEVICE_DATA pDev, SK_U8 on)
+{
+    if (!pDev->CardIn) {
+        return SK_FALSE;
+    }
+
+    if (on) {
+
+        GPO_ON();
+    } else {
+
+        GPO_OFF();
+    }
+    return SK_TRUE;
+}
+
+/******************************************************************************
+ *
+ *  SDHost_PsState - Set the power state of the upper layer driver
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_PsState(PSD_DEVICE_DATA pDev, SK_U8 State)
+{
+    pDev->PsState = State;
+}
+
+/******************************************************************************
+ *
+ *  SDHost_ErrorRecovery - SDIO Standard Host Spec conform error recovery
+ *
+ * Description:
+ *
+ * Notes:
+ *
+ * Context:
+ *
+ * Returns:
+ *
+ */
+VOID
+SDHost_ErrorRecovery(PSD_DEVICE_DATA pDev)
+{
+    SK_U8 ucValue;
+    SK_U16 usValue;
+    SK_U32 j, ulVal, ulDataLineMask;
+
+    // We have to do spec conform error recovery
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS, &usValue);
+    DBGPRINT(DBG_ERROR, (KERN_DEBUG "~#~#~#~#\n"));
+    DBGPRINT(DBG_W528D,
+             (KERN_DEBUG "SDHost_ErrorRecovery : ERROR_IRQ_STATUS=0x%4.04X\n",
+              usValue));
+    // 1.) check whether any of bits3-0 are set.
+    if (usValue & 0x000F) {
+        // reset the command line
+        MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                        STDHOST_SW_RESET, STDHOST_SW_RESET_CMD_LINE);
+
+        // wait until CMD line reset is 0
+        j = 0;
+        do {
+            MEM_READ_UCHAR(pDev, SK_SLOT_0, STDHOST_SW_RESET, &ucValue);
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG
+                      "SDHost_ErrorRecovery : CMD-LINE SW_RESET=0x%2.02X\n",
+                      ucValue));
+            UDELAY(2);
+        } while ((ucValue & STDHOST_SW_RESET_CMD_LINE) && j++ < 10000);
+    }
+    // 2.) check whether any of bits6-4 are set.
+    if (usValue & 0x0070) {
+
+        // reset the data line 
+        MEM_WRITE_UCHAR(pDev, SK_SLOT_0,
+                        STDHOST_SW_RESET, STDHOST_SW_RESET_DAT_LINE);
+
+        // wait until data line reset is 0
+        j = 0;
+        do {
+
+            MEM_READ_UCHAR(pDev, SK_SLOT_0, STDHOST_SW_RESET, &ucValue);
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG
+                      "SDHost_ErrorRecovery : DAT-LINE SW_RESET=0x%2.02X\n",
+                      ucValue));
+            UDELAY(2);
+        } while ((ucValue & STDHOST_SW_RESET_DAT_LINE) && j++ < 10000);
+
+    }
+    // clear error irq bits
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS, 0xFFFF);
+
+    // wait for more than 40 us
+    UDELAY(100);
+
+    if (pDev->bus_type == SDIO_SPI_TYPE) {
+        ulDataLineMask = STDHOST_STATE_DAT0_LINE_LVL;
+    } else {
+        if (pDev->bus_width == SDIO_1_BIT) {
+            ulDataLineMask = STDHOST_STATE_DAT0_LINE_LVL;
+        } else {
+            ulDataLineMask =
+                (STDHOST_STATE_DAT0_LINE_LVL | STDHOST_STATE_DAT1_LINE_LVL |
+                 STDHOST_STATE_DAT2_LINE_LVL | STDHOST_STATE_DAT3_LINE_LVL);
+        }
+    }
+    for (j = 0; j < 50; j++) {
+        MEM_READ_ULONG(pDev, SK_SLOT_0, STDHOST_PRESENT_STATE, &ulVal);
+        UDELAY(5);
+        if ((ulVal & ulDataLineMask) == ulDataLineMask) {
+            break;
+        }
+    }
+    DBGPRINT(DBG_W528D,
+             (KERN_DEBUG
+              "SDHost_ErrorRecovery : DAT-LINE=%d %d %d %d CMD-Line=%d\n",
+              ulVal & STDHOST_STATE_DAT3_LINE_LVL ? 1 : 0,
+              ulVal & STDHOST_STATE_DAT2_LINE_LVL ? 1 : 0,
+              ulVal & STDHOST_STATE_DAT1_LINE_LVL ? 1 : 0,
+              ulVal & STDHOST_STATE_DAT0_LINE_LVL ? 1 : 0,
+              ulVal & STDHOST_STATE_CMD_LINE_LVL ? 1 : 0));
+    if (j >= 50) {
+        DBGPRINT(DBG_ERROR,
+                 (KERN_DEBUG
+                  "SDHost_ErrorRecovery : Present state=8x%8.08X : Non-recoverable error (bad datalines 0x%8.08X)!!!!!!!!!!!!!!!!!!!!\n",
+                  ulVal, ulVal & ulDataLineMask));
+    }
+    // clear error irq bits
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_ERROR_IRQ_STATUS, 0xFFFF);
+    // clear normal irq bits
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_NORMAL_IRQ_STATUS,
+                     ~(pDev->currentIRQSignalMask));
+
+    UDELAY(100);
+}
+
+SK_U32
+SDHost_wait_event(PSD_DEVICE_DATA pDev, SDHOST_EVENT * pEvt, SK_U32 to)
+{
+    SK_U32 timeOut = 0;
+    SK_U32 rc = 0;
+
+    DECLARE_WAITQUEUE(sdwait, current);
+
+    if (to == 0) {
+        timeOut = LONG_MAX;
+    } else {
+        timeOut = to;
+    }
+
+//  DBGPRINT(DBG_ALL, (">>> %s: timeout=%d event=%ld\n",__FUNCTION__,timeOut,pEvt->event));
+
+    add_wait_queue(&pEvt->wq, &sdwait);
+    set_current_state(TASK_INTERRUPTIBLE);
+
+    while ((test_bit(0, &pEvt->event) == 0) && timeOut) {
+        timeOut = schedule_timeout(timeOut);
+        if (signal_pending(current)) {
+            rc = 1;
+            DBGPRINT(DBG_ALL, ("%s: Signal pending!\n", __FUNCTION__));
+            break;
+        }
+    }
+
+    if (timeOut <= 0 || (test_bit(0, &pEvt->event) == 0)) {
+        rc = 2;
+        DBGPRINT(DBG_ALL,
+                 ("%s: timeout=%d event=%ld\n", __FUNCTION__, timeOut,
+                  pEvt->event));
+    }
+    set_current_state(TASK_RUNNING);
+    remove_wait_queue(&pEvt->wq, &sdwait);
+
+    // DBGPRINT(DBG_ALL, ("<<< %s: timeout=%d
+    // event=%ld\n",__FUNCTION__,timeOut,pEvt->event));
+
+    return (rc);
+}
+
+SK_BOOL
+SDHost_DumpCIS(PSD_DEVICE_DATA pDev, SK_U8 function_number, SK_U32 length)
+{
+    SK_U8 R;
+    SK_U32 _cis = 0;
+    SK_U32 j;
+    SK_U32 i = 0;
+    SK_U32 len = 0;
+    SK_U32 state = 0;
+
+    if (!SDHost_CMD52_Read(pDev, FN_CIS_POINTER_0_REG(function_number), 0, &R)) {
+        return SK_FALSE;
+    }
+    _cis = R;
+    if (!SDHost_CMD52_Read(pDev, FN_CIS_POINTER_1_REG(function_number), 0, &R)) {
+        return SK_FALSE;
+    }
+    _cis |= (R << 8);
+    if (!SDHost_CMD52_Read(pDev, FN_CIS_POINTER_2_REG(function_number), 0, &R)) {
+        return SK_FALSE;
+    }
+    _cis |= (R << 16);
+
+    // Search for CISTPL
+    printk("SDHost_DumpCIS : FN=%d CIS=%8.08X\n", function_number, _cis);
+    R = 0;
+
+    if (_cis == 0) {
+        return SK_FALSE;
+    }
+
+    j = 0;
+    while (j < length) {
+        SDHost_CMD52_Read(pDev, _cis + j, function_number, &R);
+        j++;
+        switch (state) {
+        case 0:
+            {
+                printk("%2.02X:", R);
+                state++;
+                if (R == 0xFF) {
+                    printk("END\n");
+                    return SK_TRUE;
+                }
+                break;
+            }
+        case 1:
+            {
+                printk("len=%2.02X:", R);
+                len = R;
+                i = 0;
+                state++;
+                break;
+            }
+        case 2:
+            {
+                printk("%2.02X ", R);
+                i++;
+                if (i >= len) {
+                    printk("\n");
+                    state = 0;
+                }
+                break;
+            }
+        }
+    }
+    printk("\n");
+
+    return SK_TRUE;
+}
+
+SK_BOOL
+SDHost_Disable_HighSpeedMode(PSD_DEVICE_DATA pDev)
+{
+    SK_U8 R;
+    SK_U16 usVal;
+    SK_U8 ucHostCtrl = 0;
+
+    // Turn Off Bus Clock
+    SDHost_SetClock(pDev, 0);
+
+    MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, &usVal);
+
+    usVal &= 0x00FF;
+    usVal |= MK_CLOCK((SK_U16) pDev->ClockSpeed);
+
+    MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, usVal);
+    // Turn On Bus Clock
+    SDHost_SetClock(pDev, 1);
+
+    if (SDHost_CMD52_Read(pDev, HIGH_SPEED_REG, 0, &R) && pDev->ClockSpeed != 0) {
+        if (R & EHS) {
+            // Disable high speed mode if requested bus clock is not 50MHz 
+            R &= ~EHS;
+            SDHost_CMD52_Write(pDev, HIGH_SPEED_REG, 0, R);
+        }
+    }
+    MEM_READ_UCHAR(pDev, SK_SLOT_0, STDHOST_HOST_CTRL, &ucHostCtrl);
+
+    if (ucHostCtrl & STDHOST_HIGH_SPEED_ENA) {
+        ucHostCtrl &= ~STDHOST_HIGH_SPEED_ENA;
+        MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_HOST_CTRL, ucHostCtrl);
+    }
+    return SK_TRUE;
+}
+
+SK_BOOL
+SDHost_Enable_HighSpeedMode(PSD_DEVICE_DATA pDev)
+{
+    SK_U8 R;
+    SK_U16 usVal;
+    SK_U8 ucHostCtrl = 0;
+
+    // Read High Speed register of CCCR
+    if (SDHost_CMD52_Read(pDev, HIGH_SPEED_REG, 0, &R) &&
+        (pDev->ClockSpeed == 0)) {
+        if (R & SHS) {
+            /* Make the clock edge to rising */
+            MEM_READ_UCHAR(pDev, SK_SLOT_0, STDHOST_HOST_CTRL, &ucHostCtrl);
+            ucHostCtrl |= STDHOST_HIGH_SPEED_ENA;
+            MEM_WRITE_UCHAR(pDev, SK_SLOT_0, STDHOST_HOST_CTRL, ucHostCtrl);
+
+            DBGPRINT(DBG_W528D, (KERN_DEBUG "High speed mode is supported.\n"));
+
+            // Enable high speed mode if requested bus clock is 50MHz 
+            // and card supports high speed mode
+            R |= EHS;
+            SDHost_CMD52_Write(pDev, HIGH_SPEED_REG, 0, R);
+
+            /* Change the Host controller clock to 50MHZ */
+            // Turn Off Bus Clock
+            SDHost_SetClock(pDev, 0);
+            MEM_READ_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, &usVal);
+            usVal &= 0x00FF;
+            usVal |= MK_CLOCK((SK_U16) pDev->ClockSpeed);
+            MEM_WRITE_USHORT(pDev, SK_SLOT_0, STDHOST_CLOCK_CTRL, usVal);
+            // Turn On Bus Clock
+            SDHost_SetClock(pDev, 1);
+        } else {
+            DBGPRINT(DBG_W528D,
+                     (KERN_DEBUG "High speed mode is not supported.\n"));
+        }
+    }
+    return SK_TRUE;
+}
diff --git a/make_pkg.sh b/make_pkg.sh
new file mode 100755
index 0000000..396102c
--- /dev/null
+++ b/make_pkg.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Builds the .deb package.
+
+# Load common constants.  This should be the first executable line.
+# The path to common.sh should be relative to your script's location.
+COMMON_SH="$(dirname "$0")/../../scripts/common.sh"
+. "$COMMON_SH"
+
+# Make the package
+make_pkg_common "marvell-8787" "$@"
diff --git a/marvell_8787.conf b/marvell_8787.conf
new file mode 100644
index 0000000..f998a7a
--- /dev/null
+++ b/marvell_8787.conf
@@ -0,0 +1 @@
+options sd8787 fw_name=mrvl/sd8787.bin
diff --git a/unpack.sh b/unpack.sh
new file mode 100644
index 0000000..d3f8ea4
--- /dev/null
+++ b/unpack.sh
@@ -0,0 +1,8 @@
+# /bin/sh
+
+# unpack vendor drop into git
+
+for i in SD-BT-8787-*.tgz
+do
+	tar xf $i --strip 1
+done
diff --git a/wlan_src/Makefile b/wlan_src/Makefile
new file mode 100755
index 0000000..f8bbdd1
--- /dev/null
+++ b/wlan_src/Makefile
@@ -0,0 +1,262 @@
+# File: Makefile
+#
+# Copyright (C) 2008-2009, Marvell International Ltd. 
+#
+# This software file (the "File") is distributed by Marvell International 
+# Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+# (the "License").  You may use, redistribute and/or modify this File in 
+# accordance with the terms and conditions of the License, a copy of which 
+# is available by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# A copy of the GPL is available in file gpl-2.0.txt accompanying in this 
+# deliverables.
+#
+# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+# ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+# this warranty disclaimer.
+
+CC=		$(CROSS_COMPILE)gcc
+LD=		$(CROSS_COMPILE)ld
+BACKUP=		/root/backup
+YMD=		`date +%Y%m%d%H%M`
+
+#############################################################################
+# Configuration Options
+#############################################################################
+
+# Debug Option
+# DEBUG LEVEL n/1/2:
+# n: NO DEBUG
+# 1: Only PRINTM(MMSG,...), PRINTM(MFATAL,...), ...
+# 2: All PRINTM()
+CONFIG_DEBUG=1
+
+# Proc debug file
+CONFIG_PROC_DEBUG=y
+
+# Re-association in driver
+CONFIG_REASSOCIATION=y
+
+# Manufacturing firmware support
+CONFIG_MFG_CMD_SUPPORT=y
+
+# Big-endian platform
+CONFIG_BIG_ENDIAN=n
+
+# Enable SDIO multi-port Tx aggregation
+CONFIG_SDIO_MULTI_PORT_TX_AGGR=y
+
+# Enable SDIO multi-port Rx aggregation
+CONFIG_SDIO_MULTI_PORT_RX_AGGR=y
+
+
+#############################################################################
+# Select Platform Tools
+#############################################################################
+
+MODEXT = ko
+#EXTRA_CFLAGS += -I$(PWD)/mlan
+EXTRA_CFLAGS += -I$(M)/mlan
+EXTRA_CFLAGS += -DLINUX
+
+# KERNELDIR point to the installed kernel directory.
+# KERNELDIR can be set on the command line,
+# make KERNELDIR=/usr/src/arm/<arch-bsp-path>
+# Alternatively KERNELDIR can be set in the environment.
+# Default value for KERNELDIR is set below.
+KERNELDIR ?= /usr/src/arm/linux-2.6.25-pxa9xx
+
+# CROSS_COMPILE specify the prefix used for all executables used
+# during compilation. Only gcc and related bin-utils executables
+# CROSS_COMPILE can be set on the command line 
+# make CROSS_COMPILE=</usr/local/arm/4.1.1/bin/>arm-linux-
+# Alternatively CROSS_COMPILE can be set in the environment.
+# Default value for CROSS_COMPILE is set below.
+CROSS_COMPILE ?= /usr/local/arm/4.1.1/bin/arm-linux-
+
+# INSTALLDIR specify the path to install the kernel module after
+# succesful compilation.
+# INSTALLDIR can be set on the command line 
+# make INSTALLDIR=/tftpboot/<rootfs>
+# Alternatively INSTALLDIR can be set in the environment.
+# Default value for INSTALL is set below.
+INSTALLDIR ?= /tftpboot/pxa9xx/root
+
+# ARCH specifies the architecture of the target processor, this kernel
+# module will run.
+# ARCH can be set on the command line
+# make ARCH=<arm/i386>
+# Alternatively ARCH can be set in the environment
+# Default values of ARCH for specific platform are set below.
+ARCH ?= arm
+
+LD += -S
+BINDIR = ../bin_sd8787
+
+#############################################################################
+# Compiler Flags
+#############################################################################
+
+	EXTRA_CFLAGS += -I$(KERNELDIR)/include
+
+	EXTRA_CFLAGS += -DFPNUM='"64"'
+
+ifeq ($(CONFIG_DEBUG),1)
+	EXTRA_CFLAGS += -DDEBUG_LEVEL1
+endif
+
+ifeq ($(CONFIG_DEBUG),2)
+	EXTRA_CFLAGS += -DDEBUG_LEVEL1
+	EXTRA_CFLAGS += -DDEBUG_LEVEL2
+	DBG=	-dbg
+endif
+
+ifeq ($(CONFIG_PROC_DEBUG),y)
+	EXTRA_CFLAGS += -DPROC_DEBUG
+	export CONFIG_PROC_DEBUG
+endif
+
+ifeq ($(CONFIG_REASSOCIATION),y)
+	EXTRA_CFLAGS += -DREASSOCIATION
+endif
+
+ifeq ($(CONFIG_MFG_CMD_SUPPORT),y)
+	EXTRA_CFLAGS += -DMFG_CMD_SUPPORT
+endif
+
+ifeq ($(CONFIG_BIG_ENDIAN),y)
+	EXTRA_CFLAGS += -DBIG_ENDIAN
+endif
+
+ifeq ($(CONFIG_SDIO_MULTI_PORT_TX_AGGR),y)
+	EXTRA_CFLAGS += -DSDIO_MULTI_PORT_TX_AGGR
+endif
+
+ifeq ($(CONFIG_SDIO_MULTI_PORT_RX_AGGR),y)
+	EXTRA_CFLAGS += -DSDIO_MULTI_PORT_RX_AGGR
+endif
+
+
+#############################################################################
+# Make Targets
+#############################################################################
+
+ifneq ($(KERNELRELEASE),)
+
+MOALOBJS =	mlinux/moal_main.o \
+		mlinux/moal_ioctl.o \
+		mlinux/moal_shim.o
+
+MLANOBJS =	mlan/mlan_shim.o mlan/mlan_init.o \
+		mlan/mlan_txrx.o \
+		mlan/mlan_cmdevt.o mlan/mlan_misc.o \
+		mlan/mlan_module.o
+
+MLANOBJS += mlan/mlan_wmm.o
+MLANOBJS += mlan/mlan_sdio.o
+MLANOBJS += mlan/mlan_11n_aggr.o
+MLANOBJS += mlan/mlan_11n_rxreorder.o
+MLANOBJS += mlan/mlan_11n.o
+MLANOBJS += mlan/mlan_11d.o
+MLANOBJS += mlan/mlan_scan.o
+MLANOBJS += mlan/mlan_join.o
+MLANOBJS += mlan/mlan_cfp.o \
+            mlan/mlan_sta_ioctl.o \
+            mlan/mlan_sta_rx.o \
+            mlan/mlan_sta_tx.o \
+            mlan/mlan_sta_event.o \
+            mlan/mlan_sta_cmd.o \
+            mlan/mlan_sta_cmdresp.o
+MOALOBJS += mlinux/moal_priv.o \
+            mlinux/moal_wext.o
+MLANOBJS += mlan/mlan_11h.o
+MLANOBJS += mlan/mlan_meas.o
+
+
+ifdef CONFIG_PROC_FS
+MOALOBJS += mlinux/moal_proc.o
+ifeq ($(CONFIG_PROC_DEBUG),y)
+MOALOBJS += mlinux/moal_debug.o
+endif
+endif
+
+obj-m := mlan.o
+mlan-objs := $(MLANOBJS)
+MOALOBJS += mlinux/moal_sdio_mmc.o
+obj-m += sd8xxx.o
+sd8xxx-objs := $(MOALOBJS)
+
+
+# Otherwise we were called directly from the command line; invoke the kernel build system.
+else
+
+default:
+	$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
+
+endif
+
+###############################################################
+
+export		CC LD EXTRA_CFLAGS KERNELDIR
+
+.PHONY: mapp/mlanconfig mapp/mlan2040coex clean distclean
+	@echo "Finished Making Marvell Wlan Linux Driver"
+
+mapp/mlanconfig:
+	$(MAKE) -C $@
+mapp/mlan2040coex:
+	$(MAKE) -C $@
+
+echo:
+
+build:		echo default
+
+	@if [ ! -d $(BINDIR) ]; then \
+		mkdir $(BINDIR); \
+	fi 
+	cp -f mlan.$(MODEXT) $(BINDIR)/mlan$(DBG).$(MODEXT)
+	cp -f sd8xxx.$(MODEXT) $(BINDIR)/sd8787$(DBG).$(MODEXT)
+
+	cp -f README $(BINDIR)
+	$(MAKE) -C mapp/mlanconfig $@ INSTALLDIR=$(BINDIR)
+	$(MAKE) -C mapp/mlan2040coex $@ INSTALLDIR=$(BINDIR)
+
+clean:
+	-find . -name "*.o" -exec rm {} \;
+	-find . -name "*.ko" -exec rm {} \;
+	-find . -name ".*.cmd" -exec rm {} \;
+	-find . -name "*.mod.c" -exec rm {} \;
+	-find . -name "Module.symvers" -exec rm {} \;
+	-find . -name "Module.markers" -exec rm {} \;
+	-find . -name "modules.order" -exec rm {} \;
+	-rm -rf .tmp_versions
+	$(MAKE) -C mapp/mlanconfig $@
+	$(MAKE) -C mapp/mlan2040coex $@
+
+install: default
+
+	cp -f mlan.$(MODEXT) $(INSTALLDIR)/mlan$(DBG).$(MODEXT)
+	cp -f sd8xxx.$(MODEXT) $(INSTALLDIR)/sd8787$(DBG).$(MODEXT)
+	echo "sd8787 Driver Installed"
+
+distclean:
+	-find . -name "*.o" -exec rm {} \;
+	-find . -name "*.orig" -exec rm {} \;
+	-find . -name "*.swp" -exec rm {} \;
+	-find . -name "*.*~" -exec rm {} \;
+	-find . -name "*~" -exec rm {} \;
+	-find . -name "*.d" -exec rm {} \;
+	-find . -name "*.a" -exec rm {} \;
+	-find . -name "tags" -exec rm {} \;
+	-find . -name ".*" -exec rm -rf 2> /dev/null \;
+	-find . -name "*.ko" -exec rm {} \;
+	-find . -name ".*.cmd" -exec rm {} \;
+	-find . -name "*.mod.c" -exec rm {} \;
+	-rm -rf .tmp_versions
+	$(MAKE) -C mapp/mlanconfig $@
+	$(MAKE) -C mapp/mlan2040coex $@
+
+# End of file
diff --git a/wlan_src/README b/wlan_src/README
new file mode 100755
index 0000000..1c70ffe
--- /dev/null
+++ b/wlan_src/README
@@ -0,0 +1,1600 @@
+===============================================================================
+			U S E R  M A N U A L
+
+ Copyright (C) 2008-2009, Marvell International Ltd. 
+ All Rights Reserved
+
+1) FOR DRIVER BUILD
+
+	Goto source code directory wlan_src/. 
+	make [clean] build	
+	The driver and utility binaries can be found in ../bin_xxxx directory.
+
+2) FOR DRIVER INSTALL
+
+	a) Copy sd8786.bin | sd8787.bin | ... to /lib/firmware/mrvl/ directory, 
+	   create the directory if it doesn't exist. 
+	b) Install WLAN driver,
+		insmod mlan.ko
+		insmod sd8xxx.ko [helper_name=mrvl/helper_sd.bin] [fw_name=mrvl/sd8xxx.bin]
+	c) Uninstall WLAN driver,
+		ifconfig mlanX down
+		rmmod sd8xxx
+		rmmod mlan
+
+	To load driver with MFG firmware file, use mfg_mode=1 when insmod WLAN driver and 
+	specify MFG firmware name if needed.
+
+3) FOR DRIVER PROC & DEBUG
+
+	The following info are provided in /proc/net/mwlan/mlanX/info,
+	on kernel 2.6.24 or later, the entry is /proc/mwlan/mlanX/info.
+
+	driver_name = "wlan"
+	driver_version = <chip id, firmware version and driver version>
+	interface_name = "mlanX"
+	bss_mode = "Ad-hoc" | "Managed" | "Auto" | "Unknown"
+	media_state = "Disconnected" | "Connected"
+	mac_address = <6-byte adapter MAC address>
+	multicase_count = <multicast address count>
+	essid = <current SSID>
+	bssid = <current BSSID>
+	channel = <current channel>
+	region_code = <current region code>
+	multicasr_address[n] = <multicast address>
+	num_tx_bytes = <number of bytes sent to device>
+	num_rx_bytes = <number of bytes received from device and sent to kernel>
+	num_tx_pkts = <number of packets sent to device>
+	num_rx_pkts = <number of packets received from device and sent to kernel>
+	num_tx_pkts_dropped = <number of Tx packets dropped by driver>
+	num_rx_pkts_dropped = <number of Rx packets dropped by driver>
+	num_tx_pkts_err = <number of Tx packets failed to send to device>
+	num_rx_pkts_err = <number of Rx packets failed to receive from device>
+	carrier "on" | "off"
+	tx queue "stopped" | "started"
+
+	The following debug info are provided in /proc/net/mwlan/mlanX/debug,
+	on kernel 2.6.24 or later, the entry is /proc/mwlan/mlanX/debug.
+
+	int_counter = <interrupt count, cleared when interrupt handled>
+	wmm_ac_vo = <number of packets sent to device from WMM AcVo queue>
+	wmm_ac_vi = <number of packets sent to device from WMM AcVi queue>
+	wmm_ac_be = <number of packets sent to device from WMM AcBE queue>
+	wmm_ac_bk = <number of packets sent to device from WMM AcBK queue>
+	max_tx_buf_size = <maximum Tx buffer size>
+	tx_buf_size = <current Tx buffer size>
+	ps_mode = <0/1, CAM mode/PS mode>
+	ps_state = <0/1/2/3, full power state/awake state/pre-sleep state/sleep state>
+	is_deep_sleep = <0/1, not deep sleep state/deep sleep state>
+	wakeup_dev_req = <0/1, wakeup device not required/required>
+	wakeup_tries = <wakeup device count, cleared when device awake>
+	hs_configured = <0/1, host sleep not configured/configured>
+	hs_activated = <0/1, extended host sleep not activated/activated>
+	num_tx_timeout = <number of Tx timeout>
+	num_cmd_timeout = <number of timeout commands>
+	timeout_cmd_id = <command id of the last timeout command>
+	timeout_cmd_act = <command action of the last timeout command>
+	last_cmd_id = <command id of the last several commands sent to device>
+	last_cmd_act = <command action of the last several commands sent to device>
+	last_cmd_index = <0 based last command index>
+	last_cmd_resp_id = <command id of the last several command responses received from device>
+	last_cmd_resp_index = <0 based last command response index>
+	last_event = <event id of the last several events received from device>
+	last_event_index = <0 based last event index>
+	num_cmd_h2c_fail = <number of commands failed to send to device>
+	num_cmd_sleep_cfm_fail = <number of sleep confirm failed to send to device>
+	num_tx_h2c_fail = <number of data packets failed to send to device>
+	num_evt_deauth = <number of deauthenticated events received from device>
+	num_evt_disassoc = <number of disassociated events received from device>
+	num_evt_link_lost = <number of link lost events received from device>
+	num_cmd_deauth = <number of deauthenticate commands sent to device>
+	num_cmd_assoc_ok = <number of associate commands with success return>
+	num_cmd_assoc_fail = <number of associate commands with failure return>
+	cmd_sent = <0/1, send command resources available/sending command to device>
+	data_sent = <0/1, send data resources available/sending data to device>
+	mp_rd_bitmap = <SDIO multi-port read bitmap>
+	mp_wr_bitmap = <SDIO multi-port write bitmap>
+	cmd_resp_received = <0/1, no cmd response to process/response received and yet to process>
+	event_received = <0/1, no event to process/event received and yet to process>
+	ioctl_pending = <number of ioctl pending>
+	tx_pending = <number of Tx packet pending>
+	rx_pending = <number of Rx packet pending>
+	malloc_count = <number of malloc done>
+	lock_count = <number of lock used>
+
+	Use dmesg or cat /var/log/debug to check driver debug messages.
+
+	Update /proc/sys/kernel/printk to change message log levels.
+	For example,
+	echo 6 > /proc/sys/kernel/printk    (messages with a higher priority than 6 
+	                                     will be printed to the console)
+	echo 15 > /proc/sys/kernel/printk   (all messages will be printed to console)
+
+4) FOR IWPRIV COMMAND
+
+NAME
+	This manual describes the usage of private commands used in Marvell MLAN
+	Linux Driver.
+
+	To use parameters as hex format, a '0x' must precede it for the parameters to 
+	be parsed properly. 
+
+SYNOPSIS
+	iwpriv <mlanX> <command> [sub-command] ...
+
+	iwpriv mlanX version
+	iwpriv mlanX verext
+	iwpriv mlanX getsignal [m] [n]
+	iwpriv mlanX antcfg [m]
+	iwpriv mlanX regioncode [n]
+	iwpriv mlanX wwscfg [m]
+	iwpriv mlanX esuppmode
+	iwpriv mlanX passphrase <ssid/psk/passphrase>
+	iwpriv mlanX httxcfg <m>
+	iwpriv mlanX htcapinfo <m>
+	iwpriv mlanX addbapara <m> <n> <o>
+	iwpriv mlanX aggrpriotbl <n>
+	iwpriv mlanX addbareject <n>
+	iwpriv mlanX txbufcfg <n>
+	iwpriv mlanx amsduaggrctrl <n>
+	iwpriv mlanX mpactrl [tx_ena] [rx_ena] [tx_size] [rx_size] [tx_ports] [rx_ports]
+	iwpriv mlanX tideligtbl [N0] [N1] [N2] [N3] [N4] [N5] [N6] [N7]
+	iwpriv mlanX atimwindow [n]
+	iwpriv mlanX deepsleep [n] [m]
+	iwpriv mlanX hscfg [condition [[GPIO# [gap]]]]
+	iwpriv mlanX hssetpara condition [GPIO# [gap]]
+	iwpriv mlanX deauth [n]
+	iwpriv mlanX radioctrl
+	iwpriv mlanX reassoctrl [n]
+	iwpriv mlanX adhocaes
+	iwpriv mlanX bandcfg [l] [m] [n]
+	iwpriv mlanX getlog
+	iwpriv mlanX 11dcfg
+	iwpriv mlanX wmmcfg [n]
+	iwpriv mlanX txpowercfg [<RateIndex> [<MinPwr> [<MaxPwr> <step>]]]
+	iwpriv mlanX qoscfg
+	iwpriv mlanX getdatarate
+	iwpriv mlanX txratecfg [n]
+	iwpriv mlanX bcninterval [n]
+	iwpriv mlanX sysclock [clk1] [clk2] [clk3] [clk4]
+	iwpriv mlanX ldocfg [n]
+	iwpriv mlanX drvdbg [n] [m]
+	iwpriv mlanX warmreset
+	iwpriv mlanX regrdwr <type> <offset> [value]
+	iwpriv mlanX rdeeprom <offset> <length>
+	iwpriv mlanX memrdwr <address> [value]
+	iwpriv mlanX inactivityto <n> <m> <l> [k]
+	iwpriv mlanX bcats <traffic_type> [<timeshare_interval> <bt_time>]
+	iwpriv mlanX sdioclock <n>
+	iwpriv mlanX scancfg [t] [m] [p] [s] [a] [b]
+	iwpriv mlanX vsiecfg <action> <id> [<mask> [data1] ... [dataN]]
+	iwpriv mlanX sleeppd [n]
+	iwpriv mlanX pscfg [k] [d] [l] ...
+	iwpriv mlanX sleepparams [<p1> <p2> <p3> <p4> <p5> <p6>]
+	iwpriv mlanX authtype [n]
+
+DESCRIPTION
+	Those commands are used to send additional commands to the Marvell MLAN
+	card via the Linux device driver.
+
+	The mlanX parameter specifies the network device that is to be used to 
+	perform this command on. It could be mlan0, mlan1 etc.
+
+version	
+	This is used to get the current version of the driver and the firmware.
+
+verext
+	Retrieve and display an extended version string from the firmware
+
+	Usage:
+		iwpriv mlanX verext [#]
+
+	where [#] is an optional argument to retrieve a specific version string,
+	omission of the argument retrieves the 0 indexed string.
+
+getsignal
+	This command gets the last and average value of RSSI, SNR and NF of
+	Beacon and Data.
+	Note: This command is available only when STA is connected.
+
+	where value of m is:
+		1   -- RSSI (Receive Signal Strength Indication)
+		2   -- SNR (Signal to Noise Ratio)
+		3   -- NF (Noise Floor)
+	where value of n is:
+		1   -- Beacon last
+		2   -- Beacon average
+		3   -- Data last
+		4   -- Data average
+
+	Examples:
+		iwpriv mlan0 getsignal 1        : Get the RSSI info (beacon last, beacon
+		                                  average, data last and data average)
+		iwpriv mlan0 getsignal 3 4      : Get the NF of data average
+		iwpriv mlan0 getsignal 2 1      : Get the SNR of beacon last
+		iwpriv mlan0 getsignal          : Get all of the signal info
+		mlan0     getsignal:-32  -33  -35  -36  67  59  63  56  -99  -92  -98  -92
+		RSSI info: beacon last -32, beacon average -33, data last -35, data average -36
+		SNR info: beacon last 67, beacon average 59, data last 63, data average 56
+		NF info: beacon last -99, beacon average -92, data last -98, data average -92
+
+antcfg
+	This command is used to set/get the mode of Tx/Rx antenna. 
+
+	where value of m is:
+		1       -- Tx/Rx antenna 1.
+		2       -- Tx/Rx antenna 2.
+		0xFFFF  -- Tx/Rx antenna diversity.
+
+	Examples:
+		iwpriv mlan0 antcfg             : Get Tx/Rx antenna mode
+		iwpriv mlan0 antcfg 1           : Set Tx/Rx antenna 1
+		iwpriv mlan0 antcfg 0xFFFF      : Set Tx/Rx antenna diversity
+
+regioncode
+	This command is used to set/get the region code in the station.
+	Note: This command should be issued at beginning before band/channel selection
+	and association.
+
+	where value is 'region code' for various regions like
+	USA FCC, Canada IC, Europe ETSI, Japan ...
+	The special code (0xff) is used for Japan to support channel 1-14 in B/G/N mode.
+
+	Examples:
+		iwpriv mlan0 regioncode         : Get region code
+		iwpriv mlan0 regioncode 0x10    : Set region code to USA (0x10)
+
+wwscfg
+	This command is used to set/get the WWS (World Wide Safe) mode.
+
+	where value of m is:
+		0       -- Disable WWS mode (default)
+		1       -- Enable WWS mode
+
+	Examples:
+		iwpriv mlan0 wwscfg             : Get WWS mode
+		iwpriv mlan0 wwscfg 1           : Enable WWS mode
+		iwpriv mlan0 wwscfg 0           : Disable WWS mode
+
+esuppmode
+	This command is used to get the current RSN mode and active pairwise/group 
+    cipher for WPA/WPA2 mode.
+	Note: This command is available only when STA is connected.
+
+	These are bits settings used to indicate each RSN mode.
+		Bit 0    : No RSN
+		Bit 1-2  : RFU
+		Bit 3    : WPA
+		Bit 4    : WPA-NONE
+		Bit 5    : WPA2
+		Bit 6    : AES CCKM
+		Bit 7-15 : RFU
+
+	These are bits settings used to indicate each pairwise and group cipher.
+		Bit 0    : RFU
+		Bit 1    : RFU
+		Bit 2    : TKIP
+		Bit 3    : AES CCKM
+		Bit 2-7  : RFU
+
+	Example:
+		iwpriv mlan0 esuppmode          : Get RSN mode and pairwise/group cipher
+		8 4 4
+		(The current RSN mode is WPA, active pairwise cipher is TKIP and 
+		 active group cipher is TKIP.)
+
+passphrase
+	This command is used to set/get passphrase for WPA-PSK/WPA2-PSK mode.
+	
+	Where <n>		
+		ASCII string for ssid/passphrase/psk.
+	
+	1) "0;<ssid=valid ssid>" - This will get the passphrase, AKMP 
+	   for specified ssid, if none specified then it will get all.
+	            
+	Example:
+		iwpriv mlan0 passphrase "0;ssid=marvell"
+
+	2) "1;<psk=64 byte hexpsk>;<passphrase=1-63 byte passphare>
+	   <ssid=valid ssid>" - Passphrase and psk cannot be provided for the same SSID. 
+	   This command takes only one SSID at a time, If ssid= is present it should contain 
+	   a passphrase or psk. If no arguments are provided then AKMP=802.1x, and passphrase 
+	   should be provided after association.
+	   End of each parameter should be followed by a ';'(except for the last parameter) 
+	   as the delimiter. If ';' or '/' has to be used in an SSID then a '/' should be preceded 
+	   to ';' or '/' as a escape.
+	            
+	Examples:
+		iwpriv mlan0 passphrase "1;ssid=mrvlAP;passphrase=abcdefgd"
+		iwpriv mlan0 passphrase "1;ssid=mrvl AP;psk=<64 bytes hexpsk>"
+
+		If user wants to input the ssid as "mrvl; AP" then command has to be
+		iwpriv mlan0 passphrase "1;ssid=mrvl/; AP;passphrase=abcdefgh"
+
+		If user wants to input the ssid as "//;" then command has to be
+		iwpriv mlan0 passphrase "1;ssid=/////;;passphrase=abcdefgh"
+
+	3) "2;<ssid=valid ssid>" - This will clear the passphrase 
+	   for specified ssid, if none specified then it will clear all.
+	            
+	Examples:
+		iwpriv mlan0 passphrase "2;ssid=marvell"
+		iwpriv mlan0 passphrase "2"     : Clear all profiles and disable embedded supplicant
+
+httxcfg
+	This command is used to configure various 11n specific configration 
+	for transmit (such as Short GI, Channel BW and Green field support)
+
+	where <m>
+	This is a bitmap and should be used as following
+		Bit 15-7: Reserved set to 0
+		Bit 6: Short GI in 40 Mhz enable/disable
+		Bit 5: Short GI in 20 Mhz enable/disable
+		Bit 4: Green field enable/disble
+		Bit 3-2: Reserved set to 0
+		Bit 1: 20/40 Mhz enable disable.
+		Bit 0: Reserved set to 0
+
+	When Bit 1 is set then firmware could transmit in 20Mhz or 40Mhz based
+	on rate adaptation. When this bit is reset then firmware will only
+	transmit in 20Mhz.
+
+	iwpriv mlanX httxcfg 0x62
+	This will enable 20/40 and Short GI but will disable Green field.
+
+	iwpriv mlanX httxcfg 0x30
+	This will enable Short GI and Green field.
+
+	The default value is 0x20
+
+	Note:- If 20/40 MHz support is disabled in htcapinfo, device will not transmit
+	in 40 MHz even 20/40 MHz is enabled in httxcfg.
+
+htcapinfo
+	This command is used to configure some of paramters in HTCapInfo IE 
+	(such as Short GI, Channel BW, and Green field support)
+
+	where <m>
+	This is a bitmap and should be used as following
+		Bit 29: Green field enable/disable
+		Bit 26: Rx STBC Support enable/disable. (As we support
+			single spatial stream only 1 bit is used for Rx STBC)
+		Bit 24: Short GI in 40 Mhz enable/disable
+		Bit 23: Short GI in 20 Mhz enable/disable
+		Bit 17: 20/40 Mhz enable disable.
+		Bit  8: Enable/disable 40Mhz Intolarent bit in ht capinfo.
+		        0 will reset this bit and 1 will set this bit in
+		        htcapinfo attached in assoc request.
+		All others are reserved and should be set to 0.
+
+	Setting of any other bits will return error.
+
+	iwpriv mlanX htcapinfo 0x1820000
+	This will enable Short GI, Channel BW to 20/40 and disable Green field support.
+
+	iwpriv mlanX htcapinfo 0x800000
+	This will enable Short GI, Channel BW to 20 only, No Rx STBC support and disable Green field support.
+
+	The default value is 0x4800000
+
+	Note:- This command can be issued any time but it will only come to effect from
+	next association. (as HTCapInfo is sent only during Association).
+
+addbapara
+	This command can be used to update the default ADDBA parameters.
+
+	where <m> is <timeout>
+	<timeout> - This is the block ack timeout for ADDBA request. 
+		0 : Disable (recommended for throughput test)
+		1 - 65535 : Block Ack Timeout in us
+
+	where <n> is <txwinsize>
+	<txwinsize> - Window size for ADDBA request. (32 is recommended and default value)
+
+	where <o> is <rxwinsize>
+	<rxwinsize> - Window size for ADDBA response. (16 is recommended value for most APs, 64
+			      is recommended for AP85)
+
+	eg:
+	iwpriv mlanX addbapara - This command will get the current addba params
+	iwpriv mlanX addbapara 1000 64 5 (This will change the ADDBA timeout to (1000 * 1024) us,
+			txwinsize to 64 and rxwinsize to 5.
+
+	In case the ADDBA timeout value is updated then a ADDBA is sent for all streams 
+	to update the timeout value.
+
+	In case txwinsize and/or rxwinsize is update the effect could only be seen on
+	next ADDBA request/response. The current streams will not be affected with this
+	change.
+
+aggrpriotbl
+	This command is used set/get the priority table for AMPDU/AMSDU traffic per tid.
+	This command can also be used to disable AMPDU/AMSDU for a given tid.
+	In case of AMPDU this priority table will be used to setup block ack (to make
+	sure the highest priority tid always uses AMPDU as we have limited AMPDU streams)
+
+	where <m0> <n0> <m1> <n1> ... <m7> <n7>
+
+	<mx> - This is priority for Tid0 for AMPDU packet. A priority could be any 
+		   values between 0 - 7, 0xff to disable aggregation.
+	<nx> - This is priority for Tid0 for AMSDU packet. A priority could be any 
+		   values between 0 - 7, 0xff to disable aggregation.
+
+	eg:
+	iwpriv mlanX aggrpriotbl - This command will get the current Priority table for AMPDU and AMSDU.
+						  <2 2 0 0 1 1 3 3 4 4 5 5 255 255 255 255>. This is read as
+						  <"Prio for AMPDU for Tid0" "Prio for AMSDU for Tid0" 
+						   "Prio for AMPDU for Tid1" "Prio for AMSDU for Tid1" and so on
+	iwpriv mlanX aggrpriotbl 2 2 0 0 1 1 3 3 4 4 5 5 255 255 255 255 - 
+						This will set the priority table for AMPDU and AMSDU
+						Priority for Tid0/AMPDU = 2, Tid0/AMSDU = 2, Tid1/AMPDU = 0, Tid1/AMSDU = 0
+						and so on. Aggregation for Tid6 and Tid7 are disabled. 
+						Here higher the priority number, higher the priority (i.e. 7 
+						has higher priority than 6). Similarly for AMSDU.
+	iwpriv mlanX aggrpriotbl 0xff 2 0xff 0 0xff 1 0xff 3 0xff 4 0xff 5 0xff 0xff 0xff 0xff - This will disable
+						AMPDU for all the TIDs but will still keep AMSDU enabled to Tid0 to Tid5
+
+	A delBA should be seen in case a disable happens on a TID for which AMPDU stream 
+	is currently setup. 
+
+	Note:- This command should only be issue in disconnected state.
+
+addbareject
+	This command is used set/get the addbareject table for all the TIDs.
+	This command can also be used to enable rejection of ADDBA requests for a given tid.
+
+	where <m0> <m1> ... <m7>
+
+	<mX> - This can be 0/1 for TidX. 1 enables rejection of ADDBA request for TidX and 
+		   0 would accept any ADDBAs for TidX.
+
+	eg:
+	iwpriv mlanX addbareject - This command will get the current table.
+	    [0 0 0 0 0 0 0 0]. ADDBA would be accepted for all TIDs. This is the default state.
+
+	iwpriv mlanX addbareject 0 0 1 1 0 0 0 0 - This command will accept ADDBA requests for
+		Tid [0,1,4,5,6,7] and reject ADDBA requests for Tid [2,3]
+							
+	iwpriv mlanX addbareject 1 1 1 1 1 1 1 1 - This will enable rejection of ADDBA requests for
+		all Tids.
+
+	Note:- This command should only be issue in disconnected state.
+
+txbufcfg
+	This command can be used to set max transmit buffer size of firmware. Increasing this
+	buffer size is recommended for AMSDU packets. (Default is 2048)
+
+	where <n> is <buffer size in byte>
+
+	<buffer size> - This can be 2048/4096/8192.
+
+	eg:
+	iwpriv mlanX txbufcfg 	  - This will display the current buffer size.
+	iwpriv mlanX txbufcfg 8192 - This will change the tx buffer size of 8192.
+
+	For AMSDU for work for multiple packets we may need the max tx buffer size to be
+	4096/8192.
+
+	Note:- This command should be issue in disconnected state.
+           Otherwise, new setting will be effected in next time associate. 
+           The actual tx buf size will depends on AP's capability and max transmit buffer size. 
+
+amsduaggrctrl
+	This command could be used to enable/disable a feature where firmware gives feedback to driver
+	regarding the optimal AMSDU buffer size to use with the current rate. Firmware will use the 
+	current rate to decide the buffer size we could transmit. The max buffer size will still be 
+	limited by buffer size provided in txbufcfg. (i.e. if the txbufcfg is 4K, then we could only transmit
+	4K/2K AMSDU packets, if the txbufcfg is 8K then we could transmit 8k/4k/2k based on current rate)
+
+	If enabled AMSDU buffer size at various rates will be as follows
+
+	1.	Legacy B/G rate.
+		No AMSDU aggregation.
+
+	2.	BW20 HT Rate:
+		When TX rate goes down, 
+		MCS 7, 6, 5, 4:
+			a	8K aggregation size (if TX buffer size is 8K)
+			b	4K aggregation size (if TX buffer size is 4K)
+			c	2K aggregation size (if TX buffer size is 2K)
+
+		MCS 3, 2:
+			a	4K aggregation size (if TX buffer size is 8K/4K)
+			b	2K aggregation size (if TX buffer size is 2K)
+
+		MCS 1, 0:
+			a	No aggregation
+
+		When TX rate goes up, 
+		MCS 7, 6, 5:
+			a	8K aggregation size (if TX buffer size is 8K)
+			b	4K aggregation size (if TX buffer size is 4K)
+			c	2K aggregation size (if TX buffer size is 2K)
+
+		MCS 4, 3:
+			a	4K aggregation size (if TX buffer size is 8K/4K)
+			b	2K aggregation size (if TX buffer size is 2K)
+
+		MCS 2, 1, 0:
+			a	No aggregation
+
+	3.	BW40 HT Rate:
+		When TX rate goes down, 
+		MCS 7, 6, 5, 4, 3, 2, 1:
+			a	8K aggregation size (if TX buffer size is 8K)
+			b	4K aggregation size (if TX buffer size is 4K)
+			c	2K aggregation size (if TX buffer size is 2K)
+
+		MCS 0:
+			a	No aggregation
+
+		When TX rate goes up, 
+		MCS 7, 6, 5, 4, 3:
+			a	8K aggregation size (if TX buffer size is 8K)
+			b	4K aggregation size (if TX buffer size is 4K)
+			c	2K aggregation size (if TX buffer size is 2K)
+
+		MCS 2, 1, 0:
+			a	No aggregation
+
+	where <n> is 0/1 (for disable/enable)
+
+	eg:
+	iwpriv mlanx amsduaggrctrl 1 - Enable this feature
+	iwpriv mlanx amsduaggrctrl 0 - Disable this feature
+	iwpriv mlanx amsduaggrctrl (This will get the enable/disable flag
+	and the current AMSDU buffer size). The AMSDU buffer size returned is only
+	valid after association as before association there is no rate info.
+
+	Note:- This command to enable/disable could be given anytime (before/after
+			association). This feature is enabled by default by the driver during
+			initialization.
+
+mpactrl
+	This command is used to set/get the Tx, Rx SDIO aggregation parameters
+	Note: The parameters can be set only in disconnected state.
+
+	Examples:
+		iwpriv mlan0 mpactrl       : Get MP aggregation parameters
+		iwpriv mlan0 mpactrl 1 1 2048 2048 5 7
+		                           : Enable MP aggregation for Tx, Rx
+		                           : Set Tx, Rx buffer size to 2048 bytes.
+		                           : Set maximum Tx ports to 5 and maximum Rx ports to 7.
+	default values are 0 0 4096 4096 8 8
+
+tideligtbl
+	This command is used to set/get number of available ports for transfer 
+	eligibility for TIDs (TID0-TID7).
+
+	Usage:
+		iwpriv mlanX tideligtbl [N0] [N1] [N2] [N3] [N4] [N5] [N6] [N7]
+
+	The Nx (x=0-7) is for TIDx. For each TIDx, there must be at least Nx 
+	number of available ports to transfer the corresponding packet.
+	The Nx could be 1-15, 0 or no input for unchanged.
+
+	Examples:
+		iwpriv mlan0 tideligtbl         : Get the TID eligibility table
+		iwpriv mlan0 tideligtbl 6 6 5 4 3 2 1 1
+		                                : Set the TID eligibility table
+		iwpriv mlan0 tideligtbl 4 0 2   : Set TID table TID0 and TID2,
+		                                  keep the others unchanged
+
+atimwindow
+	This command is used to set/get the ATIM window value in the station.
+	The range of ATIM window is 0 - 50.
+	Note: This command should be issued before ad-hoc start/join and ad-hoc 
+	power save on.
+
+	Examples:
+		iwpriv mlan0 atimwindow 20      : Set atimwindow to 20
+		iwpriv mlan0 atimwindow         : Get atimwindow
+
+deepsleep
+	This command is used to set/get auto deep sleep mode.
+
+	Usage:
+		iwpriv mlanX deepsleep [n] [m]
+
+	where the parameters are:
+		[n]: Enable/disable auto deep sleep mode (1/0)
+		[m]: Idle time in milliseconds after which firmware will put the device 
+		     in deep sleep mode. Default value is 100 ms.
+
+	Examples:
+		iwpriv mlan0 deepsleep          : Display auto deep sleep mode
+		iwpriv mlan0 deepsleep 1        : Enable auto deep sleep mode, idle time unchanged
+		iwpriv mlan0 deepsleep 0        : Disable auto deep sleep mode
+		iwpriv mlan0 deepsleep 1 500    : Enable auto deep sleep mode with idle time 500 ms
+
+hscfg
+	This command is used to configure the host sleep parameters.
+
+	Usage:
+		iwpriv mlanX hscfg [condition [[GPIO# [gap]]]]
+
+	This command takes one (condition), two (condition and GPIO#) or three 
+	(condition, GPIO# and gap) parameters for set. If no paramter provided, 
+	get is performed.
+
+	where Condition is:
+		bit 0 = 1   -- broadcast data
+		bit 1 = 1   -- unicast data
+		bit 2 = 1   -- mac event
+		bit 3 = 1   -- multicast packet
+
+	where GPIO is the pin number of GPIO used to wakeup the host. It could be 
+	any valid GPIO pin# (e.g. 0-7) or 0xff (interface, e.g. SDIO will be used 
+	instead).
+
+	where Gap is the gap in milliseconds between wakeup signal and wakeup event
+	or 0xff for special setting.
+
+	The host sleep mode will be cancelled if condition is set to -1.
+
+	Examples:
+		iwpriv mlan0 hscfg              : Get current host sleep mode
+		iwpriv mlan0 hscfg -1           : Cancel host sleep mode
+		iwpriv mlan0 hscfg 3            : Broadcast and unicast data
+		                                  Use GPIO and gap set previously
+		iwpriv mlan0 hscfg 2 3          : Unicast data
+		                                  Use GPIO 3 and gap set previously
+		iwpriv mlan0 hscfg 2 1 0xa0     : Unicast data
+		                                  Use GPIO 1 and gap 160 ms
+		iwpriv mlan0 hscfg 2 0xff       : Unicast data
+		                                  Use interface (e.g. SDIO)
+		                                  Use gap set previously
+		iwpriv mlan0 hscfg 4 3 0xff     : MAC event
+		                                  Use GPIO 3
+		                                  Special host sleep mode
+		iwpriv mlan0 hscfg 1 0xff 0xff  : Broadcast data
+		                                  Use interface (e.g. SDIO)
+		                                  Special host sleep mode
+
+hssetpara
+	This command is used to set host sleep parameters.
+
+	Usage:
+		iwpriv mlanX hssetpara Condition [GPIO# [gap]]
+
+	Note:
+	1) The usages of parameters are the same as "hscfg" command.
+	2) The parameters will be saved in the driver and be used when host suspends.
+
+deauth
+	This command is used to send a de-authentication to an arbitrary AP.
+	If [n] is omitted, the driver will deauth the associated AP.
+	If in ad-hoc mode this command is used to stop beacon transmission 
+	from the station and go into idle state.
+
+	When <n> is supplied as a MAC address, the driver will deauth the 
+	  specified AP.  If the AP address matches the driver's associated AP,
+	  the driver will disconnect. Otherwise, the driver remains connected.
+
+radioctrl
+	This command is used to turn on/off the radio.
+	Note: The radio can be disabled only in disconnected state.
+
+	where value of n is:
+		0   -- Disable
+		1   -- Enable
+
+	Examples:
+		iwpriv mlan0 radioctrl 1        : Turn the radio on
+		iwpriv mlan0 radioctrl          : Get radio status
+
+reassoctrl
+	This command is used to turn on/off re-association in driver.
+
+	Usage:
+		iwpriv mlanX reassoctrl [n]
+
+	Where value of n is:
+		0   -- Disable
+		1   -- Enable
+
+	Examples:
+		iwpriv mlan0 reassoctrl         : Get re-association status
+		iwpriv mlan0 reassoctrl 1       : Turn re-association on
+
+adhocaes
+	This command is used to set/get the AES key, when the station is in ad-hoc mode.
+	Note: This command is only available in disconnected state.
+
+	where value can be any 16 byte value.
+
+	Examples:
+		iwpriv mlan0 adhocaes           : Get ad-hoc aes key
+		iwpriv mlan0 adhocaes "1;12345678901234567890123456789012" 
+		                                : Set ad-hoc aes key
+		iwpriv mlan0 adhocaes 2         : Clear ad-hoc aes key
+
+bandcfg
+	This command is used to set/get infra/ad-hoc band.
+	Note: This command is only available in disconnected state.
+
+	Usage:
+		iwpriv mlanX bandcfg [l] [m] [n]
+
+	where the parameters:
+		[l]: Infrastructure band
+		     bit 0: B
+		     bit 1: G
+		     bit 2: A
+		     bit 3: GN
+		     bit 4: AN
+
+		[m]: Ad-hoc start band
+		     bit 0: B
+		     bit 1: G
+		     bit 2: A
+		     bit 3: GN
+		     bit 4: AN
+		[n]: Ad-hoc start channel 
+
+	Examples:
+		iwpriv mlan0 bandcfg            : Get infra/ad-hoc band and ad-hoc
+		                                  start channel configurations
+		iwpriv mlan0 bandcfg 1          : Set infra band to B only
+		iwpriv mlan0 bandcfg 3 2 6      : Set infra band to B/G, ad-hoc start band
+		                                  to G and ad-hoc start channel to 6
+
+getlog
+	This command is used to get the statistics available in the station.
+
+11dcfg
+	This command is used to control 11D. No argument is used to get.
+
+	where value of n is:
+		0   -- Disable
+		1   -- Enable
+
+	Examples:
+		iwpriv mlan0 11dcfg 1           : Enable 11D
+		iwpriv mlan0 11dcfg             : Get 11D status
+
+wmmcfg
+	This command is used to control WMM. No argument is used to get.
+
+	where value of n is:
+		0   -- Disable
+		1   -- Enable
+
+	Examples:
+		iwpriv mlan0 wmmcfg 1           : Enable WMM
+		iwpriv mlan0 wmmcfg             : Get WMM status
+
+txpowercfg
+	This command is used to get/set the Tx power configuration.
+
+	Where 
+		<RateIndex> - Data rate index
+			0	1 Mbps
+			1	2 Mbps
+			2	5.5 Mbps
+			3	11 Mbps
+			4	6 Mbps
+			5	9 Mbps
+			6	12 Mbps
+			7	18 Mbps
+			8	24 Mbps
+			9	36 Mbps
+			10	48 Mbps
+			11	54 Mbps
+			12	MCS0 (BW20)
+			13	MCS1 (BW20)
+			14	MCS2 (BW20)
+			15	MCS3 (BW20)
+			16	MCS4 (BW20)
+			17	MCS5 (BW20)
+			18	MCS6 (BW20)
+			19	MCS7 (BW20)
+			140	MCS0 (BW40)
+			141	MCS1 (BW40)
+			142	MCS2 (BW40)
+			143	MCS3 (BW40)
+			144	MCS4 (BW40)
+			145	MCS5 (BW40)
+			146	MCS6 (BW40)
+			147	MCS7 (BW40)
+			0xff	Default
+		<MinPwr> - Minimum power level in dBm
+		<MaxPwr> - Maximum power level in dBm
+		<step>   - Power step
+
+	Note: Firmware may adjust the setting if over limit, use get command to
+	      check the current setting.
+
+	Examples:
+		iwpriv mlan0 txpowercfg 0xff        : Default power configuration
+		iwpriv mlan0 txpowercfg 11 12       : Set power level 12 dBm to data rate 54 Mbps
+		iwpriv mlan0 txpowercfg 7 11 16 1   : Set power level 11 dBm to 16 dBm with
+		                                      step 1 to data rate 18 Mbps
+		iwpriv mlan0 txpowercfg             : Get current configuration
+		mlan0     txpowercfg:2  3  13  18  2  1  1  13  18  2  0  0  13  18  2  
+		10  11  13  15  2  8  9  13  16  2  6  7  13  17  2  4  5  13  17  2  
+		17  19  13  15  2  15  16  13  16  2  13  14  13  17  2  12  12  13  17  2  
+		145  147  13  14  1  143  144  13  14  1  141  142  13  14  1  140  140  13  14  1 
+
+		 2 -> First rate index is 5.5 Mbps.
+		 3 -> Last rate index is 11 Mbps.
+		13 -> Min Tx power value is 13 dBm.
+		18 -> Max Tx power value is 18 dBm.
+		 2 -> Power adjustment step value is 2.
+
+		Similarly
+		17 -> First rate index is MCS5 (BW20).
+		19 -> Last rate index is MCS7 (BW20).
+		13 -> Min Tx power value is 13 dBm.
+		15 -> Max Tx power value is 15 dBm.
+		 2 -> Power adjustment step value is 2.
+
+		so on...
+
+qoscfg
+	This command sets WMM IE QOS info when an argument is given, and gets current WMM
+	IE QOS info when no argument is given.
+
+	Examples:
+		iwpriv mlan0 qoscfg 0x0f        : Set WMM IE QOS info to 0x0f
+		iwpriv mlan0 qoscfg             : Get WMM IE QOS info
+
+getdatarate
+	This command is used to get the data rate (index) being used in last Tx 
+	packet and last Rx packet.
+
+txratecfg
+	This command is used to set/get the transmit data rate.
+	
+	Note: 
+	1) The data rate can be set only after association. 
+	
+	2) If the reassoc is OFF driver reset the data rate to auto if the connection state is disconnected.
+	Please note that user has to re-issue the set data rate command if the driver is disconnected.
+	
+	3) If the reassoc is ON driver remembers the data rate set by the user, if the driver is 
+	disconnected user does not have to re-issue the set data rate again.
+	
+	Where <n>
+		 data rate
+				Data rate
+			0	1 Mbps
+			1	2 Mbps
+			2	5.5 Mbps
+			3	11 Mbps
+			4	6 Mbps
+			5	9 Mbps
+			6	12 Mbps
+			7	18 Mbps
+			8	24 Mbps
+			9	36 Mbps
+			10	48 Mbps
+			11	54 Mbps
+			12	MCS0
+			13	MCS1
+			14	MCS2
+			15	MCS3
+			16	MCS4
+			17	MCS5
+			18	MCS6
+			19	MCS7
+			44	MCS32
+			0xff	Auto
+
+	Examples:
+		iwpriv mlan0 txratecfg 3        : Set fixed Tx rate to 11 Mbps
+		iwpriv mlan0 txratecfg 11       : Set fixed Tx rate to 54 Mbps	
+		iwpriv mlan0 txratecfg 15       : Set fixed Tx rate to MCS3	
+		iwpriv mlan0 txratecfg 0xff     : Disable fixed rate and uses auto rate
+		iwpriv mlan0 txratecfg          : Read the current data rate setting
+
+bcninterval
+	This command is used to set/get the beacon interval in ad-hoc mode.
+	The valid beacon interval is between 20 - 1000, default beacon
+	interval is 100.
+
+	Where <n>
+		Beacon interval in TU (Time Unit: 1024 us).
+
+	Examples:
+		iwpriv mlan0 bcninterval 200    : Set ad-hoc beacon interval to 200
+		iwpriv mlan0 bcninterval        : Get ad-hoc beacon interval
+
+sysclock
+	This command is used to set/get system clocks in MHz.
+	The current system clock, configurable system clocks and all of the 
+	supported system clocks will be returned if no parameter provided.
+
+	Examples:
+		iwpriv mlan0 sysclock           : Get system clocks
+		80 80 128 128 128 5 11 16 20 22 32 40 44 64 80 106 128 160
+		(The current system clock is 80 MHz.
+		 The configurable system clocks of non-security, security, non-security 
+		 A-MPDU and security A-MPDU are 80 MHz, 128 MHz, 128 MHz and 128 MHz.
+		 The supported system clocks are 5 MHz, 11 MHz, ..., 160 MHz.)
+
+		iwpriv mlanX sysclock 80        : Set system clock in non-security mode
+		                                  to 80 MHz, no change for others
+		iwpriv mlanX sysclock 0 0 128   : Set system clock in non-security A-MPDU 
+		                                  mode to 128 MHz, no changes for others
+
+ldocfg
+	This command is used to set/get internal/external core power voltage source.
+	By default firmware uses internal LDO for 1.2V core power supply.
+	The current setting will be returned if no parameter provided.
+
+	Usage:
+		iwpriv mlanX ldocfg [n]
+
+	where the parameter is,
+		0       -- internal
+		1       -- external
+
+drvdbg
+	This command is used to set/get the bit masks of driver debug message control.
+
+	Usage:
+		iwpriv mlanX drvdbg [n] [m]
+
+	Where the parameter <n> is the generic debug message control bit mask.
+	The following types of driver debug messages can be dynamically enabled or 
+	disabled by setting or clearing the corresponding bits, 
+		bit 0:  MMSG  		PRINTM(MMSG,...)
+		bit 1:  MFATAL		PRINTM(MFATAL,...)
+		bit 2:  MERROR		PRINTM(MERROR,...)
+		bit 3:  MDATA 		PRINTM(MDATA,...)
+		bit 4:  MCMND 		PRINTM(MCMND,...)
+		bit 5:  MEVENT		PRINTM(MEVENT,...)
+		bit 6:  MINTR 		PRINTM(MINTR,...)
+		...
+		bit 16: MDAT_D		PRINTM(MDAT_D,...), DBG_HEXDUMP(MDAT_D,...)
+		bit 17: MCMD_D		PRINTM(MCMD_D,...), DBG_HEXDUMP(MCMD_D,...)
+		bit 18: MFW_D		PRINTM(MFW_D,...)
+		...
+		bit 28: MENTRY		PRINTM(MENTRY,...), ENTER(), LEAVE()
+		bit 29: MWARN 		PRINTM(MWARN,...)
+		bit 30: MINFO 		PRINTM(MINFO,...)
+
+	Where the parameter <m> is the extended interface module debug message control 
+	bit mask. The following types of debug messages can be controlled.
+
+		bit 0:  MIF_D 		PRINTM(MIF_D,...),  DBG_HEXDUMP(MIF_D,...)
+
+	If CONFIG_DEBUG=2, all kinds of debug messages can be configured. 
+	By default all debug messages are enabled except for MEVENT and MIF_D.
+
+	If CONFIG_DEBUG=1, all kinds of debug messages can be configured except 
+	for MENTRY, MWARN and MINFO. By default MMSG, MFATAL and MERROR are enabled.
+
+	Some special debug messages,
+		'*'		// MLAN driver ISR is called (bit 6 MINTR enabled)
+		'|'		// PS awake event is received (bit 5 MEVENT enabled)
+		'_'		// PS sleep event is received (bit 5 MEVENT enabled)
+		'+'		// PS sleep confirm is sent (bit 5 MEVENT enabled)
+
+	Examples:
+		iwpriv mlan0 drvdbg             : Get the current driver debug masks
+		iwpriv mlan0 drvdbg 0 0         : Disable all the debug messages
+		iwpriv mlan0 drvdbg 7           : Enable MMSG, MFATAL and MERROR messages,
+		                                  no change for if debug control
+		iwpriv mlan0 drvdbg 3 1         : Enable MMSG and MFATAL messages,
+		                                  enable MIF_D message
+		iwpriv mlan0 drvdbg -1 -1       : Enable all the debug messages
+
+warmreset
+	This command is used for warm reset of the interface.
+
+	Usage:
+		iwpriv mlanX warmreset
+
+regrdwr
+	This command is used to read/write the adapter register.
+	
+	Usage:
+		iwpriv mlanX regrdwr <type> <offset> [value]
+
+	where the parameters are,
+		<type>:     1:MAC/SOC, 2:BBP, 3:RF, 4:PMIC, 5:CAU
+		<offset>:   offset of register
+		[value]:    value to be written
+	Note: If highest bit of a 32-bit value needs to be set, use negitive input.
+
+	Examples:
+		iwpriv mlan0 regrdwr 1 0xa060       : Read the MAC register
+		iwpriv mlan0 regrdwr 1 0xa060 0x12  : Write the MAC register
+		iwpriv mlan0 regrdwr 1 0xa794 -0x80000000
+		                                    : Write 0x80000000 to MAC register
+		iwpriv mlan0 regrdwr 1 0xa794 -0x00000001
+		                                    : Write 0xffffffff to MAC register
+
+rdeeprom
+	This command is used to read the EEPROM contents of the card.
+
+	Usage:
+		iwpriv mlanX rdeeprom <offset> <length>
+
+	where the parameters are,
+		<offset>:   multiples of 4
+		<length>:   4-20, multiples of 4
+
+	Example:
+		iwpriv mlan0 rdeeprom 0 20      : Read 20 bytes of EEPROM data from offset 0
+
+memrdwr
+	This command is used to read/write the adapter memory.
+	
+	Usage:
+		iwpriv mlanX memrdwr <address> [value]
+
+	where the parameters are,
+		<address>:  memory address
+		[value]:    value to be written
+	Note: If highest bit of a 32-bit value needs to be set, use negitive input.
+
+	Examples:
+		iwpriv mlan0 memrdwr -0x80000000
+		                                : Read memory address 0x80000000
+		iwpriv mlan0 memrdwr -0x80000000 -0x00000001
+		                                : Write 0xffffffff to memory address 0x80000000
+
+inactivityto
+	This command is used to set/get the inactivity timeout value, which specifies 
+	when WLAN device is put to sleep.
+
+	Usage:
+		iwpriv mlanX inactivityto <n> <m> <l> [k]
+
+	where the parameter are:
+		<n>: timeout unit in microseconds.
+		<m>: Inactivity timeout for unicast data.
+		<l>: Inactivity timeout for multicast data.
+		[k]: Inactivity timeout for new Rx traffic after PS notification to AP.
+
+	Examples:
+		iwpriv mlan0 inactivityto           : Get the timeout value
+		iwpriv mlan0 inactivityto 1000 2 3  : Set timeout unit to 1000 us (1 ms), 
+		                                      inactivity timeout for unicast data is 2 ms,
+		                                      inactivity timeout for multicast data is 3 ms
+
+bcats
+	This command is used to set/get the BCA timeshare parameters.
+	This command only works after BCA has been enabled. 
+
+	Usage:
+		iwpriv mlanX bcats <traffic_type> [<timeshare_interval> <bt_time>]
+
+	where:
+		<traffic_type>: 0 - Wlan and bluetooth are low priority.
+		                1 - Wlan and bluetooth are high priority.
+		                2 - Wlan and bluetooth are medium priority.
+		                3 - Wlan and bluetooth are medium high priority.
+		                0xffff - Reset fairshare.
+ 	
+		If <timeshare_interval> value is not multiple of 10 then floor value 
+		is taken and the valid range is <20 ... 60,000> in milliseconds.
+
+		If <bt_time> value is not multiple of 10 then floor value is taken 
+		and the valid range is <0 ... timeshare_interval value> in milliseconds.
+
+	Examples:
+		iwpriv mlan0 bcats 1            : Get the BCA timeshare settings when wlan
+		                                  and bluetooth are set to high priority
+		iwpriv mlan0 bcats 0xffff       : Reset fairshare, disable all modes above 
+		                                  that are running, and restore arbitration 
+		                                  table register values to before the user 
+		                                  enabled any of the above fairshare modes.   
+		iwpriv mlan0 bcats 1 30 20      : Set wlan and bluetooth to high priority, 
+		                                  wlan timeshare_interval to 30 ms and
+		                                  bt_time to 20 ms
+
+sdioclock
+	Turn On(1) or Off(0) the SDIO clock.
+
+	Usage:
+		iwpriv mlanX sdioclock 1 (on)
+		iwpriv mlanX sdioclock 0 (off)
+		iwpriv mlanX sdioclock (get the current clock state)
+
+scancfg
+	This command is used to set/get scan configuration parameters.
+                
+	Usage:
+		iwpriv mlanX scancfg [t] [m] [p] [s] [a] [b]
+                
+	where the parameters:
+		[t]: Scan Type (0: Unchanged, 1: Active, 2: Passive)
+		[m]: Scan Mode (0: Unchanged, 1: BSS, 2: IBSS, 3: Any)
+		[p]: Scan Probes (0: Unchanged, 1-10: Number of probes per channel)
+		[s]: Specific Scan Time (0: Unchanged, n: Value in ms, default 110 ms, max 500 ms)
+		[a]: Active Scan Time (0: Unchanged, n: Value in ms, default 200 ms, max 500 ms)
+		[b]: Passive Scan Time (0: Unchanged, n: Value in ms, default 200 ms, max 2000 ms)
+	No change if the parameter is 0 or the parameter is not provided.
+
+	Examples:
+		iwpriv mlan0 scancfg            : Get all the current scan configuration settings
+		iwpriv mlan0 scancfg 1 3        : Set scan type to active and scan mode to any,
+		                                  all the other scan configurations are unchanged
+		iwpriv mlan0 scancfg 0 1 2 200  : Set scan mode to BSS, number of probes to 2 and 
+		                                  specific scan time to 200 ms, all the other scan 
+		                                  configurations are unchanged
+
+vsiecfg
+	This command is used to get/add/remove vendor specific IE.
+
+	Usage:
+		iwpriv mlanX vsiecfg <action> <id> [<mask> [data1] ... [dataN]]
+
+	where:
+		<action>:   0/1/2:  Get/Add/Remove
+		<id>:       0-7:    IE index in the driver IE array
+		[mask]:     Bit 0:  IE for scan
+		            Bit 1:  IE for associate
+		            Bit 2:  IE for ad-hoc
+		[data1]...[dataN]:  IE data
+
+	Note: The max data length is 254-byte, IE ID (221) and length is not included.
+	      The max total length of vendor specific IEs for scan/assoc/ad-hoc is 512-byte.
+
+	Examples:
+		iwpriv mlan0 vsiecfg 0 2        : Get the 3rd IE
+		iwpriv mlan0 vsiecfg 1 0 4 0x12 0x34
+		                                : Add IE in 1st position for ad-hoc
+		iwpriv mlan0 vsiecfg 1 6 3 0x00 0x50 0x43 0x20 0xFF 0xFE
+		                                : Add IE in 7th position for scan and associate
+		iwpriv mlan0 vsiecfg 2 1        : Remove the 2nd IE
+
+sleeppd
+	This command is used to configure the sleep period of the WLAN device.
+
+	Usage:
+		iwpriv mlanX sleeppd [<period>]
+
+	Where the parameter is:
+		period: sleep period in milliseconds. Range 10~60. 0 for disable.
+
+	Examples:
+		iwpriv mlan0 sleeppd            : Get sleep period configuration
+		iwpriv mlan0 sleeppd 10         : Set sleep period to 10 ms
+
+pscfg
+	This command is used to set/get PS configuration parameters.
+
+	Usage:
+		iwpriv mlanX pscfg [k] [d] [l] ...
+
+	Where the parameters:
+		[k]: Keep alive null packet interval (0: Unchanged, -1: Disable, n: Interval in seconds)
+		[d]: DTIM interval (0: Unchanged, 1-5: Value, 65534: DTIM will be ignored 
+		                    in firmware, listen interval will be used)
+		[l]: Local listen interval (0: Unchanged, n: Interval)
+		[a]: Ad-hoc awake period (0: Unchanged, 1-31: Beacon interval, 255: Firmware 
+		                          will go to sleep after beacon send out)
+		[b]: Beacon miss timeout (0: Unchanged, 1-50: Value in milliseconds, 65535: Disable)
+		[p]: Delay to PS (0-65535: Value in milliseconds)
+		[m]: PS mode (0: Unchanged, 1: Auto mode, 2: PS-Poll mode, 3: PS Null mode)
+	No change if parameters are not provided.
+
+	Examples:
+		iwpriv mlan0 pscfg              : Get all the current PS configuration settings
+		iwpriv mlan0 pscfg 3 4          : Set PS keep alive null packet interval to 3 seconds 
+		                                  and DTIM interval to 4, all the other configurations 
+		                                  are unchanged
+		iwpriv mlan0 pscfg 0 0xfffe 10 0 20 
+		                                : Disable DTIM interval, set local listen interval to 
+		                                  10 beacon intervals and beacon miss interval to 20, 
+		                                  all the other configurations are unchanged
+		iwpriv mlan0 pscfg 0 0 0 0 0 50 : Set delay to PS to 50 ms, keep the others unchanged
+
+sleepparams
+	This command is used to set the sleepclock configurations
+
+	Usage:
+		iwpriv mlanX sleepparams [<p1> <p2> <p3> <p4> <p5> <p6>]
+
+	where:
+		p1 is Sleep clock error in ppm (0-65535)
+		p2 is Wakeup offset in usec (0-65535)
+		p3 is Clock stabilization time in usec (0-65535)
+		p4 is Control periodic calibration (0-2)
+		p5 is Control the use of external sleep clock (0-2)
+		p6 is reserved for debug (0-65535)
+
+	Examples:
+		iwpriv mlan0 sleepparams                      : Get current sleepclock configuration
+		iwpriv mlan0 sleepparams 10 1000 2000 1 0 128 : Set sleepclock configuration
+
+authtype 
+	This command is used to set/get authentication type. 
+
+	Usage:
+		iwpriv mlanX authtype [n]
+
+	where <n>
+		0: 802.11 open system authentication.
+		1: 802.11 shared key authentication.
+		255: allow open system or shared key authentication.
+
+	Examples:
+		iwpriv mlan0 authtype 0         : use open system authentication
+		iwpriv mlan0 authtype 1         : use shared key authentication
+		iwpriv mlan0 authtype 255       : allow open system or shared key authentication
+		iwpriv mlan0 authtype           : get current setting
+
+
+===============================================================================
+		U S E R  M A N U A L  F O R  M L A N C O N F I G 
+
+NAME
+mlanconfig - configure the additional parameters available for the Marvell mdriver.
+
+SYNOPSIS
+mlanconfig -v
+mlanconfig <mlanX> <command> [parameters] ...
+
+mlanconfig mlanX hostcmd <bg_scan.conf> bgscfg
+mlanconfig mlanX hostcmd <requesttpc.conf> requesttpc
+mlanconfig mlanX hostcmd <crypto_test.conf> crypto_test
+mlanconfig mlanX hostcmd <subevent.conf> subevent_get
+mlanconfig mlanX hostcmd <subevent.conf> subevent_set
+mlanconfig mlanX hostcmd <auto_tx.conf> auto_tx_get
+mlanconfig mlanX hostcmd <auto_tx.conf> nat_keep_alive
+mlanconfig mlanX hostcmd <auto_tx.conf> auto_tx_unreg
+mlanconfig mlanX hostcmd <txrate_cfg.conf> txrate_cfg_get
+mlanconfig mlanX hostcmd <txrate_cfg.conf> txrate_cfg_set_bg
+mlanconfig mlanX hostcmd <txrate_cfg.conf> txrate_cfg_set_bgn
+mlanconfig mlanX hostcmd <txpwrlimit_cfg.conf> txpwrlimit_cfg_get
+mlanconfig mlanX hostcmd <txpwrlimit_cfg.conf> txpwrlimit_cfg_set
+mlanconfig mlanX hostcmd <11n_2040coex.conf> 2040coex
+mlanconfig mlanX hostcmd <robust_btc.conf> robust_btc_get
+mlanconfig mlanX hostcmd <robust_btc.conf> robust_btc_enable
+mlanconfig mlanX hostcmd <robust_btc.conf> robust_btc_disable
+mlanconfig mlanX arpfilter <arpfilter.conf>
+mlanconfig mlanX mefcfg <mef.conf>
+mlanconfig mlanX cfgdata <register type> <conf file>
+mlanconfig mlanX sdcmd52rw <FN no.> <address> [data]
+mlanconfig mlanX sdcmd53rw <FN no.> <address> <mode> <blksize> <blknum> [data1] ... [dataN]
+mlanconfig mlanX setuserscan [ARGS]
+mlanconfig mlanX getscantable
+mlanconfig mlanX addts <filename.conf> <section# of tspec> <timeout in ms>
+mlanconfig mlanX delts <filename.conf> <section# of tspec>
+mlanconfig mlanX qconfig set msdu <lifetime in TUs> [Queue Id: 0-3]
+mlanconfig mlanX qconfig get [Queue Id: 0-3]
+mlanconfig mlanX qconfig def [Queue Id: 0-3]
+mlanconfig mlanX qstats on  [Queue Id: 0-3]
+mlanconfig mlanX qstats off [Queue Id: 0-3]
+mlanconfig mlanX qstats get [Queue Id: 0-3]
+mlanconfig mlanX qstatus
+mlanconfig mlanX ts_status
+mlanconfig mlanX regrdwr <type> <offset> [value]
+
+DESCRIPTION
+
+Those commands are used in Marvell specific application called mlanconfig.
+
+===========
+-v
+	This command is used to display the version of mlanconfig utility.
+	Usage:	
+		mlanconfig -v
+
+hostcmd bgscfg
+	This command is used to configure the various parameters for PPS/UAPSD 
+	or normal background scan.
+	
+	Usage:
+		mlanconfig mlanX hostcmd config/bg_scan.conf bgscfg
+
+hostcmd requesttpc
+	This command is used to request 802.11H TPC info. 
+	
+	Usage:
+		mlanconfig mlanX hostcmd config/requesttpc.conf requesttpc
+
+hostcmd crypto_test
+	This command is used to test the encryption/decryption API of the firmware.
+
+	Usage:
+		mlanconfig mlanX hostcmd config/crypto_test.conf crypto_test
+
+hostcmd subevent_get
+hostcmd subevent_set
+	This command is used to get/set the configurations for event descriptor 
+	interface command.
+	subsvent_get: get subscribed event parameters
+	subsvent_set: set subscribed event parameters
+
+	Usage:
+		mlanconfig mlanX hostcmd config/subevent.conf subevent_get
+		mlanconfig mlanX hostcmd config/subevent.conf subevent_set
+
+hostcmd auto_tx_get
+hostcmd nat_keep_alive
+hostcmd auto_tx_unreg
+	This command is used to configures the Frame Auto Transmission parameters.
+	auto_tx_get: get auto_tx parameters
+	nat_keep_alive: register to firmware for sending NAT Keep Alive packet
+	auto_tx_unreg: unregister to firmware auto_tx
+
+	Usage:
+		mlanconfig mlanX hostcmd config/auto_tx.conf auto_tx_get
+		mlanconfig mlanX hostcmd config/auto_tx.conf nat_keep_alive
+		mlanconfig mlanX hostcmd config/auto_tx.conf auto_tx_unreg
+
+hostcmd txrate_cfg_get
+hostcmd txrate_cfg_set_bg
+hostcmd txrate_cfg_set_bgn
+	This command is used to set/get the transmit data rate.
+
+	Usage:
+		mlanconfig mlanX hostcmd config/txrate_cfg.conf txrate_cfg_get
+		mlanconfig mlanX hostcmd config/txrate_cfg.conf txrate_cfg_set_bg
+		mlanconfig mlanX hostcmd config/txrate_cfg.conf txrate_cfg_set_bgn
+
+hostcmd txpwrlimit_cfg_get
+hostcmd txpwrlimit_cfg_set
+	This command is used to set/get the configuration data of Tx power limitation.
+	Note: The configuration set should be issued when STA is disconnetced.
+
+	Usage:
+		mlanconfig mlanX hostcmd config/txpwrlimit_cfg.conf txpwrlimit_cfg_get
+		mlanconfig mlanX hostcmd config/txpwrlimit_cfg.conf txpwrlimit_cfg_set
+
+hostcmd 2040coex
+	This command is used to send the 11n 20/40 Coex command to firmware. 
+	Firmware will send 11n 20/40 Coex management action frame to AP.
+	
+	Usage:
+		mlanconfig mlanX hostcmd config/11n_2040coex.conf 2040coex
+
+hostcmd robust_btc_get
+hostcmd robust_btc_enable
+hostcmd robust_btc_disable
+	This command is used to get/set Robust BT Coex.
+	robust_btc_get: get the current configuration
+	robust_btc_enable: enable and set the Robust BT Coex timing
+	robust_btc_disable: disable the Robust BT Coex
+
+	Usage:
+		mlanconfig mlanX hostcmd config/robust_btc.conf robust_btc_get
+		mlanconfig mlanX hostcmd config/robust_btc.conf robust_btc_enable
+		mlanconfig mlanX hostcmd config/robust_btc.conf robust_btc_disable
+
+arpfilter
+	This command is used to configure the ARP filtering parameters.
+
+	Usage:
+		mlanconfig mlanX arpfilter config/arpfilter.conf
+
+mefcfg
+	This command is used to set MEF settings.
+
+	Usage:
+		mlanconfig mlanX mefcfg config/mef.conf
+
+cfgdata
+	This command is used to set/get the configuration data to/from firmware.
+
+	Usage:
+		mlanconfig mlanX cfgdata <type> <.conf file name>
+		This command is used to set the cfg data in the .conf file to firmware.
+
+		mlanconfig mlanX cfgdata <type>
+		This command is used to get the cfg data from firmware and display
+		on to the console.
+
+	Where the value of <type> field is:
+		1   -- Optimal Register download and <.conf file name > is or_data.conf
+		2   -- Cal data download and <.conf file name> is cal_data.conf
+		3   -- PMIC data download and <.conf file name> is pmic_data.conf
+
+sdcmd52rw
+	This command is used to read/write a controller register in 
+	Secure Digital I/O Interfaces.
+
+	Usage:
+		mlanconfig mlanX sdcmd52rw <function number> <register address> [value]
+
+    Examples:
+		mlanconfig mlan0 sdcmd52rw 1 3
+		mlanconfig mlan0 sdcmd52rw 1 1 0x3f
+
+sdcmd53rw
+	This command is used to issue a CMD53 read/write data in 
+	Secure Digital I/O Interfaces.
+
+	Usage:
+		mlanconfig mlanX sdcmd53rw <func> <address> <mode> <blksize> <blknum> [data1] ... [dataN]
+
+	where the parameters are,
+		<func>:     function number (0/1/2/..)
+		<address>:  data address
+		<mode>:     byte mode/block mode (0/1)
+		<blksize>:  block size (32/64/../512, NA for byte mode)
+		<blknum>:   block number or byte number
+		<data1> ... <dataN>:  data for write
+
+	Note: The total data length is block size * block number for block mode
+	or byte number for byte mode. The max data length is 2000-byte.
+	For write the data pattern will be duplicated to data buffer.
+
+	Examples:
+		mlanconfig mlan0 sdcmd53rw 0 0x8000 1 64 2
+		mlanconfig mlan0 sdcmd53rw 1 0x10000 0 1 5 0x0a 0x0b 0x0c 0x0d 0x0e
+
+setuserscan
+	Initiate a customized scan and retrieve the results
+
+	Usage:
+		mlanconfig mlanX setuserscan [ARGS]
+
+	Where [ARGS]:
+	  ssid="[SSID]"            specify a SSID filter for the scan
+	  chan=[chan#][band][mode] where band is [a,b,g,n] and mode is
+	                           blank for active or 'p' for passive
+	  bssid=xx:xx:xx:xx:xx:xx  specify a BSSID filter for the scan
+	  wc="[WILDCARD SSID]"     specify a UNIX pattern matching filter (using *
+	                           and ?) for SSIDs found in a broadcast probe
+	  keep=[0 or 1]            keep the previous scan results (1), discard (0)
+	  dur=[scan time]          time to scan for each channel in milliseconds
+	  probes=[#]               number of probe requests to send on each chan
+	                           for each broadcast probe required and each SSID
+	                           specific probe required (1-10)
+	  type=[1,2,3]             BSS type: 1 (Infra), 2(Adhoc), 3(Any)
+
+	Any combination of the above arguments can be supplied on the command line.
+	If the chan token is absent, a full channel scan will be completed by driver.
+	If the dur or probes tokens are absent, the driver default setting will be 
+	used. The bssid and ssid fields, if blank, will produce an unfiltered scan.
+	The type field will default to 3 (Any) and the keep field will default to 0 
+	(Discard).
+
+	Examples:
+	1) Perform an active scan on channels 1, 6, and 11 in the 'g' band:
+		setuserscan chan=1g,6g,11g
+
+	2) Perform a passive scan on channel 11 for 20 ms:
+		setuserscan chan=11gp dur=20
+
+	3) Perform an active scan on channels 1, 6, and 11; and a passive scan on
+	   channel 36 in the 'a' band:
+		setuserscan chan=1g,6g,11g,36ap
+
+	4) Perform an active scan on channel 6 and 36 for a specific SSID:
+		setuserscan chan=6g,36a ssid="TestAP"
+
+	5) Scan all available channels (B/G/N, A bands) for a specific BSSID, keep
+	   the current scan table intact, update existing or append new scan data:
+		setuserscan bssid=00:50:43:20:12:82 keep=1
+
+	6) Scan channel 6, for all infrastructure networks, sending two probe
+	   requests.  Keep the previous scan table intact. Update any duplicate
+	   BSSID/SSID matches with the new scan data:
+		setuserscan chan=6g type=1 probes=2 keep=1
+
+	7) Scan channel 1 and 6, for all networks matching the Mrvl*AP
+	   or AP*Mrvl? patterns and for MrvlTst SSID.  Generate 3 broadcast
+	   probes for the patterns and 3 SSID specific probes for MrvlTst on
+	   both channel 1 and channel 6.
+		setuserscan chan=1g,6g probes=3 wc="Mrvl*AP" wc="AP*Mrvl?" ssid="MrvlTst"
+
+	8) Scan all the channels for specified band.
+		setuserscan chan=0g
+
+	All entries in the scan table (not just the new scan data when keep=1)
+	will be displayed upon completion by use of the getscantable ioctl.
+
+getscantable
+	Display the current contents of the driver scan table
+
+	Usage:
+		mlanconfig mlanX getscantable
+		mlanconfig mlanX getscantable [#]
+		mlanconfig mlanX getscantable tsf
+		mlanconfig mlanX getscantable help
+
+	1) Without argument, the entire scantable is displayed.
+	2) Specifying a # will display detailed information about a specific scan
+	   table entry.  '0' displays driver cached information regarding the
+	   current association (if any).
+	3) The tsf argument will display the entire scan table with the recorded
+	   TSF timestamp for the entry.
+	4) The help argument will display the legend for the capability field.
+
+addts
+	Send an ADDTS command to the associated AP.
+
+	Process a given conf file for a specific TSPEC data block.  Send the
+	  TSPEC along with any other IEs to the driver/firmware for transmission
+	  in an ADDTS request to the associated AP.  
+
+	Return the execution status of the command as well as the ADDTS response
+	  from the AP if any.
+
+	Usage:
+		mlanconfig mlanX addts <filename.conf> <section# of tspec> <timeout(ms)>
+
+delts
+	Send a DELTS command to the associated AP.
+
+	Process a given conf file for a specific TSPEC data block.  Send the
+	  TSPEC along with any other IEs to the driver/firmware for transmission
+	  in a DELTS request to the associated AP.  
+ 
+	Return the execution status of the command.  There is no response to a
+	  DELTS from the AP.
+
+	Usage:
+		mlanconfig mlanX delts <filename.conf> <section# of tspec>
+
+qconfig
+	Send a WMM AC Queue configuration command to get/set/default params
+ 
+	Configure or get the parameters of a WMM AC queue. The command takes
+	  an optional Queue Id as a last parameter.  Without the queue id, all
+	  queues will be acted upon.
+ 
+	Usage:  
+		mlanconfig mlanX qconfig set msdu <lifetime in TUs> [Queue Id: 0-3]
+		mlanconfig mlanX qconfig get [Queue Id: 0-3]
+		mlanconfig mlanX qconfig def [Queue Id: 0-3]
+
+qstats
+	Turn on/off or retrieve and clear the queue statistics for an AC
+
+	Turn the queue statistics collection on/off for a given AC or retrieve the
+	  current accumulated stats and clear them from the firmware. The command
+	  takes an optional Queue Id as a last parameter. Without the queue id,
+	  all queues will be acted upon.
+ 
+	Usage:
+		mlanconfig mlanX qstats on  [Queue Id: 0-3]
+		mlanconfig mlanX qstats off [Queue Id: 0-3]
+		mlanconfig mlanX qstats get [Queue Id: 0-3]
+
+qstatus
+	This command retrieves the current status of the WMM queues. If WMM
+	  is enabled then it displays the informations for each AC in a table.
+
+	Usage:
+		mlanconfig mlanX qstatus
+
+ts_status
+	This command queries the FW for the status of TSIDs 0 through 7
+	  configured via call admission control and displays the results in a
+	  table.
+
+	Usage:
+		mlanconfig mlanX ts_status
+
+regrdwr
+	This command is used to read/write the adapter register.
+	
+	Usage:
+		mlanconfig mlanX regrdwr <type> <offset> [value]
+
+	where the parameters are,
+		<type>:     1:MAC/SOC, 2:BBP, 3:RF, 4:PMIC, 5:CAU
+		<offset>:   offset of register
+		[value]:    value to be written
+
+	Examples:
+		mlanconfig mlan0 regrdwr 1 0xa060   : Read the MAC register
+		mlanconfig mlan0 regrdwr 1 0xa794 0x80000000
+		                                    : Write 0x80000000 to MAC register
+
+
+===============================================================================
+		U S E R  M A N U A L  F O R  M L A N 2 0 4 0 C O E X 
+
+NAME
+mlan2040coex - This application handles the 11n 20/40 coexistence operation for 
+               the Marvell mdriver
+
+SYNOPSIS
+mlan2040coex [-i <intfname>] [hvB]
+(If intfname not present then mlan0 assumed)
+	-h = Help
+	-v = Version
+	-B = Run the process in background
+
+===============================================================================
diff --git a/wlan_src/gpl-2.0.txt b/wlan_src/gpl-2.0.txt
new file mode 100755
index 0000000..58ca40e
--- /dev/null
+++ b/wlan_src/gpl-2.0.txt
@@ -0,0 +1,339 @@
+              GNU GENERAL PUBLIC LICENSE
+ 		       Version 2, June 1991
+ 
+  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  Everyone is permitted to copy and distribute verbatim copies
+  of this license document, but changing it is not allowed.
+ 
+ 			    Preamble
+ 
+   The licenses for most software are designed to take away your
+ freedom to share and change it.  By contrast, the GNU General Public
+ License is intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users.  This
+ General Public License applies to most of the Free Software
+ Foundation's software and to any other program whose authors commit to
+ using it.  (Some other Free Software Foundation software is covered by
+ the GNU Lesser General Public License instead.)  You can apply it to
+ your programs, too.
+ 
+   When we speak of free software, we are referring to freedom, not
+ price.  Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it
+ in new free programs; and that you know you can do these things.
+ 
+   To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the software, or if you modify it.
+ 
+   For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have.  You must make sure that they, too, receive or can get the
+ source code.  And you must show them these terms so they know their
+ rights.
+ 
+   We protect your rights with two steps: (1) copyright the software, and
+ (2) offer you this license which gives you legal permission to copy,
+ distribute and/or modify the software.
+ 
+   Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software.  If the software is modified by someone else and passed on, we
+ want its recipients to know that what they have is not the original, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.
+ 
+   Finally, any free program is threatened constantly by software
+ patents.  We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary.  To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at all.
+ 
+   The precise terms and conditions for copying, distribution and
+ modification follow.
+ 
+ 		    GNU GENERAL PUBLIC LICENSE
+    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ 
+   0. This License applies to any program or other work which contains
+ a notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License.  The "Program", below,
+ refers to any such program or work, and a "work based on the Program"
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language.  (Hereinafter, translation is included without limitation in
+ the term "modification".)  Each licensee is addressed as "you".
+ 
+ Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope.  The act of
+ running the Program is not restricted, and the output from the Program
+ is covered only if its contents constitute a work based on the
+ Program (independent of having been made by running the Program).
+ Whether that is true depends on what the Program does.
+ 
+   1. You may copy and distribute verbatim copies of the Program's
+ source code as you receive it, in any medium, provided that you
+ conspicuously and appropriately publish on each copy an appropriate
+ copyright notice and disclaimer of warranty; keep intact all the
+ notices that refer to this License and to the absence of any warranty;
+ and give any other recipients of the Program a copy of this License
+ along with the Program.
+ 
+ You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a fee.
+ 
+   2. You may modify your copy or copies of the Program or any portion
+ of it, thus forming a work based on the Program, and copy and
+ distribute such modifications or work under the terms of Section 1
+ above, provided that you also meet all of these conditions:
+ 
+     a) You must cause the modified files to carry prominent notices
+     stating that you changed the files and the date of any change.
+ 
+     b) You must cause any work that you distribute or publish, that in
+     whole or in part contains or is derived from the Program or any
+     part thereof, to be licensed as a whole at no charge to all third
+     parties under the terms of this License.
+ 
+     c) If the modified program normally reads commands interactively
+     when run, you must cause it, when started running for such
+     interactive use in the most ordinary way, to print or display an
+     announcement including an appropriate copyright notice and a
+     notice that there is no warranty (or else, saying that you provide
+     a warranty) and that users may redistribute the program under
+     these conditions, and telling the user how to view a copy of this
+     License.  (Exception: if the Program itself is interactive but
+     does not normally print such an announcement, your work based on
+     the Program is not required to print an announcement.)
+ 
+ These requirements apply to the modified work as a whole.  If
+ identifiable sections of that work are not derived from the Program,
+ and can be reasonably considered independent and separate works in
+ themselves, then this License, and its terms, do not apply to those
+ sections when you distribute them as separate works.  But when you
+ distribute the same sections as part of a whole which is a work based
+ on the Program, the distribution of the whole must be on the terms of
+ this License, whose permissions for other licensees extend to the
+ entire whole, and thus to each and every part regardless of who wrote it.
+ 
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.
+ 
+ In addition, mere aggregation of another work not based on the Program
+ with the Program (or with a work based on the Program) on a volume of
+ a storage or distribution medium does not bring the other work under
+ the scope of this License.
+ 
+   3. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+ 
+     a) Accompany it with the complete corresponding machine-readable
+     source code, which must be distributed under the terms of Sections
+     1 and 2 above on a medium customarily used for software interchange; or,
+ 
+     b) Accompany it with a written offer, valid for at least three
+     years, to give any third party, for a charge no more than your
+     cost of physically performing source distribution, a complete
+     machine-readable copy of the corresponding source code, to be
+     distributed under the terms of Sections 1 and 2 above on a medium
+     customarily used for software interchange; or,
+ 
+     c) Accompany it with the information you received as to the offer
+     to distribute corresponding source code.  (This alternative is
+     allowed only for noncommercial distribution and only if you
+     received the program in object code or executable form with such
+     an offer, in accord with Subsection b above.)
+ 
+ The source code for a work means the preferred form of the work for
+ making modifications to it.  For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to
+ control compilation and installation of the executable.  However, as a
+ special exception, the source code distributed need not include
+ anything that is normally distributed (in either source or binary
+ form) with the major components (compiler, kernel, and so on) of the
+ operating system on which the executable runs, unless that component
+ itself accompanies the executable.
+ 
+ If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+ 
+   4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License.  Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+ void, and will automatically terminate your rights under this License.
+ However, parties who have received copies, or rights, from you under
+ this License will not have their licenses terminated so long as such
+ parties remain in full compliance.
+ 
+   5. You are not required to accept this License, since you have not
+ signed it.  However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works.  These actions are
+ prohibited by law if you do not accept this License.  Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying
+ the Program or works based on it.
+ 
+   6. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions.  You may not impose any further
+ restrictions on the recipients' exercise of the rights granted herein.
+ You are not responsible for enforcing compliance by third parties to
+ this License.
+ 
+   7. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License.  If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all.  For example, if a patent
+ license would not permit royalty-free redistribution of the Program by
+ all those who receive copies directly or indirectly through you, then
+ the only way you could satisfy both it and this License would be to
+ refrain entirely from distribution of the Program.
+ 
+ If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.
+ 
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices.  Many people have made
+ generous contributions to the wide range of software distributed
+ through that system in reliance on consistent application of that
+ system; it is up to the author/donor to decide if he or she is willing
+ to distribute software through any other system and a licensee cannot
+ impose that choice.
+ 
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+ 
+   8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License
+ may add an explicit geographical distribution limitation excluding
+ those countries, so that distribution is permitted only in or among
+ countries not thus excluded.  In such case, this License incorporates
+ the limitation as if written in the body of this License.
+ 
+   9. The Free Software Foundation may publish revised and/or new versions
+ of the General Public License from time to time.  Such new versions will
+ be similar in spirit to the present version, but may differ in detail to
+ address new problems or concerns.
+ 
+ Each version is given a distinguishing version number.  If the Program
+ specifies a version number of this License which applies to it and "any
+ later version", you have the option of following the terms and conditions
+ either of that version or of any later version published by the Free
+ Software Foundation.  If the Program does not specify a version number of
+ this License, you may choose any version ever published by the Free Software
+ Foundation.
+ 
+   10. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the author
+ to ask for permission.  For software which is copyrighted by the Free
+ Software Foundation, write to the Free Software Foundation; we sometimes
+ make exceptions for this.  Our decision will be guided by the two goals
+ of preserving the free status of all derivatives of our free software and
+ of promoting the sharing and reuse of software generally.
+ 
+ 			    NO WARRANTY
+ 
+   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+ REPAIR OR CORRECTION.
+ 
+   12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+ 
+ 		     END OF TERMS AND CONDITIONS
+ 
+ 	    How to Apply These Terms to Your New Programs
+ 
+   If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these terms.
+ 
+   To do so, attach the following notices to the program.  It is safest
+ to attach them to the start of each source file to most effectively
+ convey the exclusion of warranty; and each file should have at least
+ the "copyright" line and a pointer to where the full notice is found.
+ 
+     <one line to give the program's name and a brief idea of what it does.>
+     Copyright (C) <year>  <name of author>
+ 
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+ 
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+ 
+     You should have received a copy of the GNU General Public License along
+     with this program; if not, write to the Free Software Foundation, Inc.,
+     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ 
+ Also add information on how to contact you by electronic and paper mail.
+ 
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+ 
+     Gnomovision version 69, Copyright (C) year name of author
+     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+     This is free software, and you are welcome to redistribute it
+     under certain conditions; type `show c' for details.
+ 
+ The hypothetical commands `show w' and `show c' should show the appropriate
+ parts of the General Public License.  Of course, the commands you use may
+ be called something other than `show w' and `show c'; they could even be
+ mouse-clicks or menu items--whatever suits your program.
+ 
+ You should also get your employer (if you work as a programmer) or your
+ school, if any, to sign a "copyright disclaimer" for the program, if
+ necessary.  Here is a sample; alter the names:
+ 
+   Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+   `Gnomovision' (which makes passes at compilers) written by James Hacker.
+ 
+   <signature of Ty Coon>, 1 April 1989
+   Ty Coon, President of Vice
+ 
+ This General Public License does not permit incorporating your program into
+ proprietary programs.  If your program is a subroutine library, you may
+ consider it more useful to permit linking proprietary applications with the
+ library.  If this is what you want to do, use the GNU Lesser General
+ Public License instead of this License.
diff --git a/wlan_src/mapp/mlan2040coex/Makefile b/wlan_src/mapp/mlan2040coex/Makefile
new file mode 100755
index 0000000..42e643e
--- /dev/null
+++ b/wlan_src/mapp/mlan2040coex/Makefile
@@ -0,0 +1,47 @@
+#
+# File : mlan2040coex/Makefile
+#
+# Copyright (C) 2009, Marvell International Ltd.
+# All Rights Reserved
+
+# Path to the top directory of the mlandriver distribution
+PATH_TO_TOP = ../..
+
+# Determine how we should copy things to the install directory
+ABSPATH := $(filter /%, $(INSTALLDIR))
+RELPATH := $(filter-out /%, $(INSTALLDIR))
+INSTALLPATH := $(ABSPATH)
+ifeq ($(strip $(INSTALLPATH)),)
+INSTALLPATH := $(PATH_TO_TOP)/$(RELPATH)
+endif
+
+# Override CFLAGS for application sources, remove __ kernel namespace defines
+CFLAGS := $(filter-out -D__%, $(EXTRA_CFLAGS))
+
+#
+# List of application executables to create
+#
+libobjs:= mlan2040coex.o mlan2040misc.o
+exectarget=mlan2040coex
+TARGETS := $(exectarget)
+
+#
+# Make target rules
+#
+
+# All rule compiles list of TARGETS using builtin program target from src rule
+all :
+$(exectarget): $(libobjs)
+	$(CC) $(CFLAGS) $(libobjs) -o $(exectarget)
+
+# Update any needed TARGETS and then copy to the install path
+build install: $(TARGETS)
+	@cp -f $(exectarget) $(INSTALLPATH)
+
+clean:
+	@rm -f $(exectarget)
+	@rm -f *.o
+
+distclean: clean
+	@rm -f *~ core
+	@rm -f tags
diff --git a/wlan_src/mapp/mlan2040coex/mlan2040coex.c b/wlan_src/mapp/mlan2040coex/mlan2040coex.c
new file mode 100755
index 0000000..00d3029
--- /dev/null
+++ b/wlan_src/mapp/mlan2040coex/mlan2040coex.c
@@ -0,0 +1,1008 @@
+/** @file  mlan2040coex.c
+  *
+  * @brief 11n 20/40 MHz Coex application
+  * 
+  *  Usage:  
+  *
+  *  Copyright (C) 2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+/************************************************************************
+Change log:
+     06/24/2009: initial version
+************************************************************************/
+
+#include    <stdio.h>
+#include    <ctype.h>
+#include    <unistd.h>
+#include    <string.h>
+#include    <signal.h>
+#include    <fcntl.h>
+#include    <stdlib.h>
+#include    <errno.h>
+#include    <sys/socket.h>
+#include    <sys/ioctl.h>
+#include    <linux/if.h>
+#include    <linux/wireless.h>
+#include    <linux/netlink.h>
+#include    <linux/rtnetlink.h>
+#include    <net/ethernet.h>
+#include    "mlan2040coex.h"
+#include    "mlan2040misc.h"
+
+/** coex application's version number */
+#define COEX_VER "M1.0"
+
+/** Initial number of total private ioctl calls */
+#define IW_INIT_PRIV_NUM    128
+/** Maximum number of total private ioctl calls supported */
+#define IW_MAX_PRIV_NUM     1024
+
+/********************************************************
+		Local Variables
+********************************************************/
+
+static t_s8 *usage[] = {
+    "Usage: ",
+    "	mlan2040coex [-i <intfname>] [-hvB] ",
+    "	-h = help",
+    "	-v = version",
+    "	-B = run the process in background.",
+    "	(if intfname not present then mlan0 assumed)"
+};
+
+t_s32 sockfd = 0;  /**< socket descriptor */
+t_s32 nl_sk = 0;  /**< netlink socket descriptor */
+t_s8 dev_name[IFNAMSIZ + 1];   /**< device name */
+static struct iw_priv_args *priv_args = NULL; /**< private args */
+static int we_version_compiled = 0;
+                                  /**< version compiled */
+/** Flag: is 2040coex command required */
+int coex_cmd_req_flag = FALSE;
+/** Flag: is associated */
+int assoc_flag = FALSE;
+/** Flag: is HT AP */
+int is_ht_ap = FALSE;
+/** terminate flag */
+int terminate_flag = FALSE;
+/********************************************************
+		Global Variables
+********************************************************/
+/** OBSS scan parameter of associated AP */
+OBSSScanParam_t cur_obss_scan_param;
+
+/********************************************************
+		Local Functions
+********************************************************/
+/** 
+ *  @brief Get private info.
+ *   
+ *  @param ifname   A pointer to net name
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise --fail
+ */
+static int
+get_private_info(const t_s8 * ifname)
+{
+    /* This function sends the SIOCGIWPRIV command, which is handled by the
+       kernel and gets the total number of private ioctl's available in the
+       host driver. */
+    struct iwreq iwr;
+    int s, ret = MLAN_STATUS_SUCCESS;
+    struct iw_priv_args *ppriv = NULL;
+    struct iw_priv_args *new_priv;
+    int result = 0;
+    size_t size = IW_INIT_PRIV_NUM;
+
+    s = socket(PF_INET, SOCK_DGRAM, 0);
+    if (s < 0) {
+        perror("socket[PF_INET,SOCK_DGRAM]");
+        return MLAN_STATUS_FAILURE;
+    }
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, ifname, IFNAMSIZ);
+
+    do {
+        /* (Re)allocate the buffer */
+        new_priv = realloc(ppriv, size * sizeof(ppriv[0]));
+        if (new_priv == NULL) {
+            printf("Error: Buffer allocation failed\n");
+            ret = MLAN_STATUS_FAILURE;
+            break;
+        }
+        ppriv = new_priv;
+
+        iwr.u.data.pointer = (caddr_t) ppriv;
+        iwr.u.data.length = size;
+        iwr.u.data.flags = 0;
+
+        if (ioctl(s, SIOCGIWPRIV, &iwr)) {
+            result = errno;
+            ret = MLAN_STATUS_FAILURE;
+            if (result == E2BIG) {
+                /* We need a bigger buffer. Check if kernel gave us any hints. */
+                if (iwr.u.data.length > size) {
+                    /* Kernel provided required size */
+                    size = iwr.u.data.length;
+                } else {
+                    /* No hint from kernel, double the buffer size */
+                    size *= 2;
+                }
+            } else {
+                /* ioctl error */
+                perror("ioctl[SIOCGIWPRIV]");
+                break;
+            }
+        } else {
+            /* Success. Return the number of private ioctls */
+            priv_args = ppriv;
+            ret = iwr.u.data.length;
+            break;
+        }
+    } while (size <= IW_MAX_PRIV_NUM);
+
+    if ((ret == MLAN_STATUS_FAILURE) && (ppriv))
+        free(ppriv);
+
+    close(s);
+
+    return ret;
+}
+
+/** 
+ *  @brief Get Sub command ioctl number
+ *   
+ *  @param i        command index
+ *  @param priv_cnt     Total number of private ioctls availabe in driver
+ *  @param ioctl_val    A pointer to return ioctl number
+ *  @param subioctl_val A pointer to return sub-ioctl number
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+marvell_get_subioctl_no(t_s32 i,
+                        t_s32 priv_cnt, int *ioctl_val, int *subioctl_val)
+{
+    t_s32 j;
+
+    if (priv_args[i].cmd >= SIOCDEVPRIVATE) {
+        *ioctl_val = priv_args[i].cmd;
+        *subioctl_val = 0;
+        return MLAN_STATUS_SUCCESS;
+    }
+
+    j = -1;
+
+    /* Find the matching *real* ioctl */
+
+    while ((++j < priv_cnt)
+           && ((priv_args[j].name[0] != '\0') ||
+               (priv_args[j].set_args != priv_args[i].set_args) ||
+               (priv_args[j].get_args != priv_args[i].get_args))) {
+    }
+
+    /* If not found... */
+    if (j == priv_cnt) {
+        printf("%s: Invalid private ioctl definition for: 0x%x\n",
+               dev_name, priv_args[i].cmd);
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Save ioctl numbers */
+    *ioctl_val = priv_args[j].cmd;
+    *subioctl_val = priv_args[i].cmd;
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Get ioctl number
+ *   
+ *  @param ifname       A pointer to net name
+ *  @param priv_cmd     A pointer to priv command buffer
+ *  @param ioctl_val    A pointer to return ioctl number
+ *  @param subioctl_val A pointer to return sub-ioctl number
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+marvell_get_ioctl_no(const t_s8 * ifname,
+                     const t_s8 * priv_cmd, int *ioctl_val, int *subioctl_val)
+{
+    t_s32 i;
+    t_s32 priv_cnt;
+    int ret = MLAN_STATUS_FAILURE;
+
+    priv_cnt = get_private_info(ifname);
+
+    /* Are there any private ioctls? */
+    if (priv_cnt <= 0 || priv_cnt > IW_MAX_PRIV_NUM) {
+        /* Could skip this message ? */
+        printf("%-8.8s  no private ioctls.\n", ifname);
+    } else {
+        for (i = 0; i < priv_cnt; i++) {
+            if (priv_args[i].name[0] && !strcmp(priv_args[i].name, priv_cmd)) {
+                ret = marvell_get_subioctl_no(i, priv_cnt,
+                                              ioctl_val, subioctl_val);
+                break;
+            }
+        }
+    }
+
+    if (priv_args) {
+        free(priv_args);
+        priv_args = NULL;
+    }
+
+    return ret;
+}
+
+/** 
+ *  @brief Retrieve the ioctl and sub-ioctl numbers for the given ioctl string
+ *   
+ *  @param ioctl_name   Private IOCTL string name
+ *  @param ioctl_val    A pointer to return ioctl number
+ *  @param subioctl_val A pointer to return sub-ioctl number
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+get_priv_ioctl(char *ioctl_name, int *ioctl_val, int *subioctl_val)
+{
+    int retval;
+
+    retval =
+        marvell_get_ioctl_no(dev_name, ioctl_name, ioctl_val, subioctl_val);
+    return retval;
+}
+
+/** 
+ *  @brief Process OBSS scan table
+ *  @return     MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+process_scantable(void)
+{
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    t_u8 *scan_rsp_buf = NULL;
+    char ssid[MRVDRV_MAX_SSID_LENGTH + 1];
+    unsigned int scan_start;
+    int idx, i = 0, j, already_listed, ssid_len, ssid_idx;
+
+    t_u8 *pcurrent;
+    t_u8 *pnext;
+    IEEEtypes_ElementId_e *pelement_id;
+    t_u8 *pelement_len, ht_cap_present, intol_bit_is_set;
+    int bss_info_len, ret = MLAN_STATUS_SUCCESS;
+
+    IEEEtypes_CapInfo_t cap_info = { 0 };
+    t_u8 tsf[8];
+    t_u16 beacon_interval;
+    IEEEtypes_HTCap_t *pht_cap;
+    int scan_result_found;
+
+    wlan_ioctl_get_scan_table_info *prsp_info;
+    wlan_ioctl_get_scan_table_entry *prsp_entry;
+
+    scan_rsp_buf = (t_u8 *) malloc(SCAN_RESP_BUF_SIZE);
+    if (scan_rsp_buf == NULL) {
+        printf("Error: allocate memory for scan_rsp_buf failed\n");
+        return -ENOMEM;
+    }
+    prsp_info = (wlan_ioctl_get_scan_table_info *) scan_rsp_buf;
+    memset(leg_ap_chan_list, 0, sizeof(leg_ap_chan_list));
+    num_leg_ap_chan = 0;
+    if (get_priv_ioctl("getscantable",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        ret = -EOPNOTSUPP;
+        goto done;
+    }
+
+    scan_result_found = FALSE;
+    scan_start = 1;
+
+    do {
+        prsp_info->scan_number = scan_start;
+
+        /** Set up and execute the ioctl call */
+        strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+        iwr.u.data.pointer = (caddr_t) prsp_info;
+        iwr.u.data.length = SCAN_RESP_BUF_SIZE;
+        iwr.u.data.flags = subioctl_val;
+
+        if (ioctl(sockfd, ioctl_val, &iwr)) {
+            perror("mlan2040coex: getscantable ioctl");
+            ret = -EFAULT;
+            goto done;
+        }
+
+        pcurrent = 0;
+        pnext = prsp_info->scan_table_entry_buf;
+
+        for (idx = 0; idx < prsp_info->scan_number; idx++) {
+
+            /* 
+             * Set pcurrent to pnext in case pad bytes are at the end
+             * of the last IE we processed.
+             */
+            pcurrent = pnext;
+            prsp_entry = (wlan_ioctl_get_scan_table_entry *) pcurrent;
+            scan_result_found = TRUE;
+            pcurrent += (sizeof(prsp_entry->fixed_field_length) +
+                         prsp_entry->fixed_field_length);
+
+            bss_info_len = prsp_entry->bss_info_length;
+            pcurrent += sizeof(prsp_entry->bss_info_length);
+            pnext = pcurrent + prsp_entry->bss_info_length;
+
+            if (bss_info_len >= (sizeof(tsf)
+                                 + sizeof(beacon_interval) + sizeof(cap_info))) {
+                pcurrent +=
+                    (sizeof(tsf) + sizeof(beacon_interval) + sizeof(cap_info));
+                bss_info_len -=
+                    (sizeof(tsf) + sizeof(beacon_interval) + sizeof(cap_info));
+            }
+            ht_cap_present = FALSE;
+            intol_bit_is_set = FALSE;
+            while (bss_info_len >= 2) {
+                pelement_id = (IEEEtypes_ElementId_e *) pcurrent;
+                pelement_len = pcurrent + 1;
+                pcurrent += 2;
+
+                switch (*pelement_id) {
+                case SSID:
+                    if (*pelement_len &&
+                        *pelement_len <= MRVDRV_MAX_SSID_LENGTH) {
+                        memcpy(ssid, pcurrent, *pelement_len);
+                        ssid_len = *pelement_len;
+                    }
+                    break;
+
+                case HT_CAPABILITY:
+                    pht_cap = (IEEEtypes_HTCap_t *) pelement_id;
+                    ht_cap_present = TRUE;
+                    if (IS_INTOL_BIT_SET
+                        (le16_to_cpu(pht_cap->ht_cap.ht_cap_info))) {
+                        intol_bit_is_set = TRUE;
+                    }
+                    break;
+                default:
+                    break;
+                }
+                pcurrent += *pelement_len;
+                bss_info_len -= (2 + *pelement_len);
+            }
+            if (!ht_cap_present || intol_bit_is_set) {
+                printf("%s AP found on channel number: %-3d ",
+                       intol_bit_is_set ? "40 MHZ intolerant" : "Legacy",
+                       prsp_entry->fixed_fields.channel);
+                if (ssid_len) {
+                    printf("SSID: ");
+                    /* Print out the ssid or the hex values if non-printable */
+                    for (ssid_idx = 0; ssid_idx < ssid_len; ssid_idx++) {
+                        if (isprint(ssid[ssid_idx])) {
+                            printf("%c", ssid[ssid_idx]);
+                        } else {
+                            printf("\\%02x", ssid[ssid_idx]);
+                        }
+                    }
+                }
+                printf("\n");
+
+                /* Verify that the channel is already listed or not */
+                already_listed = FALSE;
+                for (j = 0; j < i; j++) {
+                    if (leg_ap_chan_list[j].chan_num ==
+                        prsp_entry->fixed_fields.channel) {
+                        already_listed = TRUE;
+                        break;
+                    }
+                }
+                if (!already_listed) {
+                    /* add the channel in list */
+                    leg_ap_chan_list[i].chan_num =
+                        prsp_entry->fixed_fields.channel;
+                    leg_ap_chan_list[i].is_intol_set = intol_bit_is_set;
+                    i++;
+                    coex_cmd_req_flag = TRUE;
+                    num_leg_ap_chan++;
+                }
+            }
+        }
+        scan_start += prsp_info->scan_number;
+        memset(ssid, 0, sizeof(ssid));
+        ssid_len = 0;
+
+    } while (prsp_info->scan_number);
+
+  done:
+    if (scan_rsp_buf)
+        free(scan_rsp_buf);
+    return ret;
+}
+
+/** BSS Mode any (both infra and adhoc) */
+#define BSS_MODE_ANY 3
+
+/** 
+ *  @brief Issue OBSS scan command
+ *  @return     MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+process_setuserscan(void)
+{
+    wlan_ioctl_user_scan_cfg scan_req;
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+
+    memset(&scan_req, 0x00, sizeof(scan_req));
+    coex_cmd_req_flag = FALSE;
+
+    if (get_priv_ioctl("setuserscan",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    scan_req.bss_mode = BSS_MODE_ANY;
+    scan_req.chan_list[0].scan_time =
+        (t_u32) le16_to_cpu(cur_obss_scan_param.obss_scan_active_dwell);
+
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) & scan_req;
+    iwr.u.data.length = sizeof(scan_req);
+    iwr.u.data.flags = subioctl_val;
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        perror("mlan2040coex: setuserscan ioctl");
+        return -EFAULT;
+    }
+    /** process scan results */
+    process_scantable();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief  get range 
+ *   
+ *  @return MLAN_STATUS_SUCCESS--success, otherwise --fail
+ */
+static int
+get_range(t_void)
+{
+    struct iw_range *range;
+    struct iwreq iwr;
+    size_t buf_len;
+
+    buf_len = sizeof(struct iw_range) + 500;
+    range = malloc(buf_len);
+    if (range == NULL) {
+        printf("Error: allocate memory for iw_range failed\n");
+        return -ENOMEM;
+    }
+    memset(range, 0, buf_len);
+    memset(&iwr, 0, sizeof(struct iwreq));
+    iwr.u.data.pointer = (caddr_t) range;
+    iwr.u.data.length = buf_len;
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+
+    if (ioctl(sockfd, SIOCGIWRANGE, &iwr)) {
+        printf("Get Range Results Failed\n");
+        free(range);
+        return MLAN_STATUS_FAILURE;
+    }
+    we_version_compiled = range->we_version_compiled;
+    printf("Driver build with Wireless Extension %d\n",
+           range->we_version_compiled);
+    free(range);
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Display usage
+ *  
+ *  @return       NA
+ */
+static t_void
+display_usage(t_void)
+{
+    t_s32 i;
+    for (i = 0; i < NELEMENTS(usage); i++)
+        fprintf(stderr, "%s\n", usage[i]);
+}
+
+/** 
+ *  @brief              get connection status 
+ *  
+ *  @param data         Pointer to the output buffer holding connection status
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+get_connstatus(int *data)
+{
+    struct iwreq iwr;
+    struct sockaddr apaddr;
+    struct ether_addr etherzero = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+
+    if (ioctl(sockfd, SIOCGIWAP, &iwr)) {
+        fprintf(stderr, "mlan2040coex: ioctl SIOCGIWAP failed by %s\n",
+                dev_name);
+        return MLAN_STATUS_FAILURE;
+    }
+
+    memset(&apaddr, 0, sizeof(struct sockaddr));
+    memcpy(&apaddr, &(iwr.u.ap_addr), sizeof(struct sockaddr));
+    if (!memcmp
+        ((struct ether_addr *) apaddr.sa_data, &etherzero,
+         sizeof(struct ether_addr))) {
+        /* not associated */
+        *data = FALSE;
+    } else {
+        /* associated */
+        *data = TRUE;
+    }
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief              This function parses for IWEVENT events 
+ *
+ *  @param h            Pointer to Netlink message header
+ *  @param left         Number of bytes to be read
+ *  @param evt_conn     A pointer to a output buffer. It sets TRUE when it gets
+ *  					the event CUS_EVT_OBSS_SCAN_PARAM, otherwise FALSE
+ *  @return             Number of bytes left to be read
+ */
+static int
+drv_iwevt_handler(struct nlmsghdr *h, int left, int *evt_conn)
+{
+    int len, plen, attrlen, nlmsg_len, rta_len;
+    struct ifinfomsg *ifi;
+    struct rtattr *attr;
+
+    *evt_conn = FALSE;
+    while (left >= sizeof(*h)) {
+        len = h->nlmsg_len;
+        plen = len - sizeof(*h);
+        if (len > left || plen < 0) {
+            /* malformed netlink message */
+            break;
+        }
+        if (plen < sizeof(*ifi)) {
+            break;
+        }
+        ifi = NLMSG_DATA(h);
+        nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
+        attrlen = h->nlmsg_len - nlmsg_len;
+        if (attrlen < 0) {
+            break;
+        }
+
+        attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+        rta_len = RTA_ALIGN(sizeof(struct rtattr));
+        while (RTA_OK(attr, attrlen)) {
+            if (attr->rta_type == IFLA_WIRELESS) {
+                struct iw_event *iwe;
+                char *pos = ((char *) attr) + rta_len;
+                char *end = pos + (attr->rta_len - rta_len);
+                unsigned short dlen;
+
+                while (pos + IW_EV_LCP_LEN <= end) {
+                    iwe = (struct iw_event *) pos;
+                    if (iwe->len <= IW_EV_LCP_LEN)
+                        break;
+
+                    switch (iwe->cmd) {
+                    case SIOCGIWAP:
+                        {
+                            struct ether_addr *wap;
+                            struct ether_addr etherzero =
+                                { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
+                            char buf[32];
+
+                            wap = (struct ether_addr *)
+                                ((struct sockaddr *) (&iwe->u.ap_addr))->
+                                sa_data;
+
+                            if (!memcmp
+                                (wap, &etherzero, sizeof(struct ether_addr))) {
+                                printf("---< Disconnected from AP >---\n");
+                                memset(&cur_obss_scan_param, 0,
+                                       sizeof(cur_obss_scan_param));
+                                assoc_flag = FALSE;
+                                is_ht_ap = FALSE;
+                            } else {
+                                memset(buf, 0, sizeof(buf));
+                                sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+                                        wap->ether_addr_octet[0],
+                                        wap->ether_addr_octet[1],
+                                        wap->ether_addr_octet[2],
+                                        wap->ether_addr_octet[3],
+                                        wap->ether_addr_octet[4],
+                                        wap->ether_addr_octet[5]);
+                                printf("---< Connected to AP: %s >---\n", buf);
+                                /** set TRUE, if connected */
+                                assoc_flag = TRUE;
+                            }
+                            pos += iwe->len;
+                        }
+                        break;
+                    case IWEVCUSTOM:
+                        {
+                            char *custom;
+                            custom = pos + IW_EV_POINT_LEN;
+                            if (IW_EV_POINT_LEN ==
+                                IW_EV_LCP_LEN + sizeof(struct iw_point)) {
+                                dlen = iwe->u.data.length;
+                            } else {    /* WIRELESS_EXT >= 19 */
+                                dlen =
+                                    *((unsigned short *) (pos + IW_EV_LCP_LEN));
+                            }
+                            if (custom + dlen > end)
+                                break;
+
+                            printf("---< %s >---\n", custom);
+                            if (!strncmp
+                                (CUS_EVT_OBSS_SCAN_PARAM, custom,
+                                 strlen(CUS_EVT_OBSS_SCAN_PARAM))) {
+                                memset(&cur_obss_scan_param, 0,
+                                       sizeof(cur_obss_scan_param));
+                                memcpy(&cur_obss_scan_param,
+                                       (custom +
+                                        strlen(CUS_EVT_OBSS_SCAN_PARAM) + 1),
+                                       sizeof(cur_obss_scan_param));
+                                /** set TRUE, since it is an HT AP */
+                                is_ht_ap = TRUE;
+                                *evt_conn = TRUE;
+                            }
+                            pos += iwe->len;
+                        }
+                        break;
+                    default:
+                        pos += iwe->len;
+                        break;
+                    }
+                }
+            }
+            attr = RTA_NEXT(attr, attrlen);
+        }
+
+        len = NLMSG_ALIGN(len);
+        left -= len;
+        h = (struct nlmsghdr *) ((char *) h + len);
+    }
+    return left;
+}
+
+/**
+ *  @brief Run the application
+ */
+void
+run_app(void)
+{
+    struct timeval tv;
+    fd_set rfds;
+    int ret = MLAN_STATUS_FAILURE;
+    char msg[1024];
+    int left, evt_conn;
+
+    /* Initialize timeout value */
+    tv.tv_sec = DEFAULT_SCAN_INTERVAL;
+    tv.tv_usec = 0;
+
+    /** Get connection status */
+    if (get_connstatus(&assoc_flag) == MLAN_STATUS_FAILURE)
+        return;
+
+    while (!terminate_flag) {
+        memset(msg, 0, sizeof(msg));
+        /* Setup read fds */
+        FD_ZERO(&rfds);
+        FD_SET(nl_sk, &rfds);
+        /* Wait for event */
+        ret = select(nl_sk + 1, &rfds, NULL, NULL, &tv);
+        if (ret == MLAN_STATUS_FAILURE) {
+            /* Error */
+            tv.tv_sec = DEFAULT_SCAN_INTERVAL;
+            tv.tv_usec = 0;
+            continue;
+        } else if (!ret) {
+            if (assoc_flag && is_ht_ap) {
+                /** Issue OBSS scan */
+                process_setuserscan();
+                /** Invoke 2040coex command, if any legacy AP found or 
+                 *  any AP has 40MHz intolarent bit set */
+                if (coex_cmd_req_flag)
+                    invoke_coex_command();
+            }
+            if (assoc_flag && is_ht_ap) {
+                /* Timeout. Try again after BSS channel width triger scan
+                   interval when the STA is connected with a HT AP */
+                tv.tv_sec =
+                    (t_u32) le16_to_cpu(cur_obss_scan_param.
+                                        bss_chan_width_trigger_scan_int);
+            } else {
+                /* Timeout. Try again after default duration when the STA is
+                   not connected with a HT AP */
+                tv.tv_sec = DEFAULT_SCAN_INTERVAL;
+            }
+            tv.tv_usec = 0;
+            continue;
+        }
+        if (!FD_ISSET(nl_sk, &rfds)) {
+            /* Unexpected error. Try again */
+            tv.tv_sec = DEFAULT_SCAN_INTERVAL;
+            tv.tv_usec = 0;
+            continue;
+        }
+        left = recv(nl_sk, msg, sizeof(msg), MSG_DONTWAIT);
+
+        /* handle only IWEVENT events here */
+        left = drv_iwevt_handler((struct nlmsghdr *) msg, left, &evt_conn);
+        if (assoc_flag && is_ht_ap) {
+            /** If the event is connected with an HT AP then issue OBSS scan immediately */
+            if (evt_conn) {
+                /** Issue OBSS scan */
+                process_setuserscan();
+                /** Invoke 2040coex command, if any legacy AP found or 
+                 *  any AP has 40MHz intolarent bit set */
+                if (coex_cmd_req_flag)
+                    invoke_coex_command();
+            }
+            tv.tv_sec =
+                (t_u32) le16_to_cpu(cur_obss_scan_param.
+                                    bss_chan_width_trigger_scan_int);
+        } else {
+            tv.tv_sec = DEFAULT_SCAN_INTERVAL;
+        }
+        tv.tv_usec = 0;
+    }
+    return;
+}
+
+/** 
+ *  @brief open netlink socket
+ *  @return  socket id --success, otherwise--MLAN_STATUS_FAILURE
+ */
+int
+open_netlink(void)
+{
+    int sk;
+    struct sockaddr_nl addr;
+
+    /* Open Netlink socket */
+    sk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+    if (sk < 0) {
+        printf("ERR:Could not open netlink socket.\n");
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Set source address */
+    memset(&addr, 0, sizeof(addr));
+    addr.nl_family = AF_NETLINK;
+    addr.nl_groups = RTMGRP_LINK;
+
+    /* Bind socket with source address */
+    if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+        printf("ERR:Could not bind socket!\n");
+        return MLAN_STATUS_FAILURE;
+    }
+    return sk;
+}
+
+/** 
+ *  @brief Terminate signal handler
+ */
+static t_void
+terminate_handler(int signal)
+{
+    terminate_flag = TRUE;
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+/** 
+ *  @brief Process host command 
+ *  @param cmd        Command    
+ *  @param chan_list  A pointer to a channel list    
+ *  @param chan_num   Number of channels in the channel list    
+ *  @param reg_class  Regulatory class of the channels
+ *  @param is_intol_ap_present Flag:is there any 40 MHz intolerant AP is present or not 
+ *
+ *  @return     MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+process_host_cmd(int cmd, t_u8 * chan_list, t_u8 chan_num, t_u8 reg_class,
+                 t_u8 is_intol_ap_present)
+{
+    HostCmd_DS_GEN *hostcmd;
+    struct iwreq iwr;
+    int ret = MLAN_STATUS_SUCCESS;
+    int ioctl_val, subioctl_val;
+    t_u8 *buf = NULL;
+
+    if (get_priv_ioctl("hostcmd",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+    buf = (t_u8 *) malloc(MRVDRV_SIZE_OF_CMD_BUFFER);
+    if (buf == NULL) {
+        printf("Error: allocate memory for hostcmd failed\n");
+        return -ENOMEM;
+    }
+
+    switch (cmd) {
+    case CMD_2040COEX:
+        prepare_coex_cmd_buff(buf, chan_list, chan_num, reg_class,
+                              is_intol_ap_present);
+        break;
+    default:
+        break;
+    }
+
+    hostcmd = (HostCmd_DS_GEN *) buf;
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = (t_u8 *) hostcmd;
+    iwr.u.data.length = le16_to_cpu(hostcmd->size);
+
+    iwr.u.data.flags = 0;
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        fprintf(stderr, "mlan2040coex: MLANHOSTCMD is not supported by %s\n",
+                dev_name);
+        ret = MLAN_STATUS_FAILURE;
+        goto _exit_;
+    }
+    ret = process_host_cmd_resp(buf);
+
+  _exit_:
+    if (buf)
+        free(buf);
+    return ret;
+}
+
+/** 
+ *  @brief Check the STA is 40 MHz intolerant or not 
+ *  @param intol	Flag: TRUE when the STA is 40 MHz intolerant, otherwise FALSE
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+is_intolerant_sta(int *intol)
+{
+    struct iwreq iwr;
+    int ret = MLAN_STATUS_SUCCESS;
+    int ioctl_val, subioctl_val, htcap_info;
+
+    *intol = FALSE;
+    if (get_priv_ioctl("htcapinfo",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = &htcap_info;
+    iwr.u.data.length = 0;
+    iwr.u.data.flags = subioctl_val;
+
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        fprintf(stderr,
+                "mlan2040coex: private command 'htcapinfo' is not supported by %s\n",
+                dev_name);
+        ret = MLAN_STATUS_FAILURE;
+    }
+    if (htcap_info & MBIT(8))
+        *intol = TRUE;
+
+    return ret;
+}
+
+/** 
+ *  @brief get region code 
+ *  @param reg_code	Pointer to region code
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+get_region_code(int *reg_code)
+{
+    struct iwreq iwr;
+    int ret = MLAN_STATUS_SUCCESS;
+    int ioctl_val, subioctl_val;
+
+    if (get_priv_ioctl("regioncode",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = reg_code;
+    iwr.u.data.length = 0;
+    iwr.u.data.flags = subioctl_val;
+
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        fprintf(stderr,
+                "mlan2040coex: private command 'regioncode' is not supported by %s\n",
+                dev_name);
+        ret = MLAN_STATUS_FAILURE;
+    }
+    return ret;
+}
+
+/** No option */
+#define NO_OPTION -1
+
+/** 
+ *  @brief Entry function for coex
+ *  @param argc		number of arguments
+ *  @param argv     A pointer to arguments array    
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+main(int argc, char *argv[])
+{
+    char *ifname = "mlan0";
+    int c, daemonize = FALSE;
+    for (;;) {
+        c = getopt(argc, argv, "Bhi:v");
+        /* check if all command-line options have been parsed */
+        if (c == NO_OPTION)
+            break;
+
+        switch (c) {
+        case 'B':
+            daemonize = TRUE;
+            break;
+        case 'h':
+            display_usage();
+            return MLAN_STATUS_SUCCESS;
+        case 'v':
+            fprintf(stdout, "Marvell 20/40coex application version %s\n",
+                    COEX_VER);
+            return MLAN_STATUS_SUCCESS;
+        case 'i':
+            ifname = optarg;
+            break;
+        default:
+            fprintf(stdout, "Invalid argument\n");
+            display_usage();
+            return MLAN_STATUS_SUCCESS;
+        }
+    }
+
+    strncpy(dev_name, ifname, IFNAMSIZ);
+
+    /* create a socket */
+    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        fprintf(stderr, "mlan2040coex: Cannot open socket.\n");
+        goto done;
+    }
+    if (get_range() != MLAN_STATUS_SUCCESS) {
+        fprintf(stderr, "mlan2040coex: Cannot get range.\n");
+        goto done;
+    }
+    /* create a netlink socket */
+    if ((nl_sk = open_netlink()) == MLAN_STATUS_FAILURE) {
+        fprintf(stderr, "mlan2040coex: Cannot open netlink socket.\n");
+        goto done;
+    }
+
+    signal(SIGHUP, terminate_handler);  /* catch hangup signal */
+    signal(SIGTERM, terminate_handler); /* catch kill signal */
+
+    /** Make the process background-process */
+    if (daemonize)
+        daemon(0, 0);
+
+    /** run the application */
+    run_app();
+
+  done:
+    if (sockfd)
+        close(sockfd);
+    if (nl_sk)
+        close(nl_sk);
+
+    return MLAN_STATUS_SUCCESS;
+}
diff --git a/wlan_src/mapp/mlan2040coex/mlan2040coex.h b/wlan_src/mapp/mlan2040coex/mlan2040coex.h
new file mode 100755
index 0000000..b59fbe8
--- /dev/null
+++ b/wlan_src/mapp/mlan2040coex/mlan2040coex.h
@@ -0,0 +1,125 @@
+/** @file  mlan2040coex.h
+  *
+  * @brief This file contains definitions for application
+  * 
+  *  Copyright (C) 2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+/************************************************************************
+Change log:
+     06/24/2009: initial version
+************************************************************************/
+#ifndef _COEX_H_
+#define _COEX_H_
+
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+#undef BIG_ENDIAN
+#endif
+
+/** 16 bits byte swap */
+#define swap_byte_16(x) \
+((t_u16)((((t_u16)(x) & 0x00ffU) << 8) | \
+         (((t_u16)(x) & 0xff00U) >> 8)))
+
+/** 32 bits byte swap */
+#define swap_byte_32(x) \
+((t_u32)((((t_u32)(x) & 0x000000ffUL) << 24) | \
+         (((t_u32)(x) & 0x0000ff00UL) <<  8) | \
+         (((t_u32)(x) & 0x00ff0000UL) >>  8) | \
+         (((t_u32)(x) & 0xff000000UL) >> 24)))
+
+/** Convert to correct endian format */
+#ifdef 	BIG_ENDIAN
+/** CPU to little-endian convert for 16-bit */
+#define 	cpu_to_le16(x)	swap_byte_16(x)
+/** CPU to little-endian convert for 32-bit */
+#define		cpu_to_le32(x)  swap_byte_32(x)
+/** Little-endian to CPU convert for 16-bit */
+#define 	le16_to_cpu(x)	swap_byte_16(x)
+/** Little-endian to CPU convert for 32-bit */
+#define		le32_to_cpu(x)  swap_byte_32(x)
+#else
+/** Do nothing */
+#define		cpu_to_le16(x)	(x)
+/** Do nothing */
+#define		cpu_to_le32(x)  (x)
+/** Do nothing */
+#define 	le16_to_cpu(x)	(x)
+/** Do nothing */
+#define 	le32_to_cpu(x)	(x)
+#endif
+
+/** Character, 1 byte */
+typedef char t_s8;
+/** Unsigned character, 1 byte */
+typedef unsigned char t_u8;
+
+/** Short integer */
+typedef signed short t_s16;
+/** Unsigned short integer */
+typedef unsigned short t_u16;
+
+/** Long integer */
+typedef signed long t_s32;
+/** Unsigned long integer */
+typedef unsigned long t_u32;
+
+/** Long long integer */
+typedef signed long long t_s64;
+/** Unsigned long long integer */
+typedef unsigned long long t_u64;
+
+/** Void pointer (4-bytes) */
+typedef void t_void;
+
+#ifdef FALSE
+#undef FALSE
+#endif
+
+#ifdef TRUE
+#undef TRUE
+#endif
+
+#ifndef MIN
+/** Find minimum value */
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif /* MIN */
+
+/** Type definition: boolean */
+typedef enum
+{ FALSE, TRUE } boolean;
+
+/** Find number of elements */
+#define NELEMENTS(x) (sizeof(x)/sizeof(x[0]))
+/** Success */
+#define MLAN_STATUS_SUCCESS         (0)
+/** Failure */
+#define MLAN_STATUS_FAILURE         (-1)
+
+/** Enumeration for host-command index */
+enum COMMANDS
+{
+    CMD_2040COEX = 1,
+};
+/** Maximum number of channels that can be sent in a setuserscan ioctl */
+#define WLAN_IOCTL_USER_SCAN_CHAN_MAX  50
+
+/** Structure defination of chan_intol_t*/
+typedef struct _chan_intol_t
+{
+    /** Channel numer */
+    t_u8 chan_num;
+    /** Flag: Is any 40MHz intolerant AP found in this channel */
+    t_u8 is_intol_set;
+} chan_intol_t;
+
+/** Legacy APs channel list */
+chan_intol_t leg_ap_chan_list[WLAN_IOCTL_USER_SCAN_CHAN_MAX];
+/** Total number of channel present in Legacy APs channel list */
+t_u8 num_leg_ap_chan;
+int get_region_code(int *reg_code);
+int process_host_cmd(int cmd, t_u8 * chan_list, t_u8 chan_num, t_u8 reg_class,
+                     t_u8 is_intol_ap_present);
+int is_intolerant_sta(int *intol);
+
+#endif /* _COEX_H_ */
diff --git a/wlan_src/mapp/mlan2040coex/mlan2040misc.c b/wlan_src/mapp/mlan2040coex/mlan2040misc.c
new file mode 100755
index 0000000..c2441cb
--- /dev/null
+++ b/wlan_src/mapp/mlan2040coex/mlan2040misc.c
@@ -0,0 +1,235 @@
+/** @file mlan2040misc.c
+  *
+  * @brief This file contains helper functions for coex application
+  * 
+  *  Copyright (C) 2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+/************************************************************************
+Change log:
+     06/24/2009: initial version
+************************************************************************/
+#include    <stdio.h>
+#include    <ctype.h>
+#include    <string.h>
+#include    <stdlib.h>
+#include    "mlan2040coex.h"
+#include    "mlan2040misc.h"
+
+/********************************************************
+		Local Variables
+********************************************************/
+static class_chan_t us_class_chan_t[] = {
+    {32, {1, 2, 3, 4, 5, 6, 7}, 7},
+    {33, {5, 6, 7, 8, 9, 10, 11}, 7}
+};
+
+static class_chan_t europe_class_chan_t[] = {
+    {11, {1, 2, 3, 4, 5, 6, 7, 8, 9}, 9},
+    {12, {5, 6, 7, 8, 9, 10, 11, 12, 13}, 9}
+};
+
+static class_chan_t japan_class_chan_t[] = {
+    {56, {1, 2, 3, 4, 5, 6, 7, 8, 9}, 9},
+    {57, {5, 6, 7, 8, 9, 10, 11, 12, 13}, 9}
+};
+
+static region_class_chan_t region_class_chan_table[] = {
+    {0x10, us_class_chan_t, sizeof(us_class_chan_t) / sizeof(class_chan_t)}
+    ,
+    {0x30, europe_class_chan_t,
+     sizeof(europe_class_chan_t) / sizeof(class_chan_t)}
+    ,
+    {0x40, japan_class_chan_t, sizeof(japan_class_chan_t) / sizeof(class_chan_t)}
+};
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/********************************************************
+		Local Functions
+********************************************************/
+/** 
+ *  @brief  This function prepares the channel list for a particular
+ *  		regulatory class from channel number for legacy AP
+ *  @param cur_class_chan_table  A pointer to the class_chan_t
+ *  @param num_entry             Number of entry in cur_class_chan_table table
+ *  @param chan_list             A pointer to the output channel list
+ *  @param chan_num	             total number of channel in output channel list
+ *  @param reg_domain            regulatory domain
+ *  @param reg_class             regulatory class
+ *  @param is_intol_ap_present   It sets TRUE when 40MHz intolerant AP is found
+ *  						     otherwise FALSE
+ *  @return      	  None
+ */
+static void
+get_channels_for_specified_reg_class(class_chan_t * cur_class_chan_table,
+                                     int num_entry, t_u8 * chan_list,
+                                     t_u8 * chan_num, t_u8 reg_domain,
+                                     t_u8 reg_class, t_u8 * is_intol_ap_present)
+{
+    int i, j, k, idx = 0;
+
+    *is_intol_ap_present = FALSE;
+
+    /* For each regulatory class */
+    for (i = 0; i < num_entry; i++) {
+        if (cur_class_chan_table[i].reg_class == reg_class) {
+            /* For each channel of the regulatory class */
+            for (j = 0; j < cur_class_chan_table[i].total_chan; j++) {
+                for (k = 0; k < num_leg_ap_chan; k++) {
+
+                    if (cur_class_chan_table[i].channels[j] ==
+                        leg_ap_chan_list[k].chan_num) {
+                        *(chan_list + idx) = leg_ap_chan_list[k].chan_num;
+                        idx++;
+                        if (leg_ap_chan_list[k].is_intol_set)
+                            *is_intol_ap_present = TRUE;
+                    }
+                }
+            }
+            break;
+        }
+    }
+    /* update the total number of channel */
+    *chan_num = idx--;
+    return;
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+/** 
+ *  @brief Prepare 2040 coex command buffer
+ *  @param buf		   A pointer to the command buffer
+ *  @param chan_list   Channel list
+ *  @param num_of_chan Number of channel present in channel list
+ *  @param reg_class   Regulatory class
+ *  @param is_intol_ap_present   Flag: is any 40 MHz intolerant AP 
+ *  				   is present in these chaanel set 
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+void
+prepare_coex_cmd_buff(t_u8 * buf, t_u8 * chan_list, t_u8 num_of_chan,
+                      t_u8 reg_class, t_u8 is_intol_ap_present)
+{
+    HostCmd_DS_GEN *hostcmd;
+    MrvlIETypes_2040COEX_t *coex_ie = NULL;
+    MrvlIETypes_2040BssIntolerantChannelReport_t *bss_intol_ie = NULL;
+    t_u8 *pos = NULL;
+    int intol;
+
+    memset(buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
+    hostcmd = (HostCmd_DS_GEN *) buf;
+    hostcmd->command = cpu_to_le16(HostCmd_CMD_11N_2040COEX);
+    hostcmd->size = S_DS_GEN;
+    pos = buf + S_DS_GEN;
+    {
+        coex_ie = (MrvlIETypes_2040COEX_t *) pos;
+        coex_ie->header.element_id = TLV_ID_2040COEX;
+        coex_ie->header.len = sizeof(coex_ie->coex_elem);
+        /* Check STA is 40 MHz intolerant or not */
+        is_intolerant_sta(&intol);
+        if (intol)
+            coex_ie->coex_elem |= MBIT(1);
+
+        if (is_intol_ap_present)
+            coex_ie->coex_elem |= MBIT(2);
+        pos += sizeof(MrvlIETypes_2040COEX_t);
+        hostcmd->size += sizeof(MrvlIETypes_2040COEX_t);
+    }
+    {
+        bss_intol_ie = (MrvlIETypes_2040BssIntolerantChannelReport_t *) pos;
+        bss_intol_ie->header.element_id = TLV_ID_2040BSS_INTOL_CHAN_REPORT;
+        hostcmd->size +=
+            sizeof(MrvlIETypes_2040BssIntolerantChannelReport_t) -
+            sizeof(bss_intol_ie->chan_num);
+        bss_intol_ie->reg_class = reg_class;
+        memcpy(bss_intol_ie->chan_num, chan_list, num_of_chan);
+        bss_intol_ie->header.len =
+            sizeof(bss_intol_ie->reg_class) + num_of_chan;
+        hostcmd->size += num_of_chan;
+    }
+    hostcmd->size = cpu_to_le16(hostcmd->size);
+    return;
+}
+
+/** 
+ *  @brief Invoke multiple 2040Coex commands for multiple regulatory classes
+ *
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+invoke_coex_command(void)
+{
+    int cur_reg_domain;
+    t_u8 chan_list[MAX_CHAN], is_intol_ap_present;
+    t_u8 num_of_chan;
+    int i, num_entry, ret = MLAN_STATUS_SUCCESS;
+    class_chan_t *cur_class_chan_table = NULL;
+
+        /** get region code */
+    ret = get_region_code(&cur_reg_domain);
+    if (ret != MLAN_STATUS_SUCCESS)
+        return ret;
+        /** Find region_class_chan_table for this region */
+    for (i = 0;
+         i < (sizeof(region_class_chan_table) / sizeof(region_class_chan_t));
+         i++) {
+        if (region_class_chan_table[i].reg_domain == cur_reg_domain) {
+            cur_class_chan_table = region_class_chan_table[i].class_chan_list;
+            num_entry = region_class_chan_table[i].num_class_chan_entry;
+            break;
+        }
+    }
+    if (cur_class_chan_table == NULL) {
+        printf("No region_class_chan table found for this region\n");
+        return MLAN_STATUS_FAILURE;
+    }
+
+    for (i = 0; i < num_entry; i++) {
+                /** Get channels for the specified regulatory class */
+        get_channels_for_specified_reg_class(cur_class_chan_table, num_entry,
+                                             chan_list, &num_of_chan,
+                                             cur_reg_domain,
+                                             cur_class_chan_table[i].reg_class,
+                                             &is_intol_ap_present);
+
+                /** If any channel found for this regulatory class, then invoke the 2040coex command */
+        if (num_of_chan > 0) {
+            ret = process_host_cmd(CMD_2040COEX, chan_list, num_of_chan,
+                                   cur_class_chan_table[i].reg_class,
+                                   is_intol_ap_present);
+            if (ret)
+                break;
+        }
+    }
+    return ret;
+}
+
+/** 
+ *  @brief Process host_cmd response
+ *  @param buf		A pointer to the response buffer
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+process_host_cmd_resp(t_u8 * buf)
+{
+    HostCmd_DS_GEN *hostcmd = (HostCmd_DS_GEN *) buf;
+    int ret = MLAN_STATUS_SUCCESS;
+
+    hostcmd->command = le16_to_cpu(hostcmd->command);
+    hostcmd->size = le16_to_cpu(hostcmd->size);
+
+    hostcmd->command &= ~HostCmd_RET_BIT;
+    if (!le16_to_cpu(hostcmd->result)) {
+        switch (hostcmd->command) {
+        }
+    } else {
+        printf("HOSTCMD failed: ReturnCode=%#04x, Result=%#04x\n",
+               le16_to_cpu(hostcmd->command), le16_to_cpu(hostcmd->result));
+        ret = MLAN_STATUS_FAILURE;
+    }
+    return ret;
+}
diff --git a/wlan_src/mapp/mlan2040coex/mlan2040misc.h b/wlan_src/mapp/mlan2040coex/mlan2040misc.h
new file mode 100755
index 0000000..a325c69
--- /dev/null
+++ b/wlan_src/mapp/mlan2040coex/mlan2040misc.h
@@ -0,0 +1,435 @@
+/** @file  mlan2040misc.h
+  *
+  * @brief This file contains command definitions for application
+  * 
+  *  Copyright (C) 2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+/************************************************************************
+Change log:
+     06/24/2009: initial version
+************************************************************************/
+#ifndef _COEX_MISC_H_
+#define _COEX_MISC_H_
+
+/** MLAN MAC Address Length */
+#define MLAN_MAC_ADDR_LENGTH     (6)
+/** Size of command buffer */
+#define MRVDRV_SIZE_OF_CMD_BUFFER       (2 * 1024)
+
+/** Command RET code, MSB is set to 1 */
+#define HostCmd_RET_BIT                 0x8000
+/** General purpose action : Get */
+#define HostCmd_ACT_GEN_GET             0x0000
+/** General purpose action : Set */
+#define HostCmd_ACT_GEN_SET             0x0001
+/** TLV Id for 2040Coex IE */
+#define TLV_ID_2040COEX                    0x48
+/** TLV Id for 2040BSS intolarent channel report IE */
+#define TLV_ID_2040BSS_INTOL_CHAN_REPORT   0x49
+/** Host-command for 2040coex command */
+#define HostCmd_CMD_11N_2040COEX           0x00e9
+/** Maximum scan response buffer size */
+#define SCAN_RESP_BUF_SIZE 2000
+
+/** Maximum length of SSID */
+#define MRVDRV_MAX_SSID_LENGTH          32
+
+/** Length of ethernet address */
+#ifndef ETH_ALEN
+#define ETH_ALEN            6
+#endif
+/** Maximum length of SSID list */
+#define MRVDRV_MAX_SSID_LIST_LENGTH         10
+/** Default scan interval in second*/
+#define DEFAULT_SCAN_INTERVAL 300
+
+/** BIT value */
+#define MBIT(x)    (((t_u32)1) << (x))
+
+/** Check intolerent bit set */
+#define IS_INTOL_BIT_SET(cap_info) (cap_info & MBIT(14))
+
+/** Check OBSS non-HT STAs present bit set */
+#define IS_NON_HT_STA_PRESENT(ht_info) (ht_info.field3 & MBIT(4))
+
+/** Custom event : OBSS scan parameter */
+#define CUS_EVT_OBSS_SCAN_PARAM   "EVENT=OBSS_SCAN_PARAM"
+
+/** IEEE Type definitions  */
+typedef enum _IEEEtypes_ElementId_e
+{
+    SSID = 0,
+    SUPPORTED_RATES = 1,
+    FH_PARAM_SET = 2,
+    DS_PARAM_SET = 3,
+    CF_PARAM_SET = 4,
+    IBSS_PARAM_SET = 6,
+    HT_CAPABILITY = 45,
+    HT_OPERATION = 61,
+    BSSCO_2040 = 72,
+    OVERLAPBSSSCANPARAM = 74,
+    EXT_CAPABILITY = 127,
+    ERP_INFO = 42,
+    EXTENDED_SUPPORTED_RATES = 50,
+    VENDOR_SPECIFIC_221 = 221,
+    WMM_IE = VENDOR_SPECIFIC_221,
+    RSN_IE = 48,
+} __attribute__ ((packed)) IEEEtypes_ElementId_e;
+
+/** HT Capabilities Data */
+typedef struct _HTCap_t
+{
+    /** HT Capabilities Info field */
+    t_u16 ht_cap_info;
+    /** A-MPDU Parameters field */
+    t_u8 ampdu_param;
+    /** Supported MCS Set field */
+    t_u8 supported_mcs_set[16];
+    /** HT Extended Capabilities field */
+    t_u16 ht_ext_cap;
+    /** Transmit Beamforming Capabilities field */
+    t_u32 tx_bf_cap;
+    /** Antenna Selection Capability field */
+    t_u8 asel;
+    /** Reserved set to 0 */
+    t_u16 reserved;
+} __attribute__ ((packed)) HTCap_t, *pHTCap_t;
+
+/** HT Information Data */
+typedef struct _HTInfo_t
+{
+    /** Primary channel */
+    t_u8 pri_chan;
+    /** Field 2 */
+    t_u8 field2;
+    /** Field 3 */
+    t_u16 field3;
+    /** Field 4 */
+    t_u16 field4;
+    /** Bitmap indicating MCSs supported by all HT STAs in the BSS */
+    t_u8 basic_mcs_set[16];
+    /** Reserved set to 0 */
+    t_u16 reserved;
+} __attribute__ ((packed)) HTInfo_t, *pHTInfo_t;
+
+/** 20/40 BSS Coexistence Data */
+typedef struct _BSSCo2040_t
+{
+    /** 20/40 BSS Coexistence value */
+    t_u8 bss_co_2040_value;
+    /** Reserve field */
+    t_u8 reserved[3];
+} __attribute__ ((packed)) BSSCo2040_t, *pBSSCo2040_t;
+
+/** Extended Capabilities Data */
+typedef struct _ExtCap_t
+{
+    /** Extended Capabilities value */
+    t_u8 ext_cap_value;
+    /** Reserved field */
+    t_u8 reserved[3];
+} __attribute__ ((packed)) ExtCap_t, *pExtCap_t;
+
+/** Overlapping BSS Scan Parameters Data */
+typedef struct _OverlapBSSScanParam_t
+{
+    /** OBSS Scan Passive Dwell */
+    t_u16 obss_scan_passive_dwell;
+    /** OBSS Scan Active Dwell */
+    t_u16 obss_scan_active_dwell;
+    /** BSS Channel Width Trigger Scan Interval */
+    t_u16 bss_chan_width_trigger_scan_int;
+    /** OBSS Scan Passive Total Per Channel */
+    t_u16 obss_scan_passive_total;
+    /** OBSS Scan Active Total Per Channel */
+    t_u16 obss_scan_active_total;
+    /** BSS Width Channel Transition Delay Factor */
+    t_u16 bss_width_chan_trans_delay;
+    /** OBSS Scan Activity Threshold */
+    t_u16 obss_scan_active_threshold;
+    /** Reserved Field */
+    t_u16 reserved;
+} __attribute__ ((packed)) OBSSScanParam_t, *pOBSSScanParam_t;
+
+/** IEEEtypes_CapInfo_t structure*/
+typedef struct _IEEEtypes_CapInfo_t
+{
+    /** Capability Bit Map : ESS */
+    t_u8 ess:1;
+    /** Capability Bit Map : IBSS */
+    t_u8 ibss:1;
+    /** Capability Bit Map : CF pollable */
+    t_u8 cf_pollable:1;
+    /** Capability Bit Map : CF poll request */
+    t_u8 cf_poll_rqst:1;
+    /** Capability Bit Map : privacy */
+    t_u8 privacy:1;
+    /** Capability Bit Map : Short preamble */
+    t_u8 short_preamble:1;
+    /** Capability Bit Map : PBCC */
+    t_u8 pbcc:1;
+    /** Capability Bit Map : Channel agility */
+    t_u8 chan_agility:1;
+    /** Capability Bit Map : Spectrum management */
+    t_u8 spectrum_mgmt:1;
+    /** Capability Bit Map : Reserved */
+    t_u8 rsrvd3:1;
+    /** Capability Bit Map : Short slot time */
+    t_u8 short_slot_time:1;
+    /** Capability Bit Map : APSD */
+    t_u8 apsd:1;
+    /** Capability Bit Map : Reserved */
+    t_u8 rsvrd2:1;
+    /** Capability Bit Map : DSS OFDM */
+    t_u8 dsss_ofdm:1;
+    /** Capability Bit Map : Reserved */
+    t_u8 rsrvd1:2;
+} __attribute__ ((packed)) IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t;
+
+typedef struct
+{
+    t_u8 chan_number;  /**< Channel Number to scan */
+    t_u8 radio_type;   /**< Radio type: 'B/G' Band = 0, 'A' Band = 1 */
+    t_u8 scan_type;    /**< Scan type: Active = 0, Passive = 1 */
+    t_u8 reserved;    /**< Reserved */
+    t_u32 scan_time;   /**< Scan duration in milliseconds; if 0 default used */
+} __attribute__ ((packed)) wlan_ioctl_user_scan_chan;
+
+typedef struct
+{
+    char ssid[MRVDRV_MAX_SSID_LENGTH + 1];  /**< SSID */
+    t_u8 max_len;                              /**< Maximum length of SSID */
+} __attribute__ ((packed)) wlan_ioctl_user_scan_ssid;
+
+typedef struct
+{
+
+    /** Flag set to keep the previous scan table intact */
+    t_u8 keep_previous_scan;    /* Do not erase the existing scan results */
+
+    /** BSS mode to be sent in the firmware command */
+    t_u8 bss_mode;
+
+    /** Configure the number of probe requests for active chan scans */
+    t_u8 num_probes;
+
+    /** Reserved */
+    t_u8 reserved;
+
+    /** BSSID filter sent in the firmware command to limit the results */
+    t_u8 specific_bssid[ETH_ALEN];
+    /** SSID filter list used in the to limit the scan results */
+    wlan_ioctl_user_scan_ssid ssid_list[MRVDRV_MAX_SSID_LIST_LENGTH];
+
+    /** Variable number (fixed maximum) of channels to scan up */
+    wlan_ioctl_user_scan_chan chan_list[WLAN_IOCTL_USER_SCAN_CHAN_MAX];
+
+} __attribute__ ((packed)) wlan_ioctl_user_scan_cfg;
+
+/** IEEE IE header */
+typedef struct _IEEEtypes_Header_t
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 len;
+} __attribute__ ((packed)) IEEEtypes_Header_t, *pIEEEtypes_Header_t;
+
+/** HT Capabilities IE */
+typedef struct _IEEEtypes_HTCap_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** HTCap struct */
+    HTCap_t ht_cap;
+} __attribute__ ((packed)) IEEEtypes_HTCap_t, *pIEEEtypes_HTCap_t;
+
+/** HT Information IE */
+typedef struct _IEEEtypes_HTInfo_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** HTInfo struct */
+    HTInfo_t ht_info;
+} __attribute__ ((packed)) IEEEtypes_HTInfo_t, *pIEEEtypes_HTInfo_t;
+
+/** 20/40 BSS Coexistence IE */
+typedef struct _IEEEtypes_2040BSSCo_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** BSSCo2040_t struct */
+    BSSCo2040_t bss_co_2040;
+} __attribute__ ((packed)) IEEEtypes_2040BSSCo_t, *pIEEEtypes_2040BSSCo_t;
+
+/** Extended Capabilities IE */
+typedef struct _IEEEtypes_ExtCap_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** ExtCap_t struct */
+    ExtCap_t ext_cap;
+} __attribute__ ((packed)) IEEEtypes_ExtCap_t, *pIEEEtypes_ExtCap_t;
+
+/** Overlapping BSS Scan Parameters IE */
+typedef struct _IEEEtypes_OverlapBSSScanParam_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** OBSSScanParam_t struct */
+    OBSSScanParam_t obss_scan_param;
+} __attribute__ ((packed)) IEEEtypes_OverlapBSSScanParam_t,
+    *pIEEEtypes_OverlapBSSScanParam_t;
+
+typedef struct _wlan_get_scan_table_fixed
+{
+    /** BSSID of this network */
+    t_u8 bssid[MLAN_MAC_ADDR_LENGTH];
+    /** Channel this beacon/probe response was detected */
+    t_u8 channel;
+    /** RSSI for the received packet */
+    t_u8 rssi;
+    /** TSF value from the firmware at packet reception */
+    t_u64 network_tsf;
+} wlan_get_scan_table_fixed;
+
+/**
+ *  Structure passed in the wlan_ioctl_get_scan_table_info for each
+ *    BSS returned in the WLAN_GET_SCAN_RESP IOCTL
+ */
+typedef struct _wlan_ioctl_get_scan_table_entry
+{
+    /**
+     *  Fixed field length included in the response.
+     *
+     *  Length value is included so future fixed fields can be added to the
+     *   response without breaking backwards compatibility.  Use the length
+     *   to find the offset for the bssInfoLength field, not a sizeof() calc.
+     */
+    t_u32 fixed_field_length;
+
+    /**
+     *  Always present, fixed length data fields for the BSS
+     */
+    wlan_get_scan_table_fixed fixed_fields;
+
+    /**
+     *  Length of the BSS Information (probe resp or beacon) that
+     *    follows starting at bssInfoBuffer
+     */
+    t_u32 bss_info_length;
+
+    /**
+     *  Probe response or beacon scanned for the BSS.
+     *
+     *  Field layout:
+     *   - TSF              8 octets
+     *   - Beacon Interval  2 octets
+     *   - Capability Info  2 octets
+     *
+     *   - IEEE Infomation Elements; variable number & length per 802.11 spec
+     */
+    t_u8 bss_info_buffer[1];
+} wlan_ioctl_get_scan_table_entry;
+
+/**
+ *  Sructure to retrieve the scan table
+ */
+typedef struct
+{
+    /**
+     *  - Zero based scan entry to start retrieval in command request
+     *  - Number of scans entries returned in command response
+     */
+    t_u32 scan_number;
+    /**
+     * Buffer marker for multiple wlan_ioctl_get_scan_table_entry structures.
+     *   Each struct is padded to the nearest 32 bit boundary.
+     */
+    t_u8 scan_table_entry_buf[1];
+} wlan_ioctl_get_scan_table_info;
+
+/* Define general hostcmd data structure */
+/** HostCmd_DS_GEN */
+typedef struct _HostCmd_DS_GEN
+{
+    /** Command */
+    t_u16 command;
+    /** Size */
+    t_u16 size;
+    /** Sequence number */
+    t_u16 seq_num;
+    /** Result */
+    t_u16 result;
+} __attribute__ ((packed)) HostCmd_DS_GEN;
+
+/** Size of HostCmd_DS_GEN */
+#define S_DS_GEN    sizeof(HostCmd_DS_GEN)
+
+/** TLV related data structures*/
+/** MrvlIEtypesHeader_t */
+typedef struct _MrvlIEtypesHeader
+{
+    /** Header type */
+    t_u16 type;
+    /** Header length */
+    t_u16 len;
+} __attribute__ ((packed)) MrvlIEtypesHeader_t;
+
+/** _MrvlIETypes_2040BssIntolerantChannelReport_t */
+typedef struct _MrvlIETypes_2040BssIntolerantChannelReport_t
+{
+    /** Header */
+    IEEEtypes_Header_t header;
+    /** regulatory class */
+    t_u8 reg_class;
+    /** channel numbers for legacy AP */
+    t_u8 chan_num[1];
+} __attribute__ ((packed)) MrvlIETypes_2040BssIntolerantChannelReport_t;
+
+/** MrvlIETypes_2040COEX_t */
+typedef struct _MrvlIETypes_2040COEX_t
+{
+    /** Header */
+    IEEEtypes_Header_t header;
+    /** 2040 coex element */
+    t_u8 coex_elem;
+} __attribute__ ((packed)) MrvlIETypes_2040COEX_t;
+
+typedef struct _HostCmd_DS_CMD_11N_2040COEX
+{
+        /** 2040 coex element */
+    MrvlIETypes_2040COEX_t coex;
+        /** 2040 BSS intolerant channel report*/
+    MrvlIETypes_2040BssIntolerantChannelReport_t chan_intol_report;
+} __attribute__ ((packed)) HostCmd_DS_CMD_11N_2040COEX;
+
+/** Maximum number of channel per regulatory class */
+#define MAX_CHAN 20
+typedef struct _class_chan_t
+{
+        /** Regulatory class */
+    t_u8 reg_class;
+        /** Channel numbers */
+    t_u8 channels[MAX_CHAN];
+        /** Total number of channels */
+    t_u8 total_chan;
+} class_chan_t;
+
+typedef struct _region_class_chan_t
+{
+    /** Regulatory domain */
+    int reg_domain;
+    /** Channel numbers */
+    class_chan_t *class_chan_list;
+    /** Number of class channel table entry */
+    int num_class_chan_entry;
+} region_class_chan_t;
+
+int process_host_cmd_resp(t_u8 * buf);
+void prepare_coex_cmd_buff(t_u8 * buf, t_u8 * chan_list, t_u8 num_of_chan,
+                           t_u8 reg_class, t_u8 is_intol_ap_present);
+int invoke_coex_command(void);
+
+#endif /* _COEX_MISC_H_ */
diff --git a/wlan_src/mapp/mlanconfig/Makefile b/wlan_src/mapp/mlanconfig/Makefile
new file mode 100755
index 0000000..73666f9
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/Makefile
@@ -0,0 +1,48 @@
+#
+# File : mlanconfig/Makefile
+#
+# Copyright (C) 2008-2009, Marvell International Ltd.
+# All Rights Reserved
+
+# Path to the top directory of the mlandriver distribution
+PATH_TO_TOP = ../..
+
+# Determine how we should copy things to the install directory
+ABSPATH := $(filter /%, $(INSTALLDIR))
+RELPATH := $(filter-out /%, $(INSTALLDIR))
+INSTALLPATH := $(ABSPATH)
+ifeq ($(strip $(INSTALLPATH)),)
+INSTALLPATH := $(PATH_TO_TOP)/$(RELPATH)
+endif
+
+# Override CFLAGS for application sources, remove __ kernel namespace defines
+CFLAGS := $(filter-out -D__%, $(EXTRA_CFLAGS))
+
+#
+# List of application executables to create
+#
+libobjs:= mlanconfig.o mlanhostcmd.o mlanmisc.o
+exectarget=mlanconfig
+TARGETS := $(exectarget)
+
+#
+# Make target rules
+#
+
+# All rule compiles list of TARGETS using builtin program target from src rule
+all :
+$(exectarget): $(libobjs)
+	$(CC) $(CFLAGS) $(libobjs) -o $(exectarget)
+
+# Update any needed TARGETS and then copy to the install path
+build install: $(TARGETS)
+	@cp -f $(exectarget) $(INSTALLPATH)
+	@cp -rf config $(INSTALLPATH)
+
+clean:
+	@rm -f $(exectarget)
+	@rm -f *.o
+
+distclean: clean
+	@rm -f *~ core
+	@rm -f tags
diff --git a/wlan_src/mapp/mlanconfig/config/11n_2040coex.conf b/wlan_src/mapp/mlanconfig/config/11n_2040coex.conf
new file mode 100755
index 0000000..1e8cda7
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/11n_2040coex.conf
@@ -0,0 +1,21 @@
+#	File : 11n_2040coex.conf
+
+######################### 20/40 Coex command ##################
+2040coex={
+    CmdCode=0x00e9  # do NOT change this line
+
+    2040CoexTlvType:1=0x48
+    2040CoexTlvLen:1={
+        2040CoexElement:1=0x04
+    }
+
+    2040BssIntlChanTlvType:1=0x49
+    2040BssIntlChanTlvLen:1={
+        RegulatoryDomain:1=32   # USA: 32 (1-7), 33 (5-11)
+        ChannelNum:1=1
+        ChannelNum:1=2
+        #  ...
+    }
+}
+
+##################################################################
diff --git a/wlan_src/mapp/mlanconfig/config/arpfilter.conf b/wlan_src/mapp/mlanconfig/config/arpfilter.conf
new file mode 100755
index 0000000..fe843af
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/arpfilter.conf
@@ -0,0 +1,29 @@
+#	File : arpfilter.conf
+
+######################### Host Sleep ARP/IP filtering command ##################
+# add arp filter
+# firmware supports 8 entries of ARP_FILTER. Each entry has 8 bytes.
+# must not exceed 8x8+4=68 bytes
+
+arpfilter={
+   TlvType:2=0x0115
+   TlvLength:2={
+      AddrType:2=3              # multicast
+      EthType:2=0xffff          # Any
+      Ipv4Addr:4=0xffffffff     # Any
+      AddrType:2=1              # broadcast
+      EthType:2=0x0608          # ARP: 0x0806
+      Ipv4Addr:4=0x6200a8c0     # 192.168.0.98
+      AddrType:2=2              # unicast
+      EthType:2=0xffff          # Any
+      Ipv4Addr:4=0xffffffff     # Any    
+    }
+}
+
+# remove arp filter
+#arpfilter={
+#	TlvType:2=0x0115
+#	TlvLength:2={
+#	}
+#}
+######################### Host Sleep ARP/IP filtering command ##################
diff --git a/wlan_src/mapp/mlanconfig/config/auto_tx.conf b/wlan_src/mapp/mlanconfig/config/auto_tx.conf
new file mode 100755
index 0000000..6c35540
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/auto_tx.conf
@@ -0,0 +1,54 @@
+#	File : auto_tx.conf
+
+######################### Auto-TX command ##################
+auto_tx_get={
+	CmdCode=0x0082	# do NOT change this line
+
+	Action:2=0		# GET
+}
+
+auto_tx_unreg={
+	CmdCode=0x0082	# do NOT change this line
+
+	Action:2=1		# SET
+}
+
+nat_keep_alive={
+	CmdCode=0x0082	# do NOT change this line
+
+	Action:2=1		# SET
+
+	AutoTxTlvType:2=0x0118
+	AutoTxTlvLength:2={		# 58 = 6 + 52 (FrameLen)
+		Interval:2=2		# 1 - 3600 seconds
+		Priority:1=7		# Priority, ignored if non-WMM
+		Reserved:1=0
+		FrameLength:2={		# 52 = 6 (DA) + 6 (SA) + 2 + 38 (Length)
+			DestMacAddr:6='0x00,0x40,0xf4,0xbf,0x24,0xee'
+			SrcMacAddr:6='0x00,0x00,0x00,0x00,0x00,0x00'
+			Length:2='0x00,38'	# 38 = 8 (SNAP hdr) + 29 (IP) + 1 (padding)
+			DSAP:1=0xaa			# SNAP header
+			SSAP:1=0xaa
+			Ctrl:1=0x03
+			SNAP_OUI:3='0x00,0x00,0x00'
+			SNAP_PID:2='0x08,0x00'		# IP Packet
+			IPv4:1=0x45
+			IP_TOS:1=0x00
+			IP_LEN:2='0x00,29'		# IP hdr 20 + payload 9 = 29
+			IP_ID:2=0xefbe
+			IP_Flag_FragOffset:2=0x0000
+			IP_TTL:1=128
+			IP_Prot:1=17		  		# UDP protocol
+			IPhdr_cksum:2=0xc5f9		# may need re-calculation if changed
+			IPsrcAddr:4='192,168,0,201'	# 192.168.0.201
+			IPdstAddr:4='192,168,0,1'	# 192.168.0.1
+			UDPsrcPort:2='0x11,0x94'	# 4500
+			UDPdstPort:2='0x11,0x94'	# 4500
+			UDPlength:2='0x00,9'		# UDP hdr 8 + payload 1 = 9
+			UDPcksum:2=0x985b			# may need re-calculation if changed
+			UDPpayload:1=0xff
+			padding:1=0					# MAC Padding for 32bit alignment, set to 0
+		}
+	}
+}
+######################### Auto-TX command ##################
diff --git a/wlan_src/mapp/mlanconfig/config/bg_scan.conf b/wlan_src/mapp/mlanconfig/config/bg_scan.conf
new file mode 100755
index 0000000..270c3cc
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/bg_scan.conf
@@ -0,0 +1,116 @@
+#	File : bg_scan.conf
+
+######################### BG Scan Configuration command ##################
+########### Sample configuration for Get BG Scan Configuration #####################
+#bgscfg={
+#	CmdCode=0x006b          # do NOT change this line
+#	Action:1=0              # 0- Get, 1- Set
+#	ConfigType:1=0          # 0- normal BG Scan config, 1-PPS or UAPSD BG Scan config	
+#	Enable:1=1              # 0- Disable, 1-Enable
+#	BssType:1=0             # 1 - Infrastructure,2 - IBSS,3 - Any
+#	ChannelsPerScan:1=0     # Number of Channel to scan at one scan; maximum 14
+#	Reserved1:3=0
+#	ScanInterval:4=0        # Interval between consecutive scan (in milliseconds)
+#	Reserved2:4=0
+#	ReportConditions:4=0    # bit0  - SSID match
+	                        # bit1  - SNR above SNR threshold
+	                        # bit2  - RSSI above RSSI threshold
+	                        # bit31 - All channels scanned at least once
+#	Reserved3:2=0
+#}
+
+########### SET BG Scan Configuration #####################
+bgscfg={
+	CmdCode=0x006b          # do NOT change this line
+	Action:1=1              # 0- Get, 1- Set
+	ConfigType:1=0          # 0- normal BG Scan config, 1-PPS or UAPSD BG Scan config	
+	Enable:1=1              # 0- Disable, 1-Enable
+	BssType:1=3             # 1 - Infrastructure,2 - IBSS,3 - Any
+	ChannelsPerScan:1=14    # Number of Channel to scan at one scan; maximum 14
+	Reserved1:3=0
+	ScanInterval:4=1000     # Interval between consecutive scan (in milliseconds)
+	Reserved2:4=0
+	ReportConditions:4=1  	# bit0  - SSID match
+	                      	# bit1  - SNR above SNR threshold
+	                      	# bit2  - RSSI above RSSI threshold
+	                      	# bit31 - All channels scanned at least once
+	Reserved3:2=0
+
+	# SSID entries:
+	#
+	# 1. SSID=""                - to denote NULL SSID, which is considered 
+	#                             as SSID with length 0.
+	# 2. SSID="AP_NAME"         - to mention a specific SSID to match.
+	# 3. SSID="AP_NAME",maxlen  - AP_NAME will be use to base match
+	#                             the SSID, and SSID's max length is max length
+
+	SSIDHeaderType:2=0x0112
+	SSIDHeaderLen:2={
+		MaxSSIDLen:1=0x00
+		SSID:9="MarvellAP"
+	}
+#	SSIDHeaderType:2=0x0112
+#	SSIDHeaderLen:2={
+#		MaxSSIDLen:1=0x00
+#		SSID:10="MarvellAP2"
+#	}
+
+	# Number Probe requests to be sent for broadcast and
+	# for each SSID specific scan required.
+	#
+	# Set to 0 to use global scan probes setting
+	#
+	ProbeHeaderType:2=0x0102
+	ProbeHeaderLen:2={
+		NumProbes:2=2
+	}
+
+	# ChannelList contains the channels to scan
+	# The ChannelList should be specified in the form of
+	#
+	#     RadioType, ChanNumber, ScanType, MinScanTime, ScanTime;
+	#
+	# RadioType - 0 [B/G Band], 1 [A Band]
+	# ScanType  - 2 [Active],   3 [Passive]
+	#
+
+	ChannHeaderType:2=0x0101
+	ChannHeaderLen:2={
+		Chan1_RadioType:1=0
+		Chan1_ChanNumber:1=10
+		Chan1_ScanType:1=2
+		Chan1_MinScanTime:2=10
+		Chan1_ScanTime:2=100
+		
+		Chan2_RadioType:1=0
+		Chan2_ChanNumber:1=6
+		Chan2_ScanType:1=3
+		Chan2_MinScanTime:2=10
+		Chan2_ScanTime:2=100
+	}
+
+	# SNR threshold used when ReportConditions bit1 is set
+	SNRHeaderType:2=0x0105
+	SNRHeaderLen:2={
+		SNRValue:1=40 	#SNR Thereshold Value
+		SNRFreq:1=0
+	}
+
+	# RSSI threshold used when ReportConditions bit2 is set
+	#   
+	# Threshold is absolute value and match value would 
+	#   therefore be less than or equal to trigger a report
+	RSSIHeaderType:2=0x0104
+	RSSIHeaderLen:2={
+		RSSIValue:1=50 	#RSSI Thereshold Value
+		RSSIFreq:1=0
+	}
+
+	# StartLaterValue: 0 - BGScan start immediately 
+	# 1 - BGScan will start later after "Scan Interval"
+	StartLaterHeaderType:2=0x011e
+	StartLaterHeaderLen:2={
+		StartLaterValue:2=0
+	}
+}
+######################### BG Scan Configuration command ##################
diff --git a/wlan_src/mapp/mlanconfig/config/cal_data.conf b/wlan_src/mapp/mlanconfig/config/cal_data.conf
new file mode 100755
index 0000000..e37f674
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/cal_data.conf
@@ -0,0 +1,42 @@
+01 00 0c 00 58 02
+00 40 68 0c 00 00 00 40 00 00 00 00 00 11 00 00
+00 11 00 10 00 00 00 00 00 00 00 00 00 00 00 00
+10 12 00 10 10 86 40 89 01 03 02 00 01 02 05 00
+01 03 05 00 17 17 00 05 00 00 00 00 00 00 00 00
+00 30 1f 11 00 00 00 70 00 00 00 00 13 00 1e 01
+00 1e 5e 15 29 5e 15 13 5c 1d 0d 0b 1d 0d 0b 29
+0d 0b 29 5c 0b 29 5c 1d 00 5c 1d 0d 00 00 00 00
+00 5c c0 0e 00 00 00 cc 00 5f 00 00 07 01 04 00
+00 00 0e 0d 00 00 00 00 00 00 00 00 00 00 00 ff
+00 00 00 01 00 00 00 00 00 00 00 ff 00 00 00 01
+00 00 00 00 00 00 00 ff 00 00 00 01 00 00 00 00
+00 00 00 ff 00 00 00 01 00 00 00 00 06 3c 06 3d
+00 00 00 00 00 00 00 00 00 00 00 00
+00 5c dc 25 00 00 01 28 00 6f 00 00 07 01 04 00
+00 00 0e 0d 00 00 00 00 00 00 00 00 00 08 00 07
+00 00 00 09 00 00 00 00 00 08 00 07 00 00 00 09
+00 00 00 00 00 08 00 07 00 00 00 09 00 00 00 00
+00 08 00 07 00 00 00 09 00 00 00 00 06 3c 06 3d
+00 00 00 00 00 00 00 00 00 00 00 00
+00 14 9f 1f 00 00 01 3c 03 00 00 00 00 f1 0a f1
+00 fb 0d fb
+00 20 dd 28 00 00 01 5c 08 86 00 88 ff 06 b1 05
+24 24 3c 42 00 00 24 18 a4 24 bc bc 3d 00 a0 8f
+00 14 00 2a 00 00 01 70 00 00 30 00 01 05 1b 00
+00 00 00 01
+00 74 2c 10 00 00 01 e4 00 00 00 00 09 6a 09 b0
+0b 12 00 6c 04 0a 00 6c 03 03 00 6c 03 03 00 6c
+3f ff ff 00 3f ff ff 01 3f ff ff 02 3f ff ff 03
+15 00 00 04 17 00 00 05 19 00 00 06 1b 00 00 07
+1d 00 00 08 1f 00 00 09 21 00 00 0a 23 00 00 0b
+25 00 00 0c 28 00 00 0d 2a 00 00 0e 2d 00 00 0f
+2f 00 00 10 32 00 00 11 34 00 00 12 3f ff ff 13
+3f ff ff 14
+00 74 84 10 ff ff ff ff 01 00 00 00 09 b0 09 ba
+0a 0f 00 6c 04 09 00 6c 03 03 00 6c 03 03 00 6c
+3f ff ff 00 3f ff ff 01 3f ff ff 02 3f ff ff 03
+15 00 00 04 17 00 00 05 1a 00 00 06 1c 00 00 07
+1f 00 00 08 21 00 00 09 23 00 00 0a 26 00 00 0b
+2a 00 00 0c 2d 00 00 0d 31 00 00 0e 34 00 00 0f
+3f ff ff 10 3f ff ff 11 3f ff ff 12 3f ff ff 13
+3f ff ff 14
diff --git a/wlan_src/mapp/mlanconfig/config/crypto_test.conf b/wlan_src/mapp/mlanconfig/config/crypto_test.conf
new file mode 100755
index 0000000..609366c
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/crypto_test.conf
@@ -0,0 +1,57 @@
+#	File : crypto_test.conf
+
+######################### crypto_test command configuration ##################
+
+crypto_test={					
+	CmdCode=0x0078          # do NOT change this line
+	#EncDec: 0-Decrypt, 1-Encrypt  
+	EncDec:2=0 		
+	#Algorithm: 1-RC4, 2-AES, 3-AES_KEY_WRAP  
+	Algorithm:2=1
+	#KeyIVLength: Length of KeyIV (bytes)  
+	KeyIVLength:2=8
+	#KeyIV: Key IV  
+	KeyIV:32='0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11'
+	#KeyLength: Length of Key (bytes)  
+	KeyLength:2=16
+	#Key: Key   
+	Key:32='0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22'
+	#DataType: DataType  
+	DataType:2=0x0111
+	#DataLength: Data Length  
+	DataLength:2={
+		#Data: Data   
+		Data:8='0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33'
+	}
+}
+
+#####Sample crypto_test command configuration for AES-CCM algorithm #########
+
+#crypto_test={					
+#	CmdCode=0x0078          # do NOT change this line
+#	#EncDec: 0-Decrypt, 1-Encrypt  
+#	EncDec:2=1 		
+#	#Algorithm: 4-AES-CCM  
+#	Algorithm:2=4
+#	#KeyLength: Length of Key (bytes)  
+#	KeyLength:2=16
+#	#Key: Key   
+#	Key:32='0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22'
+#	#NonceLength: Length of Nonce (bytes)  
+#	NonceLength:2=10
+#	#Nonce: Nonce   
+#	Nonce:14='0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11'
+#	#AADLength: Length of AAD (bytes)  
+#	AADLength:2=12
+#	#AAD: AAD   
+#	AAD:32='0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33'
+#	#DataType: DataType  
+#	DataType:2=0x0111
+#	#DataLength: Data Length  
+#	DataLength:2={
+#		#Data: Data   
+#		Data:8='0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33'
+#	}
+#}
+
+######################### End of crypto_test configuration command ##################
diff --git a/wlan_src/mapp/mlanconfig/config/mef.conf b/wlan_src/mapp/mlanconfig/config/mef.conf
new file mode 100755
index 0000000..873fce5
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/mef.conf
@@ -0,0 +1,136 @@
+#	File : mef.conf
+
+######################### MEF Configuration command ##################
+mefcfg={					
+	#Criteria: bit0-broadcast, bit1-unicast, bit3-multicast  
+	Criteria=2 		# Unicast frames are received during hostsleepmode 		
+	NumEntries=1		# Number of activated MEF entries
+	#mef_entry_0: example filters to match TCP destination port 80 send by 192.168.0.88 pkt or magic pkt.
+	mef_entry_0={
+		#mode: bit0--hostsleep mode, bit1--non hostsleep mode
+		mode=1		# HostSleep mode
+		#action: 0--discard and not wake host, 1--discard and wake host 3--allow and wake host
+		action=3	# Allow and Wake host	
+		filter_num=3    # Number of filter 
+		#RPN only support "&&" and "||" operator,space can not be removed between operator.
+		RPN=Filter_0 && Filter_1 || Filter_2	  
+		#Byte comparion filter's type is 0x41,Decimal comparion filter's type is 0x42,
+		#Bit comparion filter's type is  0x43
+		#Filter_0 is decimal comparion filter, it always with type=0x42
+		#Decimal filter always has type, pattern, offset, numbyte 4 field
+                #Filter_0 will match rx pkt with TCP destination port 80
+		Filter_0={
+			type=0x42	# decimal comparion filter
+			pattern=80	# 80 is the decimal constant to be compared
+			offset=44	# 44 is the byte offset of the field in RX pkt to be compare
+			numbyte=2       # 2 is the number of bytes of the field
+		}
+		#Filter_1 is Byte comparion filter, it always with type=0x41
+		#Byte filter always has type, byte, repeat, offset 4 filed
+		#Filter_1 will match rx pkt send by IP address 192.168.0.88
+		Filter_1={
+			type=0x41          	# Byte comparion filter
+			repeat=1                # 1 copies of 'c0:a8:00:58'
+			byte=c0:a8:00:58	# 'c0:a8:00:58' is the byte sequence constant with each byte  
+						# in hex format, with ':' as delimiter between two byte.
+			offset=34               # 34 is the byte offset of the equal length field of rx'd pkt.
+		}	
+		#Filter_2 is Magic packet, it will looking for 16 contiguous copies of '00:50:43:20:01:02' from
+		# the rx pkt's offset 14
+		Filter_2={
+			type=0x41		# Byte comparion filter
+			repeat=16               # 16 copies of '00:50:43:20:01:02'
+			byte=00:50:43:20:01:02  # '00:50:43:20:01:02' is the byte sequence constant
+			offset=14		# 14 is the byte offset of the equal length field of rx'd pkt.
+		}
+	}
+}
+
+
+#--------------------------examples for MEF filters-------------------------------- 
+#	example: filters to match ARP packet with protocol addr 192.168.0.104
+#	mef_entry_0={
+#		mode=1			# HostSleep mode
+#		action=3		# Allow and Wake host	
+#		filter_num=3		# Number of filter 
+#		RPN=Filter_0 && Filter_1 && Filter_2
+#		#Filter_0 looking for rx pkt with DA is broadcast address
+#		Filter_0={
+#			type=0x41
+#			repeat=6
+#			byte=ff
+#			offset=0
+#		}
+#		#Filter_1 looking for rx pkt with EtherType is 0x0806(ARP) 
+#		Filter_1={
+#			type=0x41
+#			repeat=1
+#			byte=08:06
+#			offset=20
+#		}	
+#		#Filter_2 looking for rx pkt with ARP target protocol addr 192.168.0.104 
+#		Filter_2={
+#			type=0x41
+#			repeat=1
+#			byte=c0:a8:00:68
+#			offset=46
+#		}
+#	}
+#-------------------------------------------------------------------------------------
+#	example: filter to check if the destination MAC address is unicast pkt
+#	mef_entry_0={
+#		mode=1			# HostSleep mode
+#		action=3		# Allow and Wake host	
+#		filter_num=3		# Number of filter 
+#		RPN=Filter_0
+#		#Filter_0 is Bit comparion filter, it always with type=0x43
+#		#Byte filter always has type, byte, mask, offset 4 filed 
+#		#"byte" is the byte sequence constant with each byte in hex format, with ':' as delimiter between two byte
+#		#"mask" is also with each byte in hex format, with ':' as delimiter between two byte
+#		#"byte" should has the same length as "mask"
+#		#Filter_0 will check if the destination MAC address is unicast pkt
+#		Filter_0={
+#			type=0x43	#Bit comparion filter
+#			byte=00		#00 is the 1-byte sequence constant
+#			offset=0        #0 is the byte offset of the rx pkt
+#			mask=01		#1 is the 1-byte mask        
+#		}
+#	}
+#--------------------------------------------------------------------------------------------------
+#	example: Disable MEF filters 
+#	mefcfg={					
+#		#Criteria: bit0-broadcast, bit1-unicast, bit3-multicast  
+#		Criteria=2 		# Unicast frames are received during hostsleepmode 		
+#		NumEntries=0		# Number of activated MEF entries
+#	}
+#--------------------------------------------------------------------------------------------------
+#	example: Test MEF filters
+#       mefcfg={
+#		Criteria=1
+#		NumEntries=1
+#		mef_entry_0={
+#			mode=4         # Test Mode
+#			action=16      # Invoke Test 		
+#			filter_num=0
+#		}
+#	}
+#-----------------------------------------------------------------------------------------------------
+#	example: Test MEF filters
+#       mefcfg={
+#		Criteria=1
+#		NumEntries=1
+#		mef_entry_0={
+#			mode=4
+#			action=0	
+#			filter_num=1
+#			RPN=Filter_0
+#			Filter_0={
+#				type=0x44		# test filter
+#				repeat=2                # 2 copies of 'BE:EF'
+#				byte=BE:EF		# 'BE:EF' is the byte sequence constant
+#				offset=18		# 18 is the byte offset of the equal length field of rx'd pkt.
+#				dest=00:50:43:20:5a:82  # '00:50:43:20:5a:82' is the byte sequence constant		
+#			}
+#		}
+#	}
+#----------------------------------------------------------------------------------------------------
diff --git a/wlan_src/mapp/mlanconfig/config/or_data.conf b/wlan_src/mapp/mlanconfig/config/or_data.conf
new file mode 100755
index 0000000..bf12214
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/or_data.conf
@@ -0,0 +1,7 @@
+ 07 01 03 3A 80 00 3A 00 ff ff 00 17 03 00 07 03 
+ 09 00 0e 10 16 02 19 25 1a 04 1c ff 32 5e 33 15
+ 35 29 36 17 4b 74 4c 64 4d 3b 50 27 61 d6 62 98
+ 6b ae 6f 5b 77 f2 79 ff 7f 2d
+ 07 01 12 16 c0 00 ff ff ff ff 00 05 03 10 32 5c 
+ 33 1a 6b a2 7f 20
+
diff --git a/wlan_src/mapp/mlanconfig/config/pmic_data.conf b/wlan_src/mapp/mlanconfig/config/pmic_data.conf
new file mode 100755
index 0000000..3a2b528
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/pmic_data.conf
@@ -0,0 +1,6 @@
+08 86 00 88 
+ff 06 b1 05 
+24 24 3c 42 
+00 00 24 18 
+a4 24 bc bc 
+3d 00 a0 8f
diff --git a/wlan_src/mapp/mlanconfig/config/requesttpc.conf b/wlan_src/mapp/mlanconfig/config/requesttpc.conf
new file mode 100755
index 0000000..159829b
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/requesttpc.conf
@@ -0,0 +1,15 @@
+#	File : requesttpc.conf
+
+######################### requesttpc command configuration ##################
+
+requesttpc={					
+	CmdCode=0x0060  # do NOT change this line
+	#DestMac: Destination STA address  
+	DestMac:6='0x02,0x04,0x0e,0x06,0x01,0x12'
+	#RateIndex: IEEE Rate index to send request   
+	RateIndex:1=22
+	#Timeout: Response timeout in ms  
+	Timeout:2=10
+}
+
+######################### End of requesttpc command configuration ##################
diff --git a/wlan_src/mapp/mlanconfig/config/robust_btc.conf b/wlan_src/mapp/mlanconfig/config/robust_btc.conf
new file mode 100755
index 0000000..823e530
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/robust_btc.conf
@@ -0,0 +1,63 @@
+#	File : robust_btc.conf
+
+######################### Robust Coex command ###############
+robust_btc_get={
+	CmdCode=0x00e0		# do NOT change this line
+
+	Action:2=0			# GET
+	RSVD:2=0
+
+	# Robust Coex Mode TLV
+	RobustCoexTlvType:2=0x0160
+	RobustCoexTlvLength:2={
+		Enable:1=0x00		# Enable Robust Coex Mode
+		Reserved:3=0
+	}
+
+	# Robust Coex Period TLV
+	RobustCoexPeriodTlvType:2=0x0161
+	RobustCoexPeriodTlvLength:2={
+		Mode:2=0x0000		# Strict to time mode. So, 0
+		Reserved:2=0
+		BTTime:4=0		# Length of time to give to BT in uSeconds
+		Period:4=0		# Length of the period in uSeconds
+	}
+}
+
+robust_btc_enable={
+	CmdCode=0x00e0		# do NOT change this line
+
+	Action:2=1			# SET
+	RSVD:2=0
+
+	# Robust Coex Mode TLV
+	RobustCoexTlvType:2=0x0160
+	RobustCoexTlvLength:2={
+		Enable:1=0x01		# Enable Robust Coex Mode
+		Reserved:3=0
+	}
+
+	# Robust Coex Period TLV
+	RobustCoexPeriodTlvType:2=0x0161
+	RobustCoexPeriodTlvLength:2={
+		Mode:2=0x0000		# Strict to time mode. So, 0
+		Reserved:2=0
+		BTTime:4=14000		# Length of time to give to BT in uSeconds
+		Period:4=20000		# Length of the period in uSeconds
+	}
+}
+
+robust_btc_disable={
+	CmdCode=0x00e0		# do NOT change this line
+
+	Action:2=1			# SET
+	RSVD:2=0
+
+	# Robust Coex Mode TLV
+	RobustCoexTlvType:2=0x0160
+	RobustCoexTlvLength:2={
+		Enable:1=0x00		# Disable Robust Coex Mode
+		Reserved:3=0
+	}
+}
+######################### Robust Coex command ###############
diff --git a/wlan_src/mapp/mlanconfig/config/subevent.conf b/wlan_src/mapp/mlanconfig/config/subevent.conf
new file mode 100755
index 0000000..cd56149
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/subevent.conf
@@ -0,0 +1,97 @@
+#	File : subevent.conf
+
+######################### Subscribe Events command ##################
+subevent_get={
+	CmdCode=0x0075	# do NOT change this line
+
+	Action:2=0		# GET
+	Events:2=0
+}
+
+subevent_set={
+	CmdCode=0x0075	# do NOT change this line
+
+	Action:2=1		# SET
+	Events:2=0xbc8	# bit0 - Beacon RSSI_LOW; bit1 - Beacon SNR_LOW
+					# bit2 - FAILED_COUNT; bit3 - Beacon Missed
+					# bit4 - Beacon RSSI_HIGH; bit5 - Beacon SNR_HIGH
+					# bit6 - Data RSSI_LOW; bit7 - Data SNR_LOW
+					# bit8 - Data RSSI_HIGH; bit9 - Data SNR_HIGH
+					# bit10 - LINK_QUALITY; bit11 - PRE_BCN_LOST
+					# bit12-15 reserved
+
+	LowRssiTlvType:2=0x0104
+	LowRssiTlvLength:2={
+		Threshold:1=70
+		ReportingFreq:1=0
+	}
+
+	LowSnrTlvType:2=0x0105
+	LowSnrTlvLength:2={
+		Threshold:1=56
+		ReportingFreq:1=0
+	}
+
+	FailedCountTlvType:2=0x0106
+	FailedCountTlvLength:2={
+		Threshold:1=5
+		ReportingFreq:1=0
+	}
+
+	BeaconMissTlvType:2=0x0107
+	BeaconMissTlvLength:2={
+		BeaconMissed:1=60
+		Reserved:1=0
+	}
+
+	HighRssiTlvType:2=0x0116
+	HighRssiTlvLength:2={
+		Threshold:1=40
+		ReportingFreq:1=0
+	}
+
+	HighSnrTlvType:2=0x0117
+	HighSnrTlvLength:2={
+		Threshold:1=86
+		ReportingFreq:1=0
+	}
+
+	DataLowRssiTlvType:2=0x0126
+	DataLowRssiTlvLength:2={
+		Threshold:1=10
+		ReportingFreq:1=0
+	}
+
+	DataLowSnrTlvType:2=0x0127
+	DataLowSnrTlvLength:2={
+		Threshold:1=66
+		ReportingFreq:1=0
+	}
+
+	DataHighRssiTlvType:2=0x0128
+	DataHighRssiTlvLength:2={
+		Threshold:1=50
+		ReportingFreq:1=0
+	}
+
+	DataHighSnrTlvType:2=0x0129
+	DataHighSnrTlvLength:2={
+		Threshold:1=96
+		ReportingFreq:1=1
+	}
+	LinkQualityTlvType:2=0x0124
+	LinkQualityTlvType:2={
+		LinkSNRThreshold:2=0x0056
+		LinkSNRFrequency:2=0x0003
+		MinRateVal:2=0x0014
+		MinRateFreq:2=0x0003
+		TxLatencyVal:4=0x00C8
+		TxLatencyThreshold:4=0x0003
+	}
+	PreBcnLostTlvType:2=0x0149
+	PreBcnLostTlvLength:2={
+		PreBeaconCnt:1=30
+		Reserved:1=0
+	}
+}
+######################### Subscribe Events command ##################
diff --git a/wlan_src/mapp/mlanconfig/config/tspecs.conf b/wlan_src/mapp/mlanconfig/config/tspecs.conf
new file mode 100755
index 0000000..92c1f9d
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/tspecs.conf
@@ -0,0 +1,99 @@
+# TSPEC contents for TID=0, UserPriority = 6
+[tspec0]
+# Element ID
+dd 
+# Length
+3d 
+# OUI
+00 50 f2 
+# OUI Type
+02 
+# OUI SubType
+02 
+# Version
+01 
+# TSInfo
+e0 34 00 
+# Nominal MSDU Size
+d0 80 
+# Maximum MSDU Size
+d0 00 
+# Min Service Interval
+20 4e 00 00 
+# Max Service Interval
+20 4e 00 00 
+# Inactivity Interval
+80 96 98 00 
+# Suspension Interval
+ff ff ff ff 
+# Service Start Time
+00 00 00 00 
+# Minimum Data Rate
+00 45 01 00 
+# Mean Data Rate
+00 45 01 00 
+# Peak Data Rate
+00 45 01 00 
+# Max Burst Size
+00 00 00 00 
+# Delay Bound
+00 00 00 00 
+# Min PHY Rate
+00 1b b7 00 
+# Surplus Bandwidth Allowance
+00 30 
+# Medium Time
+00 00 
+# Extra Data Bytes
+[/tspec0]
+
+
+# TSPEC contents for TID=1, UserPriority = 4
+[tspec1]
+# Element ID
+dd 
+# Length
+3d 
+# OUI
+00 50 f2 
+# OUI Type
+02 
+# OUI SubType
+02 
+# Version
+01 
+# TSInfo
+e3 20 00 
+# Nominal MSDU Size
+96 00 
+# Maximum MSDU Size
+dc 05 
+# Min Service Interval
+00 00 00 00 
+# Max Service Interval
+00 00 00 00 
+# Inactivity Interval
+00 00 00 00 
+# Suspension Interval
+ff ff ff ff 
+# Service Start Time
+00 00 00 00 
+# Minimum Data Rate
+a0 00 00 00 
+# Mean Data Rate
+a0 00 00 00 
+# Peak Data Rate
+a0 00 00 00 
+# Max Burst Size
+00 00 00 00 
+# Delay Bound
+00 00 00 00 
+# Min PHY Rate
+80 8d 5b 00 
+# Surplus Bandwidth Allowance
+00 30 
+# Medium Time
+00 00 
+# Extra Data Bytes
+[/tspec1]
+
diff --git a/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg.conf b/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg.conf
new file mode 100755
index 0000000..f72aa66
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/txpwrlimit_cfg.conf
@@ -0,0 +1,331 @@
+#	File : txpwrlimit_cfg.conf
+
+## Get CFG data for Tx power limitation
+txpwrlimit_cfg_get={
+	CmdCode=0x008f		# do NOT change this line
+	Action:2=0    		# 0 - GET
+	Type:2=4      		# do NOT change this line
+
+	CfgLen:2={
+	}
+}
+
+## Set CFG data for Tx power limitation
+txpwrlimit_cfg_set={
+	CmdCode=0x008f		# do NOT change this line
+	Action:2=1    		# 1 - SET
+	Type:2=4      		# do NOT change this line
+
+	CfgLen:2={
+               # Channel 1 Tx Power Limit
+               ch1.channel:1=1                  # Channel 1
+
+               ch1.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch1.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch1.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch1.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch1.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch1.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch1.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch1.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch1.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch1.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch1.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch1.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch1.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch1.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch1.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 2 Tx Power Limit
+               ch2.channel:1=2                  # Channel 2
+
+               ch2.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch2.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch2.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch2.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch2.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch2.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch2.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch2.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch2.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch2.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch2.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch2.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch2.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch2.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch2.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 3 Tx Power Limit
+               ch3.channel:1=3                  # Channel 3
+
+               ch3.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch3.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch3.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch3.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch3.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch3.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch3.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch3.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch3.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch3.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch3.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch3.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch3.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch3.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch3.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 4 Tx Power Limit
+               ch4.channel:1=4                  # Channel 4
+
+               ch4.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch4.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch4.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch4.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch4.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch4.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch4.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch4.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch4.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch4.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch4.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch4.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch4.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch4.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch4.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 5 Tx Power Limit
+               ch5.channel:1=5                  # Channel 5
+
+               ch5.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch5.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch5.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch5.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch5.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch5.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch5.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch5.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch5.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch5.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch5.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch5.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch5.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch5.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch5.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 6 Tx Power Limit
+               ch6.channel:1=6                  # Channel 6
+
+               ch6.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch6.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch6.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch6.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch6.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch6.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch6.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch6.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch6.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch6.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch6.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch6.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch6.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch6.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch6.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 7 Tx Power Limit
+               ch7.channel:1=7                  # Channel 7
+
+               ch7.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch7.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch7.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch7.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch7.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch7.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch7.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch7.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch7.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch7.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch7.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch7.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch7.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch7.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch7.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+
+               # Channel 8 Tx Power Limit
+               ch8.channel:1=8                  # Channel 8
+
+               ch8.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch8.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch8.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch8.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch8.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch8.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch8.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch8.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch8.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch8.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch8.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch8.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch8.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch8.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch8.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 9 Tx Power Limit
+               ch9.channel:1=9                  # Channel 9
+
+               ch9.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch9.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch9.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch9.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch9.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch9.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch9.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch9.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch9.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch9.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch9.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch9.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch9.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch9.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch9.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 10 Tx Power Limit
+               ch10.channel:1=10                 # Channel 10
+
+               ch10.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch10.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch10.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch10.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch10.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch10.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch10.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch10.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch10.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch10.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch10.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch10.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch10.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch10.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch10.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 11 Tx Power Limit
+               ch11.channel:1=11                 # Channel 11
+
+               ch11.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch11.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch11.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch11.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch11.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch11.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch11.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch11.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch11.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch11.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch11.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch11.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch11.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch11.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch11.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 12 Tx Power Limit
+               ch12.channel:1=12                 # Channel 12
+
+               ch12.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch12.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch12.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch12.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch12.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch12.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch12.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch12.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch12.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch12.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch12.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch12.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch12.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch12.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch12.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 13 Tx Power Limit
+               ch13.channel:1=13                 # Channel 13
+
+               ch13.pwr_limit_11b_cck:1=16       # DSSS 11, 5.5 Mbps
+               ch13.pwr_limit_11b_qpsk:1=16      # DSSS 2 Mbps
+               ch13.pwr_limit_11b_bpsk:1=16      # DSSS 1 Mbps
+
+               ch13.pwr_limit_11g_qam64:1=15     # OFDM 48, 54 Mbps
+               ch13.pwr_limit_11g_qam16:1=16     # OFDM 24, 36 Mbps
+               ch13.pwr_limit_11g_qpsk:1=16      # OFDM 12, 18 Mbps
+               ch13.pwr_limit_11g_bpsk:1=16      # OFDM 6, 9 Mbps
+
+               ch13.pwr_limit_ht_bw20_qam64:1=15 # HTBW20 MCS 5, 6, 7 
+               ch13.pwr_limit_ht_bw20_qam16:1=16 # HTBW20 MCS 3, 4 
+               ch13.pwr_limit_ht_bw20_qpsk:1=16  # HTBW20 MCS 1, 2 
+               ch13.pwr_limit_ht_bw20_bpsk:1=16  # HTBW20 MCS 0 
+
+               ch13.pwr_limit_ht_bw40_qam64:1=15 # HTBW40 MCS 5, 6, 7 
+               ch13.pwr_limit_ht_bw40_qam16:1=16 # HTBW40 MCS 3, 4 
+               ch13.pwr_limit_ht_bw40_qpsk:1=16  # HTBW40 MCS 1, 2 
+               ch13.pwr_limit_ht_bw40_bpsk:1=16  # HTBW40 MCS 0, 32
+
+               # Channel 14 Tx Power Limit
+               ch14.channel:1=14                 # Channel 14
+
+               ch14.pwr_limit_11b_cck:1=12       # DSSS 11, 5.5 Mbps
+               ch14.pwr_limit_11b_qpsk:1=12      # DSSS 2 Mbps
+               ch14.pwr_limit_11b_bpsk:1=12      # DSSS 1 Mbps
+
+               ch14.pwr_limit_11g_qam64:1=12     # OFDM 48, 54 Mbps
+               ch14.pwr_limit_11g_qam16:1=12     # OFDM 24, 36 Mbps
+               ch14.pwr_limit_11g_qpsk:1=12      # OFDM 12, 18 Mbps
+               ch14.pwr_limit_11g_bpsk:1=12      # OFDM 6, 9 Mbps
+
+               ch14.pwr_limit_ht_bw20_qam64:1=12 # HTBW20 MCS 5, 6, 7 
+               ch14.pwr_limit_ht_bw20_qam16:1=12 # HTBW20 MCS 3, 4 
+               ch14.pwr_limit_ht_bw20_qpsk:1=12  # HTBW20 MCS 1, 2 
+               ch14.pwr_limit_ht_bw20_bpsk:1=12  # HTBW20 MCS 0 
+
+               ch14.pwr_limit_ht_bw40_qam64:1=12 # HTBW40 MCS 5, 6, 7 
+               ch14.pwr_limit_ht_bw40_qam16:1=12 # HTBW40 MCS 3, 4 
+               ch14.pwr_limit_ht_bw40_qpsk:1=12  # HTBW40 MCS 1, 2 
+               ch14.pwr_limit_ht_bw40_bpsk:1=12  # HTBW40 MCS 0, 32
+
+	}
+}
+
diff --git a/wlan_src/mapp/mlanconfig/config/txrate_cfg.conf b/wlan_src/mapp/mlanconfig/config/txrate_cfg.conf
new file mode 100755
index 0000000..17b0ae0
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/config/txrate_cfg.conf
@@ -0,0 +1,126 @@
+#	File : txrate_cfg.conf
+
+## Tx Rate Configuration command
+txrate_cfg_get={
+	CmdCode=0x00d6		# do NOT change this line
+        Action:2=0              # 0 - GET
+        Index:2=0               # do NOT change this line
+
+	TxRateScope.TlvType:2=0x0153
+	TxRateScope.TlvLength:2={
+	}
+}
+
+txrate_cfg_set_bg={
+	CmdCode=0x00d6		# do NOT change this line
+
+	Action:2=1		# 1 - SET
+	Index:2=0		# do NOT change this line
+
+	TxRateScope.TlvType:2=0x0153
+	TxRateScope.TlvLength:2={
+                      ################# TXRATE SCOPE ######################
+ 
+                                # The following table shows the bitmap of the rates:
+                                # (bit 0 is the least significant bit)
+                                #       Bit     Data rate
+                                #       0       1 Mbps
+                                #       1       2 Mbps
+                                #       2       5.5 Mbps
+                                #       3       11 Mbps
+                                #       4       Reserved 
+                HRDSSS.RateScope:2=0x0000
+
+                                # The following table shows the bitmap of the rates:
+                                # (bit 0 is the least significant bit)
+                                #       Bit     Data rate
+                                #       0       6 Mbps
+                                #       1       9 Mbps
+                                #       2       12 Mbps
+                                #       3       18 Mbps
+                                #       4       24 Mbps
+                                #       5       36 Mbps
+                                #       6       48 Mbps
+                                #       7       54 Mbps
+                OFDM.RateScope:2=0x0080
+                
+                                # The following table shows the bitmap of the rates:
+                                # (bit 0 is the least significant bit)
+                                #       Bit     Data rate
+                                #       0       MCS0 
+                                #       1       MCS1
+                                #       2       MCS2
+                                #       3       MCS3
+                                #       4       MCS4
+                                #       5       MCS5
+                                #       6       MCS6
+                                #       7       MCS7
+                                #       32      MCS32
+                HT.RateScopeDword0:4=0x00000000
+                HT.RateScopeDword1:4=0x00000000
+                HT.RateScopeDword2:4=0x00000000
+                HT.RateScopeDword3:4=0x00000000
+	}
+
+        TxRateDrop.TlvType:2=0x0151
+        TxRateDrop.TlvLength:2={
+                RateDrop.Mode:4=0x00000001
+        }
+}
+
+txrate_cfg_set_bgn={
+	CmdCode=0x00d6		# do NOT change this line
+
+	Action:2=1		# 1 - SET
+	Index:2=0		# do NOT change this line
+
+	TxRateScope.TlvType:2=0x0153
+	TxRateScope.TlvLength:2={
+                      ################# TXRATE SCOPE ######################
+ 
+                                # The following table shows the bitmap of the rates:
+                                # (bit 0 is the least significant bit)
+                                #       Bit     Data rate
+                                #       0       1 Mbps
+                                #       1       2 Mbps
+                                #       2       5.5 Mbps
+                                #       3       11 Mbps
+                                #       4       Reserved 
+                HRDSSS.RateScope:2=0x0000
+
+                                # The following table shows the bitmap of the rates:
+                                # (bit 0 is the least significant bit)
+                                #       Bit     Data rate
+                                #       0       6 Mbps
+                                #       1       9 Mbps
+                                #       2       12 Mbps
+                                #       3       18 Mbps
+                                #       4       24 Mbps
+                                #       5       36 Mbps
+                                #       6       48 Mbps
+                                #       7       54 Mbps
+                OFDM.RateScope:2=0x0000
+                
+                                # The following table shows the bitmap of the rates:
+                                # (bit 0 is the least significant bit)
+                                #       Bit     Data rate
+                                #       0       MCS0 
+                                #       1       MCS1
+                                #       2       MCS2
+                                #       3       MCS3
+                                #       4       MCS4
+                                #       5       MCS5
+                                #       6       MCS6
+                                #       7       MCS7
+                                #       32      MCS32
+                HT.RateScopeDword0:4=0x00000080
+                HT.RateScopeDword1:4=0x00000000
+                HT.RateScopeDword2:4=0x00000000
+                HT.RateScopeDword3:4=0x00000000
+	}
+
+        TxRateDrop.TlvType:2=0x0151
+        TxRateDrop.TlvLength:2={
+                RateDrop.Mode:4=0x00000001
+        }
+}
diff --git a/wlan_src/mapp/mlanconfig/mlanconfig.c b/wlan_src/mapp/mlanconfig/mlanconfig.c
new file mode 100755
index 0000000..a4f8abf
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/mlanconfig.c
@@ -0,0 +1,2268 @@
+/** @file  mlanconfig.c
+  *
+  * @brief Program to configure addition parameters into the mlandriver
+  * 
+  *  Usage: mlanconfig mlanX cmd [...] 
+  *
+  *  Copyright (C) 2008-2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+/************************************************************************
+Change log:
+     11/26/2008: initial version
+     03/10/2009:  add setuserscan, getscantable etc. commands
+     08/11/2009:  add addts, regclass, setra, scanagent etc. commands
+************************************************************************/
+
+#include    "mlanconfig.h"
+#include    "mlanhostcmd.h"
+#include    "mlanmisc.h"
+
+/** mlanconfig version number */
+#define MLANCONFIG_VER "M1.3"
+
+/** Initial number of total private ioctl calls */
+#define IW_INIT_PRIV_NUM    128
+/** Maximum number of total private ioctl calls supported */
+#define IW_MAX_PRIV_NUM     1024
+
+/********************************************************
+		Local Variables
+********************************************************/
+
+/** Private ioctl commands */
+enum COMMANDS
+{
+    CMD_HOSTCMD,
+    CMD_MEFCFG,
+    CMD_ARPFILTER,
+    CMD_CFG_DATA,
+    CMD_CMD52RW,
+    CMD_CMD53RW,
+    CMD_GET_SCAN_RSP,
+    CMD_SET_USER_SCAN,
+    CMD_ADD_TS,
+    CMD_DEL_TS,
+    CMD_QCONFIG,
+    CMD_QSTATS,
+    CMD_TS_STATUS,
+    CMD_WMM_QSTATUS,
+    CMD_REGRW,
+};
+
+static t_s8 *commands[] = {
+    "hostcmd",
+    "mefcfg",
+    "arpfilter",
+    "cfgdata",
+    "sdcmd52rw",
+    "sdcmd53rw",
+    "getscantable",
+    "setuserscan",
+    "addts",
+    "delts",
+    "qconfig",
+    "qstats",
+    "ts_status",
+    "qstatus",
+    "regrdwr",
+};
+
+static t_s8 *usage[] = {
+    "Usage: ",
+    "   mlanconfig -v  (version)",
+    "   mlanconfig <mlanX> <cmd> [...]",
+    "   where",
+    "   mlanX : wireless network interface",
+    "   cmd : hostcmd",
+    "       : mefcfg",
+    "       : arpfilter",
+    "       : cfgdata",
+    "       : sdcmd52rw, sdcmd53rw",
+    "       : getscantable, setuserscan",
+    "       : addts, delts, qconfig, qstats, ts_status, qstatus",
+    "       : regrdwr",
+    "       : additional parameter for hostcmd",
+    "       :   <filename> <cmd>",
+    " 	    : additional parameters for mefcfg are:",
+    "       :   <filename>",
+    "       : additional parameter for arpfilter",
+    "       :   <filename>",
+    "       : additional parameter for cfgdata",
+    "       :   <type> <filename>",
+    "       : additional parameter for sdcmd52rw",
+    "       :   <function> <reg addr.> <data>",
+    "       : additional parameter for sdcmd53rw",
+    "       :   <func> <addr> <mode> <blksiz> <blknum> <data1> ... ...<dataN> ",
+    "       : additional parameter for addts",
+    "       :   <filename.conf> <section# of tspec> <timeout in ms>",
+    "       : additional parameter for delts",
+    "       :   <filename.conf> <section# of tspec>",
+    "       : additional parameter for qconfig",
+    "       :   <[set msdu <lifetime in TUs> [Queue Id: 0-3]]",
+    "       :    [get [Queue Id: 0-3]] [def [Queue Id: 0-3]]>",
+    "       : additional parameter for qstats",
+    "       :   <[on [Queue Id: 0-3]] [off [Queue Id: 0-3]] [get [Queue Id: 0-3]]>",
+    "       : additional parameter for regrdwr",
+    "       :   <type> <offset> [value]",
+};
+
+static FILE *fp; /**< socket */
+t_s32 sockfd;  /**< socket */
+t_s8 dev_name[IFNAMSIZ + 1];    /**< device name */
+static struct iw_priv_args *priv_args = NULL;      /**< private args */
+static int we_version_compiled = 0;
+                                  /**< version compiled */
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/********************************************************
+		Local Functions
+********************************************************/
+/** 
+ *  @brief Get private info.
+ *   
+ *  @param ifname   A pointer to net name
+ *  @return 	    MLAN_STATUS_SUCCESS--success, otherwise --fail
+ */
+static int
+get_private_info(const t_s8 * ifname)
+{
+    /* This function sends the SIOCGIWPRIV command, which is handled by the
+       kernel and gets the total number of private ioctl's available in the
+       host driver. */
+    struct iwreq iwr;
+    int s, ret = MLAN_STATUS_SUCCESS;
+    struct iw_priv_args *ppriv = NULL;
+    struct iw_priv_args *new_priv;
+    int result = 0;
+    size_t size = IW_INIT_PRIV_NUM;
+
+    s = socket(PF_INET, SOCK_DGRAM, 0);
+    if (s < 0) {
+        perror("socket[PF_INET,SOCK_DGRAM]");
+        return MLAN_STATUS_FAILURE;
+    }
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, ifname, IFNAMSIZ);
+
+    do {
+        /* (Re)allocate the buffer */
+        new_priv = realloc(ppriv, size * sizeof(ppriv[0]));
+        if (new_priv == NULL) {
+            printf("Error: Buffer allocation failed\n");
+            ret = MLAN_STATUS_FAILURE;
+            break;
+        }
+        ppriv = new_priv;
+
+        iwr.u.data.pointer = (caddr_t) ppriv;
+        iwr.u.data.length = size;
+        iwr.u.data.flags = 0;
+
+        if (ioctl(s, SIOCGIWPRIV, &iwr) < 0) {
+            result = errno;
+            ret = MLAN_STATUS_FAILURE;
+            if (result == E2BIG) {
+                /* We need a bigger buffer. Check if kernel gave us any hints. */
+                if (iwr.u.data.length > size) {
+                    /* Kernel provided required size */
+                    size = iwr.u.data.length;
+                } else {
+                    /* No hint from kernel, double the buffer size */
+                    size *= 2;
+                }
+            } else {
+                /* ioctl error */
+                perror("ioctl[SIOCGIWPRIV]");
+                break;
+            }
+        } else {
+            /* Success. Return the number of private ioctls */
+            priv_args = ppriv;
+            ret = iwr.u.data.length;
+            break;
+        }
+    } while (size <= IW_MAX_PRIV_NUM);
+
+    if ((ret == MLAN_STATUS_FAILURE) && (ppriv))
+        free(ppriv);
+
+    close(s);
+
+    return ret;
+}
+
+/** 
+ *  @brief Get Sub command ioctl number
+ *   
+ *  @param i        command index
+ *  @param priv_cnt     Total number of private ioctls availabe in driver
+ *  @param ioctl_val    A pointer to return ioctl number
+ *  @param subioctl_val A pointer to return sub-ioctl number
+ *  @return 	        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+marvell_get_subioctl_no(t_s32 i,
+                        t_s32 priv_cnt, int *ioctl_val, int *subioctl_val)
+{
+    t_s32 j;
+
+    if (priv_args[i].cmd >= SIOCDEVPRIVATE) {
+        *ioctl_val = priv_args[i].cmd;
+        *subioctl_val = 0;
+        return MLAN_STATUS_SUCCESS;
+    }
+
+    j = -1;
+
+    /* Find the matching *real* ioctl */
+
+    while ((++j < priv_cnt)
+           && ((priv_args[j].name[0] != '\0') ||
+               (priv_args[j].set_args != priv_args[i].set_args) ||
+               (priv_args[j].get_args != priv_args[i].get_args))) {
+    }
+
+    /* If not found... */
+    if (j == priv_cnt) {
+        printf("%s: Invalid private ioctl definition for: 0x%x\n",
+               dev_name, priv_args[i].cmd);
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Save ioctl numbers */
+    *ioctl_val = priv_args[j].cmd;
+    *subioctl_val = priv_args[i].cmd;
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Get ioctl number
+ *   
+ *  @param ifname   	A pointer to net name
+ *  @param priv_cmd	A pointer to priv command buffer
+ *  @param ioctl_val    A pointer to return ioctl number
+ *  @param subioctl_val A pointer to return sub-ioctl number
+ *  @return 	        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+marvell_get_ioctl_no(const t_s8 * ifname,
+                     const t_s8 * priv_cmd, int *ioctl_val, int *subioctl_val)
+{
+    t_s32 i;
+    t_s32 priv_cnt;
+    int ret = MLAN_STATUS_FAILURE;
+
+    priv_cnt = get_private_info(ifname);
+
+    /* Are there any private ioctls? */
+    if (priv_cnt <= 0 || priv_cnt > IW_MAX_PRIV_NUM) {
+        /* Could skip this message ? */
+        printf("%-8.8s  no private ioctls.\n", ifname);
+    } else {
+        for (i = 0; i < priv_cnt; i++) {
+            if (priv_args[i].name[0] && !strcmp(priv_args[i].name, priv_cmd)) {
+                ret = marvell_get_subioctl_no(i, priv_cnt,
+                                              ioctl_val, subioctl_val);
+                break;
+            }
+        }
+    }
+
+    if (priv_args) {
+        free(priv_args);
+        priv_args = NULL;
+    }
+
+    return ret;
+}
+
+/** 
+ *  @brief Retrieve the ioctl and sub-ioctl numbers for the given ioctl string
+ *   
+ *  @param ioctl_name   Private IOCTL string name
+ *  @param ioctl_val    A pointer to return ioctl number
+ *  @param subioctl_val A pointer to return sub-ioctl number
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+get_priv_ioctl(char *ioctl_name, int *ioctl_val, int *subioctl_val)
+{
+    int retval;
+
+    retval = marvell_get_ioctl_no(dev_name,
+                                  ioctl_name, ioctl_val, subioctl_val);
+
+    return retval;
+}
+
+/** 
+ *  @brief Process host_cmd 
+ *  @param argc		number of arguments
+ *  @param argv		A pointer to arguments array    
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_host_cmd(int argc, char *argv[])
+{
+    t_s8 cmdname[256];
+    t_u8 *buf;
+    HostCmd_DS_GEN *hostcmd;
+    struct iwreq iwr;
+    int ret = MLAN_STATUS_SUCCESS;
+    int ioctl_val, subioctl_val;
+
+    if (get_priv_ioctl("hostcmd",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    if (argc < 5) {
+        printf("Error: invalid no of arguments\n");
+        printf("Syntax: ./mlanconfig mlanX hostcmd <hostcmd.conf> <cmdname>\n");
+        exit(1);
+    }
+
+    if ((fp = fopen(argv[3], "r")) == NULL) {
+        fprintf(stderr, "Cannot open file %s\n", argv[3]);
+        exit(1);
+    }
+
+    buf = (t_u8 *) malloc(MRVDRV_SIZE_OF_CMD_BUFFER);
+    if (buf == NULL) {
+        printf("Error: allocate memory for hostcmd failed\n");
+        fclose(fp);
+        return -ENOMEM;
+    }
+    sprintf(cmdname, "%s", argv[4]);
+    ret = prepare_host_cmd_buffer(cmdname, buf);
+    fclose(fp);
+
+    if (ret == MLAN_STATUS_FAILURE)
+        goto _exit_;
+
+    hostcmd = (HostCmd_DS_GEN *) buf;
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = (t_u8 *) hostcmd;
+    iwr.u.data.length = le16_to_cpu(hostcmd->size);
+
+    iwr.u.data.flags = 0;
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        fprintf(stderr, "mlanconfig: MLANHOSTCMD is not supported by %s\n",
+                dev_name);
+        ret = MLAN_STATUS_FAILURE;
+        goto _exit_;
+    }
+    ret = process_host_cmd_resp(buf);
+
+  _exit_:
+    if (buf)
+        free(buf);
+
+    return ret;
+}
+
+/** 
+ *  @brief  get range 
+ *   
+ *  @return	MLAN_STATUS_SUCCESS--success, otherwise --fail
+ */
+static int
+get_range(t_void)
+{
+    struct iw_range *range;
+    struct iwreq iwr;
+    size_t buf_len;
+
+    buf_len = sizeof(struct iw_range) + 500;
+    range = malloc(buf_len);
+    if (range == NULL) {
+        printf("Error: allocate memory for iw_range failed\n");
+        return -ENOMEM;
+    }
+    memset(range, 0, buf_len);
+    memset(&iwr, 0, sizeof(struct iwreq));
+    iwr.u.data.pointer = (caddr_t) range;
+    iwr.u.data.length = buf_len;
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+
+    if ((ioctl(sockfd, SIOCGIWRANGE, &iwr)) < 0) {
+        printf("Get Range Results Failed\n");
+        free(range);
+        return MLAN_STATUS_FAILURE;
+    }
+    we_version_compiled = range->we_version_compiled;
+    printf("Driver build with Wireless Extension %d\n",
+           range->we_version_compiled);
+    free(range);
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Display usage
+ *  
+ *  @return       NA
+ */
+static t_void
+display_usage(t_void)
+{
+    t_s32 i;
+    for (i = 0; i < NELEMENTS(usage); i++)
+        fprintf(stderr, "%s\n", usage[i]);
+}
+
+/** 
+ *  @brief Find command
+ *  
+ *  @param maxcmds  max command number
+ *  @param cmds     A pointer to commands buffer
+ *  @param cmd      A pointer to command buffer
+ *  @return         index of command or MLAN_STATUS_FAILURE
+ */
+static int
+findcommand(t_s32 maxcmds, t_s8 * cmds[], t_s8 * cmd)
+{
+    t_s32 i;
+
+    for (i = 0; i < maxcmds; i++) {
+        if (!strcasecmp(cmds[i], cmd)) {
+            return i;
+        }
+    }
+
+    return MLAN_STATUS_FAILURE;
+}
+
+/** 
+ *  @brief Process arpfilter
+ *  @param argc   number of arguments
+ *  @param argv   A pointer to arguments array    
+ *  @return     MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_arpfilter(int argc, char *argv[])
+{
+    t_u8 *buf;
+    struct iwreq iwr;
+    t_u16 length = 0;
+    int ret = MLAN_STATUS_SUCCESS;
+    int ioctl_val, subioctl_val;
+
+    if (get_priv_ioctl("arpfilter",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    if (argc < 4) {
+        printf("Error: invalid no of arguments\n");
+        printf("Syntax: ./mlanconfig mlanX arpfilter <arpfilter.conf>\n");
+        exit(1);
+    }
+
+    if ((fp = fopen(argv[3], "r")) == NULL) {
+        fprintf(stderr, "Cannot open file %s\n", argv[3]);
+        return MLAN_STATUS_FAILURE;
+    }
+    buf = (t_u8 *) malloc(MRVDRV_SIZE_OF_CMD_BUFFER);
+    if (buf == NULL) {
+        printf("Error: allocate memory for arpfilter failed\n");
+        fclose(fp);
+        return -ENOMEM;
+    }
+    ret = prepare_arp_filter_buffer(buf, &length);
+    fclose(fp);
+
+    if (ret == MLAN_STATUS_FAILURE)
+        goto _exit_;
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = buf;
+    iwr.u.data.length = length;
+    iwr.u.data.flags = 0;
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        fprintf(stderr,
+                "mlanconfig: arpfilter command is not supported by %s\n",
+                dev_name);
+        ret = MLAN_STATUS_FAILURE;
+        goto _exit_;
+    }
+
+  _exit_:
+    if (buf)
+        free(buf);
+
+    return ret;
+}
+
+/** 
+ *  @brief Process cfgdata 
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_cfg_data(int argc, char *argv[])
+{
+    t_u8 *buf;
+    HostCmd_DS_GEN *hostcmd;
+    struct iwreq iwr;
+    int ret = MLAN_STATUS_SUCCESS;
+    int ioctl_val, subioctl_val;
+
+    if (get_priv_ioctl("hostcmd",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    if (argc < 4 || argc > 5) {
+        printf("Error: invalid no of arguments\n");
+        printf
+            ("Syntax: ./mlanconfig mlanX cfgdata <register type> <filename>\n");
+        exit(1);
+    }
+
+    if (argc == 5) {
+        if ((fp = fopen(argv[4], "r")) == NULL) {
+            fprintf(stderr, "Cannot open file %s\n", argv[3]);
+            exit(1);
+        }
+    }
+    buf = (t_u8 *) malloc(MRVDRV_SIZE_OF_CMD_BUFFER);
+    if (buf == NULL) {
+        printf("Error: allocate memory for hostcmd failed\n");
+        fclose(fp);
+        return -ENOMEM;
+    }
+    ret = prepare_cfg_data_buffer(argc, argv, buf);
+    if (argc == 5)
+        fclose(fp);
+
+    if (ret == MLAN_STATUS_FAILURE)
+        goto _exit_;
+
+    hostcmd = (HostCmd_DS_GEN *) buf;
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = (t_u8 *) hostcmd;
+    iwr.u.data.length = le16_to_cpu(hostcmd->size);
+
+    iwr.u.data.flags = 0;
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        fprintf(stderr, "mlanconfig: MLANHOSTCMD is not supported by %s\n",
+                dev_name);
+        ret = MLAN_STATUS_FAILURE;
+        goto _exit_;
+    }
+    ret = process_host_cmd_resp(buf);
+
+  _exit_:
+    if (buf)
+        free(buf);
+
+    return ret;
+}
+
+/** 
+ *  @brief read current command
+ *  @param ptr      A pointer to data
+ *  @param curCmd   A pointer to the buf which will hold current command    
+ *  @return         NULL or the pointer to the left command buf
+ */
+static t_s8 *
+readCurCmd(t_s8 * ptr, t_s8 * curCmd)
+{
+    t_s32 i = 0;
+#define MAX_CMD_SIZE 64 /**< Max command size */
+
+    while (*ptr != ']' && i < (MAX_CMD_SIZE - 1))
+        curCmd[i++] = *(++ptr);
+
+    if (*ptr != ']')
+        return NULL;
+
+    curCmd[i - 1] = '\0';
+
+    return ++ptr;
+}
+
+/** 
+ *  @brief parse command and hex data
+ *  @param fp       A pointer to FILE stream
+ *  @param dst      A pointer to the dest buf
+ *  @param cmd      A pointer to command buf for search
+ *  @return         Length of hex data or MLAN_STATUS_FAILURE  		
+ */
+static int
+fparse_for_cmd_and_hex(FILE * fp, t_u8 * dst, t_u8 * cmd)
+{
+    t_s8 *ptr;
+    t_u8 *dptr;
+    t_s8 buf[256], curCmd[64];
+    t_s32 isCurCmd = 0;
+
+    dptr = dst;
+    while (fgets(buf, sizeof(buf), fp)) {
+        ptr = buf;
+
+        while (*ptr) {
+            /* skip leading spaces */
+            while (*ptr && isspace(*ptr))
+                ptr++;
+
+            /* skip blank lines and lines beginning with '#' */
+            if (*ptr == '\0' || *ptr == '#')
+                break;
+
+            if (*ptr == '[' && *(ptr + 1) != '/') {
+                if (!(ptr = readCurCmd(ptr, curCmd)))
+                    return MLAN_STATUS_FAILURE;
+
+                if (strcasecmp(curCmd, (char *) cmd))   /* Not equal */
+                    isCurCmd = 0;
+                else
+                    isCurCmd = 1;
+            }
+
+            /* Ignore the rest if it is not correct cmd */
+            if (!isCurCmd)
+                break;
+
+            if (*ptr == '[' && *(ptr + 1) == '/')
+                return (dptr - dst);
+
+            if (isxdigit(*ptr)) {
+                ptr = convert2hex(ptr, dptr++);
+            } else {
+                /* Invalid character on data line */
+                ptr++;
+            }
+        }
+    }
+
+    return MLAN_STATUS_FAILURE;
+}
+
+/**
+ *  @brief Send an ADDTS command to the associated AP
+ *
+ *  Process a given conf file for a specific TSPEC data block.  Send the
+ *    TSPEC along with any other IEs to the driver/firmware for transmission
+ *    in an ADDTS request to the associated AP.  
+ *
+ *  Return the execution status of the command as well as the ADDTS response
+ *    from the AP if any.
+ *  
+ *  mlanconfig mlanX addts <filename.conf> <section# of tspec> <timeout in ms>
+ *
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_addts(int argc, char *argv[])
+{
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    int ieBytes;
+    wlan_ioctl_wmm_addts_req_t addtsReq;
+
+    FILE *fp;
+    char filename[48];
+    char config_id[20];
+
+    memset(&addtsReq, 0x00, sizeof(addtsReq));
+    memset(filename, 0x00, sizeof(filename));
+
+    if (get_priv_ioctl("addts",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    if (argc != 6) {
+        fprintf(stderr, "Invalid number of parameters!\n");
+        return -EINVAL;
+    }
+
+    ieBytes = 0;
+
+    strncpy(filename, argv[3], MIN(sizeof(filename) - 1, strlen(argv[3])));
+    if ((fp = fopen(filename, "r")) == NULL) {
+        perror("fopen");
+        fprintf(stderr, "Cannot open file %s\n", argv[3]);
+        exit(1);
+    }
+
+    sprintf(config_id, "tspec%d", atoi(argv[4]));
+
+    ieBytes =
+        fparse_for_cmd_and_hex(fp, addtsReq.tspecData, (t_u8 *) config_id);
+
+    if (ieBytes > 0) {
+        printf("Found %d bytes in the %s section of conf file %s\n",
+               ieBytes, config_id, filename);
+    } else {
+        fprintf(stderr, "section %s not found in %s\n", config_id, filename);
+        exit(1);
+    }
+
+    addtsReq.timeout_ms = atoi(argv[5]);
+
+    printf("Cmd Input:\n");
+    hexdump(config_id, addtsReq.tspecData, ieBytes, ' ');
+
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.flags = subioctl_val;
+    iwr.u.data.pointer = (caddr_t) & addtsReq;
+    iwr.u.data.length = (sizeof(addtsReq.timeout_ms)
+                         + sizeof(addtsReq.commandResult)
+                         + sizeof(addtsReq.ieeeStatusCode)
+                         + ieBytes);
+
+    if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+        perror("mlanconfig: addts ioctl");
+        return -EFAULT;
+    }
+
+    ieBytes = iwr.u.data.length - (sizeof(addtsReq.timeout_ms)
+                                   + sizeof(addtsReq.commandResult)
+                                   + sizeof(addtsReq.ieeeStatusCode));
+    printf("Cmd Output:\n");
+    printf("ADDTS Command Result = %d\n", addtsReq.commandResult);
+    printf("ADDTS IEEE Status    = %d\n", addtsReq.ieeeStatusCode);
+    hexdump(config_id, addtsReq.tspecData, ieBytes, ' ');
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Send a DELTS command to the associated AP
+ *
+ *  Process a given conf file for a specific TSPEC data block.  Send the
+ *    TSPEC along with any other IEs to the driver/firmware for transmission
+ *    in a DELTS request to the associated AP.  
+ *
+ *  Return the execution status of the command.  There is no response to a
+ *    DELTS from the AP.
+ *  
+ *  mlanconfig mlanX delts <filename.conf> <section# of tspec>
+ *
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_delts(int argc, char *argv[])
+{
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    int ieBytes;
+    wlan_ioctl_wmm_delts_req_t deltsReq;
+
+    FILE *fp;
+    char filename[48];
+    char config_id[20];
+
+    memset(&deltsReq, 0x00, sizeof(deltsReq));
+    memset(filename, 0x00, sizeof(filename));
+
+    if (get_priv_ioctl("delts",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    if (argc != 5) {
+        fprintf(stderr, "Invalid number of parameters!\n");
+        return -EINVAL;
+    }
+
+    ieBytes = 0;
+
+    strncpy(filename, argv[3], MIN(sizeof(filename) - 1, strlen(argv[3])));
+    if ((fp = fopen(filename, "r")) == NULL) {
+        perror("fopen");
+        fprintf(stderr, "Cannot open file %s\n", argv[3]);
+        exit(1);
+    }
+
+    sprintf(config_id, "tspec%d", atoi(argv[4]));
+
+    ieBytes =
+        fparse_for_cmd_and_hex(fp, deltsReq.tspecData, (t_u8 *) config_id);
+
+    if (ieBytes > 0) {
+        printf("Found %d bytes in the %s section of conf file %s\n",
+               ieBytes, config_id, filename);
+    } else {
+        fprintf(stderr, "section %s not found in %s\n", config_id, filename);
+        exit(1);
+    }
+
+    deltsReq.ieeeReasonCode = 0x20;     /* 32, unspecified QOS reason */
+
+    printf("Cmd Input:\n");
+    hexdump(config_id, deltsReq.tspecData, ieBytes, ' ');
+
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.flags = subioctl_val;
+    iwr.u.data.pointer = (caddr_t) & deltsReq;
+    iwr.u.data.length = (sizeof(deltsReq.commandResult)
+                         + sizeof(deltsReq.ieeeReasonCode)
+                         + ieBytes);
+
+    if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+        perror("mlanconfig: delts ioctl");
+        return -EFAULT;
+    }
+
+    printf("Cmd Output:\n");
+    printf("DELTS Command Result = %d\n", deltsReq.commandResult);
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Send a WMM AC Queue configuration command to get/set/default params
+ *
+ *  Configure or get the parameters of a WMM AC queue. The command takes
+ *    an optional Queue Id as a last parameter.  Without the queue id, all
+ *    queues will be acted upon.
+ *  
+ *  mlanconfig mlanX qconfig set msdu <lifetime in TUs> [Queue Id: 0-3]
+ *  mlanconfig mlanX qconfig get [Queue Id: 0-3]
+ *  mlanconfig mlanX qconfig def [Queue Id: 0-3]
+ *
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_qconfig(int argc, char *argv[])
+{
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    wlan_ioctl_wmm_queue_config_t queue_config_cmd;
+    mlan_wmm_ac_e ac_idx;
+    mlan_wmm_ac_e ac_idx_start;
+    mlan_wmm_ac_e ac_idx_stop;
+
+    const char *ac_str_tbl[] = { "BK", "BE", "VI", "VO" };
+
+    if (argc < 4) {
+        fprintf(stderr, "Invalid number of parameters!\n");
+        return -EINVAL;
+    }
+
+    if (get_priv_ioctl("qconfig",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    memset(&queue_config_cmd, 0x00, sizeof(queue_config_cmd));
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) & queue_config_cmd;
+    iwr.u.data.length = sizeof(queue_config_cmd);
+    iwr.u.data.flags = subioctl_val;
+
+    if (strcmp(argv[3], "get") == 0) {
+        /* 3 4 5 */
+        /* qconfig get [qid] */
+        if (argc == 4) {
+            ac_idx_start = WMM_AC_BK;
+            ac_idx_stop = WMM_AC_VO;
+        } else if (argc == 5) {
+            if (atoi(argv[4]) < WMM_AC_BK || atoi(argv[4]) > WMM_AC_VO) {
+                fprintf(stderr, "ERROR: Invalid Queue ID!\n");
+                return -EINVAL;
+            }
+            ac_idx_start = atoi(argv[4]);
+            ac_idx_stop = ac_idx_start;
+        } else {
+            fprintf(stderr, "Invalid number of parameters!\n");
+            return -EINVAL;
+        }
+        queue_config_cmd.action = WMM_QUEUE_CONFIG_ACTION_GET;
+
+        for (ac_idx = ac_idx_start; ac_idx <= ac_idx_stop; ac_idx++) {
+            queue_config_cmd.accessCategory = ac_idx;
+            if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+                perror("qconfig ioctl");
+            } else {
+                printf("qconfig %s(%d): MSDU Lifetime GET = 0x%04x (%d)\n",
+                       ac_str_tbl[ac_idx],
+                       ac_idx,
+                       queue_config_cmd.msduLifetimeExpiry,
+                       queue_config_cmd.msduLifetimeExpiry);
+            }
+        }
+    } else if (strcmp(argv[3], "set") == 0) {
+        if ((argc >= 5) && strcmp(argv[4], "msdu") == 0) {
+            /* 3 4 5 6 7 */
+            /* qconfig set msdu <value> [qid] */
+            if (argc == 6) {
+                ac_idx_start = WMM_AC_BK;
+                ac_idx_stop = WMM_AC_VO;
+            } else if (argc == 7) {
+                if (atoi(argv[6]) < WMM_AC_BK || atoi(argv[6]) > WMM_AC_VO) {
+                    fprintf(stderr, "ERROR: Invalid Queue ID!\n");
+                    return -EINVAL;
+                }
+                ac_idx_start = atoi(argv[6]);
+                ac_idx_stop = ac_idx_start;
+            } else {
+                fprintf(stderr, "Invalid number of parameters!\n");
+                return -EINVAL;
+            }
+            queue_config_cmd.action = WMM_QUEUE_CONFIG_ACTION_SET;
+            queue_config_cmd.msduLifetimeExpiry = atoi(argv[5]);
+
+            for (ac_idx = ac_idx_start; ac_idx <= ac_idx_stop; ac_idx++) {
+                queue_config_cmd.accessCategory = ac_idx;
+                if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+                    perror("qconfig ioctl");
+                } else {
+                    printf("qconfig %s(%d): MSDU Lifetime SET = 0x%04x (%d)\n",
+                           ac_str_tbl[ac_idx],
+                           ac_idx,
+                           queue_config_cmd.msduLifetimeExpiry,
+                           queue_config_cmd.msduLifetimeExpiry);
+                }
+            }
+        } else {
+            /* Only MSDU Lifetime provisioning accepted for now */
+            fprintf(stderr, "Invalid set parameter: s/b [msdu]\n");
+            return -EINVAL;
+        }
+    } else if (strncmp(argv[3], "def", strlen("def")) == 0) {
+        /* 3 4 5 */
+        /* qconfig def [qid] */
+        if (argc == 4) {
+            ac_idx_start = WMM_AC_BK;
+            ac_idx_stop = WMM_AC_VO;
+        } else if (argc == 5) {
+            if (atoi(argv[4]) < WMM_AC_BK || atoi(argv[4]) > WMM_AC_VO) {
+                fprintf(stderr, "ERROR: Invalid Queue ID!\n");
+                return -EINVAL;
+            }
+            ac_idx_start = atoi(argv[4]);
+            ac_idx_stop = ac_idx_start;
+        } else {
+            fprintf(stderr, "Invalid number of parameters!\n");
+            return -EINVAL;
+        }
+        queue_config_cmd.action = WMM_QUEUE_CONFIG_ACTION_DEFAULT;
+
+        for (ac_idx = ac_idx_start; ac_idx <= ac_idx_stop; ac_idx++) {
+            queue_config_cmd.accessCategory = ac_idx;
+            if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+                perror("qconfig ioctl");
+            } else {
+                printf("qconfig %s(%d): MSDU Lifetime DEFAULT = 0x%04x (%d)\n",
+                       ac_str_tbl[ac_idx],
+                       ac_idx,
+                       queue_config_cmd.msduLifetimeExpiry,
+                       queue_config_cmd.msduLifetimeExpiry);
+            }
+        }
+    } else {
+        fprintf(stderr, "Invalid qconfig command; s/b [set, get, default]\n");
+        return -EINVAL;
+    }
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Turn on/off or retrieve and clear the queue statistics for an AC
+ *
+ *  Turn the queue statistics collection on/off for a given AC or retrieve the
+ *    current accumulated stats and clear them from the firmware.  The command
+ *    takes an optional Queue Id as a last parameter.  Without the queue id,
+ *    all queues will be acted upon.
+ *
+ *  mlanconfig mlanX qstats on [Queue Id: 0-3]
+ *  mlanconfig mlanX qstats off [Queue Id: 0-3]
+ *  mlanconfig mlanX qstats get [Queue Id: 0-3]
+ *
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_qstats(int argc, char *argv[])
+{
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    wlan_ioctl_wmm_queue_stats_t queue_stats_cmd;
+    mlan_wmm_ac_e ac_idx;
+    mlan_wmm_ac_e ac_idx_start;
+    mlan_wmm_ac_e ac_idx_stop;
+    t_u16 usedTime[MAX_AC_QUEUES];
+    t_u16 policedTime[MAX_AC_QUEUES];
+
+    const char *ac_str_tbl[] = { "BK", "BE", "VI", "VO" };
+
+    if (argc < 3) {
+        fprintf(stderr, "Invalid number of parameters!\n");
+        return -EINVAL;
+    }
+
+    if (get_priv_ioctl("qstats",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    printf("\n");
+
+    memset(usedTime, 0x00, sizeof(usedTime));
+    memset(policedTime, 0x00, sizeof(policedTime));
+    memset(&queue_stats_cmd, 0x00, sizeof(queue_stats_cmd));
+
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) & queue_stats_cmd;
+    iwr.u.data.length = sizeof(queue_stats_cmd);
+    iwr.u.data.flags = subioctl_val;
+
+    if ((argc > 3) && strcmp(argv[3], "on") == 0) {
+        if (argc == 4) {
+            ac_idx_start = WMM_AC_BK;
+            ac_idx_stop = WMM_AC_VO;
+        } else if (argc == 5) {
+            if (atoi(argv[4]) < WMM_AC_BK || atoi(argv[4]) > WMM_AC_VO) {
+                fprintf(stderr, "ERROR: Invalid Queue ID!\n");
+                return -EINVAL;
+            }
+            ac_idx_start = atoi(argv[4]);
+            ac_idx_stop = ac_idx_start;
+        } else {
+            fprintf(stderr, "Invalid number of parameters!\n");
+            return -EINVAL;
+        }
+        queue_stats_cmd.action = WMM_STATS_ACTION_START;
+        for (ac_idx = ac_idx_start; ac_idx <= ac_idx_stop; ac_idx++) {
+            queue_stats_cmd.accessCategory = ac_idx;
+            if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+                perror("qstats ioctl");
+            } else {
+                printf("qstats %s(%d) turned on\n", ac_str_tbl[ac_idx], ac_idx);
+            }
+        }
+    } else if ((argc > 3) && strcmp(argv[3], "off") == 0) {
+        if (argc == 4) {
+            ac_idx_start = WMM_AC_BK;
+            ac_idx_stop = WMM_AC_VO;
+        } else if (argc == 5) {
+            if (atoi(argv[4]) < WMM_AC_BK || atoi(argv[4]) > WMM_AC_VO) {
+                fprintf(stderr, "ERROR: Invalid Queue ID!\n");
+                return -EINVAL;
+            }
+            ac_idx_start = atoi(argv[4]);
+            ac_idx_stop = ac_idx_start;
+        } else {
+            fprintf(stderr, "Invalid number of parameters!\n");
+            return -EINVAL;
+        }
+        queue_stats_cmd.action = WMM_STATS_ACTION_STOP;
+        for (ac_idx = ac_idx_start; ac_idx <= ac_idx_stop; ac_idx++) {
+            queue_stats_cmd.accessCategory = ac_idx;
+            if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+                perror("qstats ioctl");
+            } else {
+                printf("qstats %s(%d) turned off\n",
+                       ac_str_tbl[ac_idx], ac_idx);
+            }
+        }
+    } else if ((argc >= 3) && ((argc == 3) ? 1 : (strcmp(argv[3], "get") == 0))) {
+        /* If the user types: "mlanconfig mlanX qstats" without get argument.
+           The mlanconfig application invokes "get" option for all queues */
+        if ((argc == 4) || (argc == 3)) {
+            ac_idx_start = WMM_AC_BK;
+            ac_idx_stop = WMM_AC_VO;
+        } else if (argc == 5) {
+            if (atoi(argv[4]) < WMM_AC_BK || atoi(argv[4]) > WMM_AC_VO) {
+                fprintf(stderr, "ERROR: Invalid Queue ID!\n");
+                return -EINVAL;
+            }
+            ac_idx_start = atoi(argv[4]);
+            ac_idx_stop = ac_idx_start;
+        } else {
+            fprintf(stderr, "Invalid number of parameters!\n");
+            return -EINVAL;
+        }
+        printf("AC  Count   Loss  TxDly   QDly"
+               "    <=5   <=10   <=20   <=30   <=40   <=50    >50\n");
+        printf("----------------------------------"
+               "---------------------------------------------\n");
+        queue_stats_cmd.action = WMM_STATS_ACTION_GET_CLR;
+
+        for (ac_idx = ac_idx_start; ac_idx <= ac_idx_stop; ac_idx++) {
+            queue_stats_cmd.accessCategory = ac_idx;
+            if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+                perror("qstats ioctl");
+            } else {
+                printf("%s  %5u  %5u %6u %6u"
+                       "  %5u  %5u  %5u  %5u  %5u  %5u  %5u\n",
+                       ac_str_tbl[ac_idx],
+                       queue_stats_cmd.pktCount,
+                       queue_stats_cmd.pktLoss,
+                       (unsigned int) queue_stats_cmd.avgTxDelay,
+                       (unsigned int) queue_stats_cmd.avgQueueDelay,
+                       queue_stats_cmd.delayHistogram[0],
+                       queue_stats_cmd.delayHistogram[1],
+                       queue_stats_cmd.delayHistogram[2],
+                       queue_stats_cmd.delayHistogram[3],
+                       queue_stats_cmd.delayHistogram[4],
+                       queue_stats_cmd.delayHistogram[5],
+                       queue_stats_cmd.delayHistogram[6]);
+
+                usedTime[ac_idx] = queue_stats_cmd.usedTime;
+                policedTime[ac_idx] = queue_stats_cmd.policedTime;
+            }
+        }
+
+        printf("----------------------------------"
+               "---------------------------------------------\n");
+        printf("\nAC      UsedTime      PolicedTime\n");
+        printf("---------------------------------\n");
+
+        for (ac_idx = ac_idx_start; ac_idx <= ac_idx_stop; ac_idx++) {
+            printf("%s        %6u           %6u\n",
+                   ac_str_tbl[ac_idx],
+                   (unsigned int) usedTime[ac_idx],
+                   (unsigned int) policedTime[ac_idx]);
+        }
+    } else {
+        fprintf(stderr, "Invalid qstats command;\n");
+        return -EINVAL;
+    }
+    printf("\n");
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Get the current status of the WMM Queues
+ *  
+ *  Command: mlanconfig mlanX qstatus
+ *
+ *  Retrieve the following information for each AC if wmm is enabled:
+ *        - WMM IE ACM Required
+ *        - Firmware Flow Required 
+ *        - Firmware Flow Established
+ *        - Firmware Queue Enabled
+ *  
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_wmm_qstatus(int argc, char *argv[])
+{
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    wlan_ioctl_wmm_queue_status_t qstatus;
+    mlan_wmm_ac_e acVal;
+
+    if (get_priv_ioctl("qstatus",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    memset(&qstatus, 0x00, sizeof(qstatus));
+
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.flags = subioctl_val;
+    iwr.u.data.pointer = (caddr_t) & qstatus;
+    iwr.u.data.length = (sizeof(qstatus));
+
+    if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+        perror("mlanconfig: qstatus ioctl");
+        return -EFAULT;
+    }
+
+    for (acVal = WMM_AC_BK; acVal <= WMM_AC_VO; acVal++) {
+        switch (acVal) {
+        case WMM_AC_BK:
+            printf("BK: ");
+            break;
+        case WMM_AC_BE:
+            printf("BE: ");
+            break;
+        case WMM_AC_VI:
+            printf("VI: ");
+            break;
+        case WMM_AC_VO:
+            printf("VO: ");
+            break;
+        default:
+            printf("??: ");
+        }
+
+        printf("ACM[%c], FlowReq[%c], FlowCreated[%c], Enabled[%c],"
+               " DE[%c], TE[%c]\n",
+               (qstatus.acStatus[acVal].wmmAcm ? 'X' : ' '),
+               (qstatus.acStatus[acVal].flowRequired ? 'X' : ' '),
+               (qstatus.acStatus[acVal].flowCreated ? 'X' : ' '),
+               (qstatus.acStatus[acVal].disabled ? ' ' : 'X'),
+               (qstatus.acStatus[acVal].deliveryEnabled ? 'X' : ' '),
+               (qstatus.acStatus[acVal].triggerEnabled ? 'X' : ' '));
+    }
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Get the current status of the WMM Traffic Streams
+ *  
+ *  Command: mlanconfig mlanX ts_status
+ *
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_wmm_ts_status(int argc, char *argv[])
+{
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    wlan_ioctl_wmm_ts_status_t ts_status;
+    int tid;
+
+    const char *ac_str_tbl[] = { "BK", "BE", "VI", "VO" };
+
+    if (get_priv_ioctl("ts_status",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    printf("\nTID   Valid    AC   UP   PSB   FlowDir  MediumTime\n");
+    printf("---------------------------------------------------\n");
+
+    for (tid = 0; tid <= 7; tid++) {
+        memset(&ts_status, 0x00, sizeof(ts_status));
+        ts_status.tid = tid;
+
+        strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+        iwr.u.data.flags = subioctl_val;
+        iwr.u.data.pointer = (caddr_t) & ts_status;
+        iwr.u.data.length = (sizeof(ts_status));
+
+        if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+            perror("mlanconfig: ts_status ioctl");
+            return -EFAULT;
+        }
+
+        printf(" %02d     %3s    %2s    %u     %c    ",
+               ts_status.tid,
+               (ts_status.valid ? "Yes" : "No"),
+               (ts_status.valid ? ac_str_tbl[ts_status.accessCategory] : "--"),
+               ts_status.userPriority, (ts_status.psb ? 'U' : 'L'));
+
+        if ((ts_status.flowDir & 0x03) == 0) {
+            printf("%s", " ---- ");
+        } else {
+            printf("%2s%4s",
+                   (ts_status.flowDir & 0x01 ? "Up" : ""),
+                   (ts_status.flowDir & 0x02 ? "Down" : ""));
+        }
+
+        printf("%12u\n", ts_status.mediumTime);
+    }
+
+    printf("\n");
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Provides interface to perform read/write operations on regsiter
+ *
+ *  Command: mlanconfig mlanX regrdwr <type> <offset> [value]
+ *
+ *  @param argc     Number of arguments
+ *  @param argv     Pointer to the arguments
+ *
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_regrdwr(int argc, char *argv[])
+{
+    struct iwreq iwr;
+    int ioctl_val, subioctl_val;
+    t_u32 type, offset, value;
+    t_u8 buf[100];
+    HostCmd_DS_GEN *hostcmd = (HostCmd_DS_GEN *) buf;
+    int ret = MLAN_STATUS_SUCCESS;
+
+    /* Check arguments */
+    if ((argc < 5) || (argc > 6)) {
+        printf("Parameters for regrdwr: <type> <offset> [value]\n");
+        return -EINVAL;
+    }
+
+    if (get_priv_ioctl("hostcmd",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    type = a2hex_or_atoi(argv[3]);
+    offset = a2hex_or_atoi(argv[4]);
+    if (argc > 5)
+        value = a2hex_or_atoi(argv[5]);
+    if ((ret = prepare_hostcmd_regrdwr(type, offset,
+                                       (argc > 5) ? &value : NULL, buf))) {
+        return ret;
+    }
+
+    memset(&iwr, 0, sizeof(iwr));
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = buf;
+    iwr.u.data.length = le16_to_cpu(hostcmd->size);
+    iwr.u.data.flags = 0;
+
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        fprintf(stderr, "mlanconfig: MLANHOSTCMD is not supported by %s\n",
+                dev_name);
+        return MLAN_STATUS_FAILURE;
+    }
+    ret = process_host_cmd_resp(buf);
+
+    return ret;
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+/** 
+ *  @brief Get one line from the File
+ *  
+ *  @param s	    Storage location for data.
+ *  @param size 	Maximum number of characters to read. 
+ *  @param line		A pointer to return current line number
+ *  @return         returns string or NULL 
+ */
+t_s8 *
+mlan_config_get_line(t_s8 * s, t_s32 size, int *line)
+{
+    t_s8 *pos, *end, *sstart;
+
+    while (fgets(s, size, fp)) {
+        (*line)++;
+        s[size - 1] = '\0';
+        pos = s;
+
+        while (*pos == ' ' || *pos == '\t')
+            pos++;
+        if (*pos == '#' || (*pos == '\r' && *(pos + 1) == '\n') ||
+            *pos == '\n' || *pos == '\0')
+            continue;
+
+        /* Remove # comments unless they are within a double quoted * string.
+           Remove trailing white space. */
+        sstart = strchr(pos, '"');
+        if (sstart)
+            sstart = strchr(sstart + 1, '"');
+        if (!sstart)
+            sstart = pos;
+        end = strchr(sstart, '#');
+        if (end)
+            *end-- = '\0';
+        else
+            end = pos + strlen(pos) - 1;
+        while (end > pos && (*end == '\r' || *end == '\n' ||
+                             *end == ' ' || *end == '\t')) {
+            *end-- = '\0';
+        }
+        if (*pos == '\0')
+            continue;
+        return pos;
+    }
+    return NULL;
+}
+
+/** 
+ *  @brief parse hex data
+ *  @param dst      A pointer to receive hex data
+ *  @return         length of hex data
+ */
+int
+fparse_for_hex(t_u8 * dst)
+{
+    t_s8 *ptr;
+    t_u8 *dptr;
+    t_s8 buf[256];
+
+    dptr = dst;
+    while (fgets(buf, sizeof(buf), fp)) {
+        ptr = buf;
+
+        while (*ptr) {
+            /* skip leading spaces */
+            while (*ptr && (isspace(*ptr) || *ptr == '\t'))
+                ptr++;
+
+            /* skip blank lines and lines beginning with '#' */
+            if (*ptr == '\0' || *ptr == '#')
+                break;
+
+            if (isxdigit(*ptr)) {
+                ptr = convert2hex(ptr, dptr++);
+            } else {
+                /* Invalid character on data line */
+                ptr++;
+            }
+        }
+    }
+
+    return (dptr - dst);
+}
+
+#define STACK_NBYTES            	100     /**< Number of bytes in stack */
+#define MAX_BYTESEQ 		       	6       /**< Maximum byte sequence */
+#define TYPE_DNUM           		1 /**< decimal number */
+#define TYPE_BYTESEQ        		2 /**< byte sequence */
+#define MAX_OPERAND         		0x40    /**< Maximum operands */
+#define TYPE_EQ         		(MAX_OPERAND+1) /**< byte comparison:    == operator */
+#define TYPE_EQ_DNUM    		(MAX_OPERAND+2) /**< decimal comparison: =d operator */
+#define TYPE_EQ_BIT     		(MAX_OPERAND+3) /**< bit comparison:     =b operator */
+#define TYPE_AND        		(MAX_OPERAND+4) /**< && operator */
+#define TYPE_OR         		(MAX_OPERAND+5) /**< || operator */
+typedef struct
+{
+    t_u16 sp;                         /**< Stack pointer */
+    t_u8 byte[STACK_NBYTES];          /**< Stack */
+} stack_t;
+
+typedef struct
+{
+    t_u8 type;                    /**< Type */
+    t_u8 reserve[3];       /**< so 4-byte align val array */
+    /* byte sequence is the largest among all the operands and operators. */
+    /* byte sequence format: 1 byte of num of bytes, then variable num bytes */
+    t_u8 val[MAX_BYTESEQ + 1];    /**< Value */
+} op_t;
+
+/** 
+ *  @brief push data to stack
+ *  
+ *  @param s			a pointer to stack_t structure
+ *  
+ *  @param nbytes		number of byte to push to stack  
+ *  
+ *  @param val			a pointer to data buffer	
+ *  
+ *  @return			TRUE-- sucess , FALSE -- fail
+ *  			
+ */
+static int
+push_n(stack_t * s, t_u8 nbytes, t_u8 * val)
+{
+    if ((s->sp + nbytes) < STACK_NBYTES) {
+        memcpy((void *) (s->byte + s->sp), (const void *) val, (size_t) nbytes);
+        s->sp += nbytes;
+        /* printf("push: n %d sp %d\n", nbytes, s->sp); */
+        return TRUE;
+    } else                      /* stack full */
+        return FALSE;
+}
+
+/** 
+ *  @brief push data to stack
+ *  
+ *  @param s			a pointer to stack_t structure
+ *  
+ *  @param op			a pointer to op_t structure  
+ *  
+ *  @return			TRUE-- sucess , FALSE -- fail
+ *  			
+ */
+static int
+push(stack_t * s, op_t * op)
+{
+    t_u8 nbytes;
+    switch (op->type) {
+    case TYPE_DNUM:
+        if (push_n(s, 4, op->val))
+            return (push_n(s, 1, &op->type));
+        return FALSE;
+    case TYPE_BYTESEQ:
+        nbytes = op->val[0];
+        if (push_n(s, nbytes, op->val + 1) &&
+            push_n(s, 1, op->val) && push_n(s, 1, &op->type))
+            return TRUE;
+        return FALSE;
+    default:
+        return (push_n(s, 1, &op->type));
+    }
+}
+
+/** 
+ *  @brief parse RPN string
+ *  
+ *  @param s			a pointer to Null-terminated string to scan. 
+ *  
+ *  @param first_time		a pointer to return first_time  
+ *  
+ *  @return			A pointer to the last token found in string.   
+ *  				NULL is returned when there are no more tokens to be found. 
+ *  			
+ */
+static char *
+getop(char *s, int *first_time)
+{
+    const char delim[] = " \t\n";
+    char *p;
+    if (*first_time) {
+        p = strtok(s, delim);
+        *first_time = FALSE;
+    } else {
+        p = strtok(NULL, delim);
+    }
+    return (p);
+}
+
+/** 
+ *  @brief Verify hex digit.
+ *  
+ *  @param c			input ascii char 
+ *  @param h			a pointer to return integer value of the digit char. 
+ *  @return			TURE -- c is hex digit, FALSE -- c is not hex digit.
+ */
+static int
+ishexdigit(char c, t_u8 * h)
+{
+    if (c >= '0' && c <= '9') {
+        *h = c - '0';
+        return (TRUE);
+    } else if (c >= 'a' && c <= 'f') {
+        *h = c - 'a' + 10;
+        return (TRUE);
+    } else if (c >= 'A' && c <= 'F') {
+        *h = c - 'A' + 10;
+        return (TRUE);
+    }
+    return (FALSE);
+}
+
+/** 
+ *  @brief convert hex string to integer.
+ *  
+ *  @param s			A pointer to hex string, string length up to 2 digits. 
+ *  @return			integer value.
+ */
+static t_u8
+hex_atoi(char *s)
+{
+    int i;
+    t_u8 digit;                 /* digital value */
+    t_u8 t = 0;                 /* total value */
+
+    for (i = 0, t = 0; ishexdigit(s[i], &digit) && i < 2; i++)
+        t = 16 * t + digit;
+    return (t);
+}
+
+/** 
+ *  @brief Parse byte sequence in hex format string to a byte sequence.
+ *  
+ *  @param opstr		A pointer to byte sequence in hex format string, with ':' as delimiter between two byte. 
+ *  @param val			A pointer to return byte sequence string
+ *  @return			NA
+ */
+static void
+parse_hex(char *opstr, t_u8 * val)
+{
+    char delim = ':';
+    char *p;
+    char *q;
+    t_u8 i;
+
+    /* +1 is for skipping over the preceding h character. */
+    p = opstr + 1;
+
+    /* First byte */
+    val[1] = hex_atoi(p++);
+
+    /* Parse subsequent bytes. */
+    /* Each byte is preceded by the : character. */
+    for (i = 1; *p; i++) {
+        q = strchr(p, delim);
+        if (!q)
+            break;
+        p = q + 1;
+        val[i + 1] = hex_atoi(p);
+    }
+    /* Set num of bytes */
+    val[0] = i;
+}
+
+/** 
+ *  @brief str2bin, convert RPN string to binary format
+ *  
+ *  @param str			A pointer to rpn string
+ *  @param stack		A pointer to stack_t structure
+ *  @return			MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+str2bin(char *str, stack_t * stack)
+{
+    int first_time;
+    char *opstr;
+    op_t op;                    /* operator/operand */
+    int dnum;
+    int ret = MLAN_STATUS_SUCCESS;
+
+    memset(stack, 0, sizeof(stack_t));
+    first_time = TRUE;
+    while ((opstr = getop(str, &first_time)) != NULL) {
+        if (isdigit(*opstr)) {
+            op.type = TYPE_DNUM;
+            dnum = atoi(opstr);
+            memcpy((t_u8 *) op.val, &dnum, sizeof(dnum));
+            if (!push(stack, &op)) {
+                printf("push decimal number failed\n");
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+        } else if (*opstr == 'h') {
+            op.type = TYPE_BYTESEQ;
+            parse_hex(opstr, op.val);
+            if (!push(stack, &op)) {
+                printf("push byte sequence failed\n");
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+        } else if (!strcmp(opstr, "==")) {
+            op.type = TYPE_EQ;
+            if (!push(stack, &op)) {
+                printf("push byte cmp operator failed\n");
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+        } else if (!strcmp(opstr, "=d")) {
+            op.type = TYPE_EQ_DNUM;
+            if (!push(stack, &op)) {
+                printf("push decimal cmp operator failed\n");
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+        } else if (!strcmp(opstr, "=b")) {
+            op.type = TYPE_EQ_BIT;
+            if (!push(stack, &op)) {
+                printf("push bit cmp operator failed\n");
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+        } else if (!strcmp(opstr, "&&")) {
+            op.type = TYPE_AND;
+            if (!push(stack, &op)) {
+                printf("push AND operator failed\n");
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+        } else if (!strcmp(opstr, "||")) {
+            op.type = TYPE_OR;
+            if (!push(stack, &op)) {
+                printf("push OR operator failed\n");
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+        } else {
+            printf("Unknown operand\n");
+            ret = MLAN_STATUS_FAILURE;
+            break;
+        }
+    }
+    return ret;
+}
+
+#define FILTER_BYTESEQ 		TYPE_EQ /**< byte sequence */
+#define FILTER_DNUM    		TYPE_EQ_DNUM /**< decimal number */
+#define FILTER_BITSEQ		TYPE_EQ_BIT /**< bit sequence */
+#define FILTER_TEST		FILTER_BITSEQ+1 /**< test */
+
+#define NAME_TYPE		1           /**< Field name 'type' */
+#define NAME_PATTERN		2       /**< Field name 'pattern' */
+#define NAME_OFFSET		3           /**< Field name 'offset' */
+#define NAME_NUMBYTE		4       /**< Field name 'numbyte' */
+#define NAME_REPEAT		5           /**< Field name 'repeat' */
+#define NAME_BYTE		6           /**< Field name 'byte' */
+#define NAME_MASK		7           /**< Field name 'mask' */
+#define NAME_DEST		8           /**< Field name 'dest' */
+
+static struct mef_fields
+{
+    t_s8 *name;
+              /**< Name */
+    t_s8 nameid;/**< Name Id. */
+} mef_fields[] = {
+    {
+    "type", NAME_TYPE}, {
+    "pattern", NAME_PATTERN}, {
+    "offset", NAME_OFFSET}, {
+    "numbyte", NAME_NUMBYTE}, {
+    "repeat", NAME_REPEAT}, {
+    "byte", NAME_BYTE}, {
+    "mask", NAME_MASK}, {
+    "dest", NAME_DEST}
+};
+
+/** 
+ *  @brief get filter data
+ *  
+ *  @param fp			A pointer to file stream
+ *  @param ln			A pointer to line number
+ *  @param buf			A pointer to hostcmd data
+ *  @param size			A pointer to the return size of hostcmd buffer
+ *  @return			MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+mlan_get_filter_data(FILE * fp, int *ln, t_u8 * buf, t_u16 * size)
+{
+    t_s32 errors = 0, i;
+    t_s8 line[256], *pos, *pos1;
+    t_u16 type = 0;
+    t_u32 pattern = 0;
+    t_u16 repeat = 0;
+    t_u16 offset = 0;
+    t_s8 byte_seq[50];
+    t_s8 mask_seq[50];
+    t_u16 numbyte = 0;
+    t_s8 type_find = 0;
+    t_s8 pattern_find = 0;
+    t_s8 offset_find = 0;
+    t_s8 numbyte_find = 0;
+    t_s8 repeat_find = 0;
+    t_s8 byte_find = 0;
+    t_s8 mask_find = 0;
+    t_s8 dest_find = 0;
+    t_s8 dest_seq[50];
+
+    *size = 0;
+    while ((pos = mlan_config_get_line(line, sizeof(line), ln))) {
+        if (strcmp(pos, "}") == 0) {
+            break;
+        }
+        pos1 = strchr(pos, '=');
+        if (pos1 == NULL) {
+            printf("Line %d: Invalid mef_filter line '%s'\n", *ln, pos);
+            errors++;
+            continue;
+        }
+        *pos1++ = '\0';
+        for (i = 0; i < NELEMENTS(mef_fields); i++) {
+            if (strncmp(pos, mef_fields[i].name, strlen(mef_fields[i].name)) ==
+                0) {
+                switch (mef_fields[i].nameid) {
+                case NAME_TYPE:
+                    type = a2hex_or_atoi(pos1);
+                    if ((type != FILTER_DNUM) && (type != FILTER_BYTESEQ)
+                        && (type != FILTER_BITSEQ) && (type != FILTER_TEST)) {
+                        printf("Invalid filter type:%d\n", type);
+                        return MLAN_STATUS_FAILURE;
+                    }
+                    type_find = 1;
+                    break;
+                case NAME_PATTERN:
+                    pattern = a2hex_or_atoi(pos1);
+                    pattern_find = 1;
+                    break;
+                case NAME_OFFSET:
+                    offset = a2hex_or_atoi(pos1);
+                    offset_find = 1;
+                    break;
+                case NAME_NUMBYTE:
+                    numbyte = a2hex_or_atoi(pos1);
+                    numbyte_find = 1;
+                    break;
+                case NAME_REPEAT:
+                    repeat = a2hex_or_atoi(pos1);
+                    repeat_find = 1;
+                    break;
+                case NAME_BYTE:
+                    memset(byte_seq, 0, sizeof(byte_seq));
+                    strcpy(byte_seq, pos1);
+                    byte_find = 1;
+                    break;
+                case NAME_MASK:
+                    memset(mask_seq, 0, sizeof(mask_seq));
+                    strcpy(mask_seq, pos1);
+                    mask_find = 1;
+                    break;
+                case NAME_DEST:
+                    memset(dest_seq, 0, sizeof(dest_seq));
+                    strcpy(dest_seq, pos1);
+                    dest_find = 1;
+                    break;
+                }
+                break;
+            }
+        }
+        if (i == NELEMENTS(mef_fields)) {
+            printf("Line %d: unknown mef field '%s'.\n", *line, pos);
+            errors++;
+        }
+    }
+    if (type_find == 0) {
+        printf("Can not find filter type\n");
+        return MLAN_STATUS_FAILURE;
+    }
+    switch (type) {
+    case FILTER_DNUM:
+        if (!pattern_find || !offset_find || !numbyte_find) {
+            printf
+                ("Missing field for FILTER_DNUM: pattern=%d,offset=%d,numbyte=%d\n",
+                 pattern_find, offset_find, numbyte_find);
+            return MLAN_STATUS_FAILURE;
+        }
+        memset(line, 0, sizeof(line));
+        sprintf(line, "%ld %d %d =d ", pattern, offset, numbyte);
+        break;
+    case FILTER_BYTESEQ:
+        if (!byte_find || !offset_find || !repeat_find) {
+            printf
+                ("Missing field for FILTER_BYTESEQ: byte=%d,offset=%d,repeat=%d\n",
+                 byte_find, offset_find, repeat_find);
+            return MLAN_STATUS_FAILURE;
+        }
+        memset(line, 0, sizeof(line));
+        sprintf(line, "%d h%s %d == ", repeat, byte_seq, offset);
+        break;
+    case FILTER_BITSEQ:
+        if (!byte_find || !offset_find || !mask_find) {
+            printf
+                ("Missing field for FILTER_BYTESEQ: byte=%d,offset=%d,repeat=%d\n",
+                 byte_find, offset_find, mask_find);
+            return MLAN_STATUS_FAILURE;
+        }
+        if (strlen(byte_seq) != strlen(mask_seq)) {
+            printf("byte string's length is different with mask's length!\n");
+            return MLAN_STATUS_FAILURE;
+        }
+        memset(line, 0, sizeof(line));
+        sprintf(line, "h%s %d h%s =b ", byte_seq, offset, mask_seq);
+        break;
+    case FILTER_TEST:
+        if (!byte_find || !offset_find || !repeat_find || !dest_find) {
+            printf
+                ("Missing field for FILTER_TEST: byte=%d,offset=%d,repeat=%d,dest=%d\n",
+                 byte_find, offset_find, repeat_find, dest_find);
+            return MLAN_STATUS_FAILURE;
+        }
+        memset(line, 0, sizeof(line));
+        sprintf(line, "h%s %d h%s %d ", dest_seq, repeat, byte_seq, offset);
+        break;
+    }
+    memcpy(buf, line, strlen(line));
+    *size = strlen(line);
+    return MLAN_STATUS_SUCCESS;
+}
+
+#define NAME_MODE	1       /**< Field name 'mode' */
+#define NAME_ACTION	2       /**< Field name 'action' */
+#define NAME_FILTER_NUM	3   /**< Field name 'filter_num' */
+#define NAME_RPN	4       /**< Field name 'RPN' */
+static struct mef_entry_fields
+{
+    t_s8 *name;
+              /**< Name */
+    t_s8 nameid;/**< Name id */
+} mef_entry_fields[] = {
+    {
+    "mode", NAME_MODE}, {
+    "action", NAME_ACTION}, {
+    "filter_num", NAME_FILTER_NUM}, {
+"RPN", NAME_RPN},};
+
+typedef struct _MEF_ENTRY
+{
+    /** Mode */
+    t_u8 Mode;
+    /** Size */
+    t_u8 Action;
+    /** Size of expression */
+    t_u16 ExprSize;
+} MEF_ENTRY;
+
+/** 
+ *  @brief get mef_entry data
+ *  
+ *  @param fp			A pointer to file stream
+ *  @param ln			A pointer to line number
+ *  @param buf			A pointer to hostcmd data
+ *  @param size			A pointer to the return size of hostcmd buffer
+ *  @return			MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+mlan_get_mef_entry_data(FILE * fp, int *ln, t_u8 * buf, t_u16 * size)
+{
+    t_s8 line[256], *pos, *pos1;
+    t_u8 mode, action, filter_num = 0;
+    t_s8 rpn[256];
+    t_s8 mode_find = 0;
+    t_s8 action_find = 0;
+    t_s8 filter_num_find = 0;
+    t_s8 rpn_find = 0;
+    t_s8 rpn_str[256];
+    int rpn_len = 0;
+    t_s8 filter_name[50];
+    t_s8 name_found = 0;
+    t_u16 len = 0;
+    int i;
+    int first_time = TRUE;
+    char *opstr;
+    t_s8 filter_action[10];
+    t_s32 errors = 0;
+    MEF_ENTRY *pMefEntry = (MEF_ENTRY *) buf;
+    stack_t stack;
+    while ((pos = mlan_config_get_line(line, sizeof(line), ln))) {
+        if (strcmp(pos, "}") == 0) {
+            break;
+        }
+        pos1 = strchr(pos, '=');
+        if (pos1 == NULL) {
+            printf("Line %d: Invalid mef_entry line '%s'\n", *ln, pos);
+            errors++;
+            continue;
+        }
+        *pos1++ = '\0';
+        if (!mode_find || !action_find || !filter_num_find || !rpn_find) {
+            for (i = 0; i < NELEMENTS(mef_entry_fields); i++) {
+                if (strncmp
+                    (pos, mef_entry_fields[i].name,
+                     strlen(mef_entry_fields[i].name)) == 0) {
+                    switch (mef_entry_fields[i].nameid) {
+                    case NAME_MODE:
+                        mode = a2hex_or_atoi(pos1);
+                        if (mode & ~0x7) {
+                            printf("invalid mode=%d\n", mode);
+                            return MLAN_STATUS_FAILURE;
+                        }
+                        pMefEntry->Mode = mode;
+                        mode_find = 1;
+                        break;
+                    case NAME_ACTION:
+                        action = a2hex_or_atoi(pos1);
+                        if (action & ~0xff) {
+                            printf("invalid action=%d\n", action);
+                            return MLAN_STATUS_FAILURE;
+                        }
+                        pMefEntry->Action = action;
+                        action_find = 1;
+                        break;
+                    case NAME_FILTER_NUM:
+                        filter_num = a2hex_or_atoi(pos1);
+                        filter_num_find = 1;
+                        break;
+                    case NAME_RPN:
+                        memset(rpn, 0, sizeof(rpn));
+                        strcpy(rpn, pos1);
+                        rpn_find = 1;
+                        break;
+                    }
+                    break;
+                }
+            }
+            if (i == NELEMENTS(mef_fields)) {
+                printf("Line %d: unknown mef_entry field '%s'.\n", *line, pos);
+                return MLAN_STATUS_FAILURE;
+            }
+        }
+        if (mode_find && action_find && filter_num_find && rpn_find) {
+            for (i = 0; i < filter_num; i++) {
+                opstr = getop(rpn, &first_time);
+                if (opstr == NULL)
+                    break;
+                sprintf(filter_name, "%s={", opstr);
+                name_found = 0;
+                while ((pos = mlan_config_get_line(line, sizeof(line), ln))) {
+                    if (strncmp(pos, filter_name, strlen(filter_name)) == 0) {
+                        name_found = 1;
+                        break;
+                    }
+                }
+                if (!name_found) {
+                    fprintf(stderr, "mlanconfig: %s not found in file\n",
+                            filter_name);
+                    return MLAN_STATUS_FAILURE;
+                }
+                if (MLAN_STATUS_FAILURE ==
+                    mlan_get_filter_data(fp, ln, (t_u8 *) (rpn_str + rpn_len),
+                                         &len))
+                    break;
+                rpn_len += len;
+                if (i > 0) {
+                    memcpy(rpn_str + rpn_len, filter_action,
+                           strlen(filter_action));
+                    rpn_len += strlen(filter_action);
+                }
+                opstr = getop(rpn, &first_time);
+                if (opstr == NULL)
+                    break;
+                memset(filter_action, 0, sizeof(filter_action));
+                sprintf(filter_action, "%s ", opstr);
+            }
+            /* Remove the last space */
+            if (rpn_len > 0) {
+                rpn_len--;
+                rpn_str[rpn_len] = 0;
+            }
+            if (MLAN_STATUS_FAILURE == str2bin(rpn_str, &stack)) {
+                printf("Fail on str2bin!\n");
+                return MLAN_STATUS_FAILURE;
+            }
+            *size = sizeof(MEF_ENTRY);
+            pMefEntry->ExprSize = stack.sp;
+            memmove(buf + sizeof(MEF_ENTRY), stack.byte, stack.sp);
+            *size += stack.sp;
+            break;
+        } else if (mode_find && action_find && filter_num_find &&
+                   (filter_num == 0)) {
+            pMefEntry->ExprSize = 0;
+            *size = sizeof(MEF_ENTRY);
+            break;
+        }
+    }
+    return MLAN_STATUS_SUCCESS;
+}
+
+#define MEFCFG_CMDCODE	0x009a
+/**
+ *  @brief Process mef cfg 
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_mef_cfg(int argc, char *argv[])
+{
+    int ioctl_val, subioctl_val;
+    t_s8 line[256], cmdname[256], *pos;
+    int cmdname_found = 0, name_found = 0;
+    int ln = 0;
+    int ret = MLAN_STATUS_SUCCESS;
+    int i;
+    t_u8 *buf;
+    t_u16 buf_len = 0;
+    t_u16 len;
+    struct iwreq iwr;
+    HostCmd_DS_MEF_CFG *mefcmd;
+    HostCmd_DS_GEN *hostcmd;
+
+    if (argc < 4) {
+        printf("Error: invalid no of arguments\n");
+        printf("Syntax: ./mlanconfig eth1 mefcfg <mef.conf>\n");
+        exit(1);
+    }
+    if (get_priv_ioctl("hostcmd",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+    sprintf(cmdname, "%s={", argv[2]);
+    cmdname_found = 0;
+    if ((fp = fopen(argv[3], "r")) == NULL) {
+        fprintf(stderr, "Cannot open file %s\n", argv[4]);
+        exit(1);
+    }
+
+    buf = (t_u8 *) malloc(MRVDRV_SIZE_OF_CMD_BUFFER);
+    if (buf == NULL) {
+        fclose(fp);
+        fprintf(stderr, "Cannot alloc memory\n");
+        exit(1);
+    }
+    memset(buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
+
+    hostcmd = (HostCmd_DS_GEN *) (buf);
+    hostcmd->command = MEFCFG_CMDCODE;
+    mefcmd = (HostCmd_DS_MEF_CFG *) (buf + S_DS_GEN);
+    buf_len = sizeof(HostCmd_DS_MEF_CFG) + S_DS_GEN;
+
+    while ((pos = mlan_config_get_line(line, sizeof(line), &ln))) {
+        if (strcmp(pos, cmdname) == 0) {
+            cmdname_found = 1;
+            sprintf(cmdname, "Criteria=");
+            name_found = 0;
+            while ((pos = mlan_config_get_line(line, sizeof(line), &ln))) {
+                if (strncmp(pos, cmdname, strlen(cmdname)) == 0) {
+                    name_found = 1;
+                    mefcmd->Criteria = a2hex_or_atoi(pos + strlen(cmdname));
+                    break;
+                }
+            }
+            if (!name_found) {
+                fprintf(stderr, "mlanconfig: criteria not found in file '%s'\n",
+                        argv[3]);
+                break;
+            }
+            sprintf(cmdname, "NumEntries=");
+            name_found = 0;
+            while ((pos = mlan_config_get_line(line, sizeof(line), &ln))) {
+                if (strncmp(pos, cmdname, strlen(cmdname)) == 0) {
+                    name_found = 1;
+                    mefcmd->NumEntries = a2hex_or_atoi(pos + strlen(cmdname));
+                    break;
+                }
+            }
+            if (!name_found) {
+                fprintf(stderr,
+                        "mlanconfig: NumEntries not found in file '%s'\n",
+                        argv[3]);
+                break;
+            }
+            for (i = 0; i < mefcmd->NumEntries; i++) {
+                sprintf(cmdname, "mef_entry_%d={", i);
+                name_found = 0;
+                while ((pos = mlan_config_get_line(line, sizeof(line), &ln))) {
+                    if (strncmp(pos, cmdname, strlen(cmdname)) == 0) {
+                        name_found = 1;
+                        break;
+                    }
+                }
+                if (!name_found) {
+                    fprintf(stderr, "mlanconfig: %s not found in file '%s'\n",
+                            cmdname, argv[3]);
+                    break;
+                }
+                if (MLAN_STATUS_FAILURE ==
+                    mlan_get_mef_entry_data(fp, &ln, buf + buf_len, &len)) {
+                    ret = MLAN_STATUS_FAILURE;
+                    break;
+                }
+                buf_len += len;
+            }
+            break;
+        }
+    }
+    fclose(fp);
+    /* hexdump("mef_cfg",buf,buf_len, ' '); */
+    if (!cmdname_found)
+        fprintf(stderr, "mlanconfig: cmdname '%s' not found in file '%s'\n",
+                argv[4], argv[3]);
+
+    if (!cmdname_found || !name_found) {
+        ret = MLAN_STATUS_FAILURE;
+        goto mef_exit;
+    }
+    hostcmd->size = buf_len;
+
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = buf;
+    iwr.u.data.length = buf_len;
+    iwr.u.data.flags = 0;
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        fprintf(stderr, "mlanconfig: MEFCFG is not supported by %s\n",
+                dev_name);
+        ret = MLAN_STATUS_FAILURE;
+        goto mef_exit;
+    }
+    ret = process_host_cmd_resp(buf);
+
+  mef_exit:
+    if (buf)
+        free(buf);
+    return ret;
+
+}
+
+/** 
+ *  @brief Entry function for mlanconfig
+ *  @param argc		number of arguments
+ *  @param argv     A pointer to arguments array    
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+main(int argc, char *argv[])
+{
+    t_s32 cmd;
+
+    if ((argc == 2) && (strcmp(argv[1], "-v") == 0)) {
+        fprintf(stdout, "Marvell mlanconfig version %s\n", MLANCONFIG_VER);
+        exit(0);
+    }
+    if (argc < 3) {
+        fprintf(stderr, "Invalid number of parameters!\n");
+        display_usage();
+        exit(1);
+    }
+
+    strncpy(dev_name, argv[1], IFNAMSIZ);
+
+    /* 
+     * create a socket 
+     */
+    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        fprintf(stderr, "mlanconfig: Cannot open socket.\n");
+        exit(1);
+    }
+    if (get_range() < 0) {
+        fprintf(stderr, "mlanconfig: Cannot get range.\n");
+        exit(1);
+    }
+    switch ((cmd = findcommand(NELEMENTS(commands), commands, argv[2]))) {
+    case CMD_HOSTCMD:
+        process_host_cmd(argc, argv);
+        break;
+    case CMD_MEFCFG:
+        process_mef_cfg(argc, argv);
+        break;
+    case CMD_ARPFILTER:
+        process_arpfilter(argc, argv);
+        break;
+    case CMD_CFG_DATA:
+        process_cfg_data(argc, argv);
+        break;
+    case CMD_CMD52RW:
+        process_sdcmd52rw(argc, argv);
+        break;
+    case CMD_CMD53RW:
+        process_sdcmd53rw(argc, argv);
+        break;
+    case CMD_GET_SCAN_RSP:
+        process_getscantable(argc, argv);
+        break;
+    case CMD_SET_USER_SCAN:
+        process_setuserscan(argc, argv);
+        break;
+    case CMD_ADD_TS:
+        process_addts(argc, argv);
+        break;
+    case CMD_DEL_TS:
+        process_delts(argc, argv);
+        break;
+    case CMD_QCONFIG:
+        process_qconfig(argc, argv);
+        break;
+    case CMD_QSTATS:
+        process_qstats(argc, argv);
+        break;
+    case CMD_TS_STATUS:
+        process_wmm_ts_status(argc, argv);
+        break;
+    case CMD_WMM_QSTATUS:
+        process_wmm_qstatus(argc, argv);
+        break;
+    case CMD_REGRW:
+        process_regrdwr(argc, argv);
+        break;
+    default:
+        fprintf(stderr, "Invalid command specified!\n");
+        display_usage();
+        exit(1);
+    }
+
+    return MLAN_STATUS_SUCCESS;
+}
diff --git a/wlan_src/mapp/mlanconfig/mlanconfig.h b/wlan_src/mapp/mlanconfig/mlanconfig.h
new file mode 100755
index 0000000..9f31311
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/mlanconfig.h
@@ -0,0 +1,111 @@
+/** @file  mlanconfig.h
+  *
+  * @brief This file contains definitions for application
+  * 
+  *  Copyright (C) 2008-2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+/************************************************************************
+Change log:
+     11/26/2008: initial version
+************************************************************************/
+#ifndef _MLANCONFIG_H_
+#define _MLANCONFIG_H_
+
+/** Include header files */
+#include    <stdio.h>
+#include    <ctype.h>
+#include    <unistd.h>
+#include    <string.h>
+#include    <stdlib.h>
+#include    <sys/socket.h>
+#include    <sys/ioctl.h>
+#include    <errno.h>
+#include    <linux/if.h>
+#include    <linux/wireless.h>
+#include    <sys/types.h>
+#include    <linux/if_ether.h>
+#include    <linux/byteorder/swab.h>
+#include    <time.h>
+
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+#undef BIG_ENDIAN
+#endif
+
+/** Type definition: boolean */
+typedef enum
+{ FALSE, TRUE } boolean;
+
+/**
+ * This macro specifies the attribute pack used for structure packing
+ */
+#ifndef __ATTRIB_PACK__
+#define __ATTRIB_PACK__  __attribute__((packed))
+#endif
+
+/** 16 bits byte swap */
+#define swap_byte_16(x) \
+((t_u16)((((t_u16)(x) & 0x00ffU) << 8) | \
+         (((t_u16)(x) & 0xff00U) >> 8)))
+
+/** 32 bits byte swap */
+#define swap_byte_32(x) \
+((t_u32)((((t_u32)(x) & 0x000000ffUL) << 24) | \
+         (((t_u32)(x) & 0x0000ff00UL) <<  8) | \
+         (((t_u32)(x) & 0x00ff0000UL) >>  8) | \
+         (((t_u32)(x) & 0xff000000UL) >> 24)))
+
+/** Convert to correct endian format */
+#ifdef 	BIG_ENDIAN
+/** CPU to little-endian convert for 16-bit */
+#define 	cpu_to_le16(x)	swap_byte_16(x)
+/** CPU to little-endian convert for 32-bit */
+#define		cpu_to_le32(x)  swap_byte_32(x)
+/** Little-endian to CPU convert for 16-bit */
+#define 	le16_to_cpu(x)	swap_byte_16(x)
+/** Little-endian to CPU convert for 32-bit */
+#define		le32_to_cpu(x)  swap_byte_32(x)
+#else
+/** Do nothing */
+#define		cpu_to_le16(x)	(x)
+/** Do nothing */
+#define		cpu_to_le32(x)  (x)
+/** Do nothing */
+#define 	le16_to_cpu(x)	(x)
+/** Do nothing */
+#define 	le32_to_cpu(x)	(x)
+#endif
+
+/** Character, 1 byte */
+typedef char t_s8;
+/** Unsigned character, 1 byte */
+typedef unsigned char t_u8;
+
+/** Short integer */
+typedef signed short t_s16;
+/** Unsigned short integer */
+typedef unsigned short t_u16;
+
+/** Long integer */
+typedef signed long t_s32;
+/** Unsigned long integer */
+typedef unsigned long t_u32;
+
+/** Long long integer */
+typedef signed long long t_s64;
+/** Unsigned long long integer */
+typedef unsigned long long t_u64;
+
+/** Void pointer (4-bytes) */
+typedef void t_void;
+
+/** Success */
+#define MLAN_STATUS_SUCCESS         (0)
+/** Failure */
+#define MLAN_STATUS_FAILURE         (-1)
+
+t_s8 *mlan_config_get_line(t_s8 * s, t_s32 size, int *line);
+int get_priv_ioctl(char *ioctl_name, int *ioctl_val, int *subioctl_val);
+int fparse_for_hex(t_u8 * dst);
+
+#endif /* _MLANCONFIG_H_ */
diff --git a/wlan_src/mapp/mlanconfig/mlanhostcmd.c b/wlan_src/mapp/mlanconfig/mlanhostcmd.c
new file mode 100755
index 0000000..feb5a5d
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/mlanhostcmd.c
@@ -0,0 +1,822 @@
+/** @file  mlanhostcmd.c
+  *
+  * @brief This file contains mlanconfig helper functions
+  * 
+  *  Copyright (C) 2008-2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+/************************************************************************
+Change log:
+     11/26/2008: initial version
+************************************************************************/
+
+#include	"mlanconfig.h"
+#include	"mlanhostcmd.h"
+
+#ifndef MIN
+/** Find minimum value */
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif /* MIN */
+
+/********************************************************
+		Local Variables
+********************************************************/
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/********************************************************
+		Local Functions
+********************************************************/
+/** 
+ *  @brief get hostcmd data
+ *  
+ *  @param ln			A pointer to line number
+ *  @param buf			A pointer to hostcmd data
+ *  @param size			A pointer to the return size of hostcmd buffer
+ *  @return      		MLAN_STATUS_SUCCESS
+ */
+static int
+mlan_get_hostcmd_data(int *ln, t_u8 * buf, t_u16 * size)
+{
+    t_s32 errors = 0, i;
+    t_s8 line[256], *pos, *pos1, *pos2, *pos3;
+    t_u16 len;
+
+    while ((pos = mlan_config_get_line(line, sizeof(line), ln))) {
+        (*ln)++;
+        if (strcmp(pos, "}") == 0) {
+            break;
+        }
+
+        pos1 = strchr(pos, ':');
+        if (pos1 == NULL) {
+            printf("Line %d: Invalid hostcmd line '%s'\n", *ln, pos);
+            errors++;
+            continue;
+        }
+        *pos1++ = '\0';
+
+        pos2 = strchr(pos1, '=');
+        if (pos2 == NULL) {
+            printf("Line %d: Invalid hostcmd line '%s'\n", *ln, pos);
+            errors++;
+            continue;
+        }
+        *pos2++ = '\0';
+
+        len = a2hex_or_atoi(pos1);
+        if (len < 1 || len > MRVDRV_SIZE_OF_CMD_BUFFER) {
+            printf("Line %d: Invalid hostcmd line '%s'\n", *ln, pos);
+            errors++;
+            continue;
+        }
+
+        *size += len;
+
+        if (*pos2 == '"') {
+            pos2++;
+            if ((pos3 = strchr(pos2, '"')) == NULL) {
+                printf("Line %d: invalid quotation '%s'\n", *ln, pos);
+                errors++;
+                continue;
+            }
+            *pos3 = '\0';
+            memset(buf, 0, len);
+            memmove(buf, pos2, MIN(strlen(pos2), len));
+            buf += len;
+        } else if (*pos2 == '\'') {
+            pos2++;
+            if ((pos3 = strchr(pos2, '\'')) == NULL) {
+                printf("Line %d: invalid quotation '%s'\n", *ln, pos);
+                errors++;
+                continue;
+            }
+            *pos3 = ',';
+            for (i = 0; i < len; i++) {
+                if ((pos3 = strchr(pos2, ',')) != NULL) {
+                    *pos3 = '\0';
+                    *buf++ = (t_u8) a2hex_or_atoi(pos2);
+                    pos2 = pos3 + 1;
+                } else
+                    *buf++ = 0;
+            }
+        } else if (*pos2 == '{') {
+            t_u16 tlvlen = 0, tmp_tlvlen;
+            mlan_get_hostcmd_data(ln, buf + len, &tlvlen);
+            tmp_tlvlen = tlvlen;
+            while (len--) {
+                *buf++ = (t_u8) (tmp_tlvlen & 0xff);
+                tmp_tlvlen >>= 8;
+            }
+            *size += tlvlen;
+            buf += tlvlen;
+        } else {
+            t_u32 value = a2hex_or_atoi(pos2);
+            while (len--) {
+                *buf++ = (t_u8) (value & 0xff);
+                value >>= 8;
+            }
+        }
+    }
+    return MLAN_STATUS_SUCCESS;
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+/** 
+ *  @brief convert char to hex integer
+ * 
+ *  @param chr 		char to convert
+ *  @return      	hex integer or 0
+ */
+int
+hexval(t_s32 chr)
+{
+    if (chr >= '0' && chr <= '9')
+        return chr - '0';
+    if (chr >= 'A' && chr <= 'F')
+        return chr - 'A' + 10;
+    if (chr >= 'a' && chr <= 'f')
+        return chr - 'a' + 10;
+
+    return 0;
+}
+
+/** 
+ *  @brief Hump hex data
+ *
+ *  @param prompt	A pointer prompt buffer
+ *  @param p		A pointer to data buffer
+ *  @param len		the len of data buffer
+ *  @param delim	delim char
+ *  @return            	hex integer
+ */
+t_void
+hexdump(t_s8 * prompt, t_void * p, t_s32 len, t_s8 delim)
+{
+    t_s32 i;
+    t_u8 *s = p;
+
+    if (prompt) {
+        printf("%s: len=%d\n", prompt, (int) len);
+    }
+    for (i = 0; i < len; i++) {
+        if (i != len - 1)
+            printf("%02x%c", *s++, delim);
+        else
+            printf("%02x\n", *s);
+        if ((i + 1) % 16 == 0)
+            printf("\n");
+    }
+}
+
+/** 
+ *  @brief convert char to hex integer
+ *
+ *  @param chr		char
+ *  @return            	hex integer
+ */
+t_u8
+hexc2bin(t_s8 chr)
+{
+    if (chr >= '0' && chr <= '9')
+        chr -= '0';
+    else if (chr >= 'A' && chr <= 'F')
+        chr -= ('A' - 10);
+    else if (chr >= 'a' && chr <= 'f')
+        chr -= ('a' - 10);
+
+    return chr;
+}
+
+/** 
+ *  @brief convert string to hex integer
+ *
+ *  @param s		A pointer string buffer
+ *  @return            	hex integer
+ */
+t_u32
+a2hex(t_s8 * s)
+{
+    t_u32 val = 0;
+
+    if (!strncasecmp("0x", s, 2)) {
+        s += 2;
+    }
+
+    while (*s && isxdigit(*s)) {
+        val = (val << 4) + hexc2bin(*s++);
+    }
+
+    return val;
+}
+
+/* 
+ *  @brief convert String to integer
+ *  
+ *  @param value	A pointer to string
+ *  @return             integer
+ */
+t_u32
+a2hex_or_atoi(t_s8 * value)
+{
+    if (value[0] == '0' && (value[1] == 'X' || value[1] == 'x')) {
+        return a2hex(value + 2);
+    } else if (isdigit(*value)) {
+        return atoi(value);
+    } else {
+        return *value;
+    }
+}
+
+/** 
+ *  @brief convert string to hex
+ * 
+ *  @param ptr		A pointer to data buffer
+ *  @param chr 		A pointer to return integer
+ *  @return      	A pointer to next data field
+ */
+t_s8 *
+convert2hex(t_s8 * ptr, t_u8 * chr)
+{
+    t_u8 val;
+
+    for (val = 0; *ptr && isxdigit(*ptr); ptr++) {
+        val = (val * 16) + hexval(*ptr);
+    }
+
+    *chr = val;
+
+    return ptr;
+}
+
+/** 
+ *  @brief Check the Hex String
+ *  @param s  A pointer to the string      
+ *  @return   MLAN_STATUS_SUCCESS --HexString, MLAN_STATUS_FAILURE --not HexString
+ */
+int
+ishexstring(t_s8 * s)
+{
+    int ret = MLAN_STATUS_FAILURE;
+    t_s32 tmp;
+
+    if (!strncasecmp("0x", s, 2)) {
+        s += 2;
+    }
+    while (*s) {
+        tmp = toupper(*s);
+        if (tmp >= 'A' && tmp <= 'F' || (tmp >= '0' && tmp <= '9')) {
+            ret = MLAN_STATUS_SUCCESS;
+        } else {
+            ret = MLAN_STATUS_FAILURE;
+            break;
+        }
+        s++;
+    }
+
+    return ret;
+}
+
+/** 
+ *  @brief Convert String to Integer
+ *  @param buf      A pointer to the string      
+ *  @return         Integer
+ */
+int
+atoval(t_s8 * buf)
+{
+    if (!strncasecmp(buf, "0x", 2))
+        return a2hex(buf + 2);
+    else if (!ishexstring(buf))
+        return a2hex(buf);
+    else
+        return atoi(buf);
+}
+
+/** 
+ *  @brief Prepare host-command buffer 
+ *  @param cmd_name	Command name
+ *  @param buf		A pointer to comand buffer    
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+prepare_host_cmd_buffer(char *cmd_name, t_u8 * buf)
+{
+    t_s8 line[256], cmdname[256], *pos, cmdcode[10];
+    HostCmd_DS_GEN *hostcmd;
+    int ln = 0;
+    int cmdname_found = 0, cmdcode_found = 0;
+
+    memset(buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
+    hostcmd = (HostCmd_DS_GEN *) buf;
+    hostcmd->command = 0xffff;
+
+    sprintf(cmdname, "%s={", cmd_name);
+    cmdname_found = 0;
+    while ((pos = mlan_config_get_line(line, sizeof(line), &ln))) {
+        if (strcmp(pos, cmdname) == 0) {
+            cmdname_found = 1;
+            sprintf(cmdcode, "CmdCode=");
+            cmdcode_found = 0;
+            while ((pos = mlan_config_get_line(line, sizeof(line), &ln))) {
+                if (strncmp(pos, cmdcode, strlen(cmdcode)) == 0) {
+                    cmdcode_found = 1;
+                    hostcmd->command = a2hex_or_atoi(pos + strlen(cmdcode));
+                    hostcmd->size = S_DS_GEN;
+                    mlan_get_hostcmd_data(&ln, buf + hostcmd->size,
+                                          &hostcmd->size);
+                    break;
+                }
+            }
+            if (!cmdcode_found) {
+                fprintf(stderr, "mlanconfig: CmdCode not found in conf file\n");
+                return MLAN_STATUS_FAILURE;
+            }
+            break;
+        }
+    }
+
+    if (!cmdname_found) {
+        fprintf(stderr, "mlanconfig: cmdname '%s' is not found in conf file\n",
+                cmd_name);
+        return MLAN_STATUS_FAILURE;
+    }
+
+    hostcmd->seq_num = 0;
+    hostcmd->result = 0;
+    hostcmd->command = cpu_to_le16(hostcmd->command);
+    hostcmd->size = cpu_to_le16(hostcmd->size);
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** Config data header length */
+#define CFG_DATA_HEADER_LEN 6
+
+/** 
+ *  @brief Prepare cfg-data buffer 
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *  @param buf      A pointer to comand buffer    
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+prepare_cfg_data_buffer(int argc, char *argv[], t_u8 * buf)
+{
+    int ln = 0, type;
+    HostCmd_DS_GEN *hostcmd;
+    HostCmd_DS_802_11_CFG_DATA *pcfg_data;
+
+    memset(buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
+    hostcmd = (HostCmd_DS_GEN *) buf;
+    hostcmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA);
+    pcfg_data = (HostCmd_DS_802_11_CFG_DATA *) (buf + S_DS_GEN);
+    pcfg_data->action = (argc == 4) ? HostCmd_ACT_GEN_GET : HostCmd_ACT_GEN_SET;
+    type = atoi(argv[3]);
+    if ((type < 1) || (type > 3)) {
+        fprintf(stderr, "mlanconfig: Invalid register type\n");
+        return MLAN_STATUS_FAILURE;
+    } else {
+        pcfg_data->type = type;
+    }
+    if (argc == 5) {
+        ln = fparse_for_hex(pcfg_data->data);
+    }
+    pcfg_data->data_len = ln;
+    hostcmd->size =
+        cpu_to_le16(pcfg_data->data_len + S_DS_GEN + CFG_DATA_HEADER_LEN);
+    pcfg_data->data_len = cpu_to_le16(pcfg_data->data_len);
+    pcfg_data->type = cpu_to_le16(pcfg_data->type);
+    pcfg_data->action = cpu_to_le16(pcfg_data->action);
+
+    hostcmd->seq_num = 0;
+    hostcmd->result = 0;
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Process host_cmd response
+ *  @param buf		A pointer to the response buffer
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+process_host_cmd_resp(t_u8 * buf)
+{
+    HostCmd_DS_GEN *hostcmd = (HostCmd_DS_GEN *) buf;
+    int ret = MLAN_STATUS_SUCCESS;
+
+    hostcmd->command = le16_to_cpu(hostcmd->command);
+    hostcmd->size = le16_to_cpu(hostcmd->size);
+
+    hostcmd->command &= ~HostCmd_RET_BIT;
+    if (!le16_to_cpu(hostcmd->result)) {
+        switch (hostcmd->command) {
+        case HostCmd_CMD_CFG_DATA:
+            {
+                HostCmd_DS_802_11_CFG_DATA *pstcfgData =
+                    (HostCmd_DS_802_11_CFG_DATA *) (buf + S_DS_GEN);
+                pstcfgData->data_len = le16_to_cpu(pstcfgData->data_len);
+                pstcfgData->action = le16_to_cpu(pstcfgData->action);
+
+                if (pstcfgData->action == HostCmd_ACT_GEN_GET) {
+                    hexdump("cfgdata", pstcfgData->data, pstcfgData->data_len,
+                            ' ');
+                }
+                break;
+            }
+        case HostCmd_CMD_802_11_TPC_ADAPT_REQ:
+            {
+                mlan_ioctl_11h_tpc_resp *tpcIoctlResp =
+                    (mlan_ioctl_11h_tpc_resp *) (buf + S_DS_GEN);
+                if (tpcIoctlResp->status_code == 0) {
+                    printf
+                        ("tpcrequest:  txPower(%d), linkMargin(%d), rssi(%d)\n",
+                         tpcIoctlResp->tx_power, tpcIoctlResp->link_margin,
+                         tpcIoctlResp->rssi);
+                } else {
+                    printf("tpcrequest:  failure, status = %d\n",
+                           tpcIoctlResp->status_code);
+                }
+                break;
+            }
+        case HostCmd_CMD_802_11_CRYPTO:
+            {
+                t_u16 alg =
+                    le16_to_cpu((t_u16) * (buf + S_DS_GEN + sizeof(t_u16)));
+                if (alg != CIPHER_TEST_AES_CCM) {
+                    HostCmd_DS_802_11_CRYPTO *cmd =
+                        (HostCmd_DS_802_11_CRYPTO *) (buf + S_DS_GEN);
+                    cmd->encdec = le16_to_cpu(cmd->encdec);
+                    cmd->algorithm = le16_to_cpu(cmd->algorithm);
+                    cmd->key_IV_length = le16_to_cpu(cmd->key_IV_length);
+                    cmd->key_length = le16_to_cpu(cmd->key_length);
+                    cmd->data.header.type = le16_to_cpu(cmd->data.header.type);
+                    cmd->data.header.len = le16_to_cpu(cmd->data.header.len);
+
+                    printf
+                        ("crypto_result: encdec=%d algorithm=%d,KeyIVLen=%d, KeyLen=%d,dataLen=%d\n",
+                         cmd->encdec, cmd->algorithm, cmd->key_IV_length,
+                         cmd->key_length, cmd->data.header.len);
+                    hexdump("KeyIV", cmd->keyIV, cmd->key_IV_length, ' ');
+                    hexdump("Key", cmd->key, cmd->key_length, ' ');
+                    hexdump("Data", cmd->data.data, cmd->data.header.len, ' ');
+                } else {
+                    HostCmd_DS_802_11_CRYPTO_AES_CCM *cmd_aes_ccm =
+                        (HostCmd_DS_802_11_CRYPTO_AES_CCM *) (buf + S_DS_GEN);
+
+                    cmd_aes_ccm->encdec = le16_to_cpu(cmd_aes_ccm->encdec);
+                    cmd_aes_ccm->algorithm =
+                        le16_to_cpu(cmd_aes_ccm->algorithm);
+                    cmd_aes_ccm->key_length =
+                        le16_to_cpu(cmd_aes_ccm->key_length);
+                    cmd_aes_ccm->nonce_length =
+                        le16_to_cpu(cmd_aes_ccm->nonce_length);
+                    cmd_aes_ccm->AAD_length =
+                        le16_to_cpu(cmd_aes_ccm->AAD_length);
+                    cmd_aes_ccm->data.header.type =
+                        le16_to_cpu(cmd_aes_ccm->data.header.type);
+                    cmd_aes_ccm->data.header.len =
+                        le16_to_cpu(cmd_aes_ccm->data.header.len);
+
+                    printf
+                        ("crypto_result: encdec=%d algorithm=%d,KeyLen=%d, NonceLen=%d,AADLen=%d,dataLen=%d\n",
+                         cmd_aes_ccm->encdec, cmd_aes_ccm->algorithm,
+                         cmd_aes_ccm->key_length, cmd_aes_ccm->nonce_length,
+                         cmd_aes_ccm->AAD_length, cmd_aes_ccm->data.header.len);
+                    hexdump("Key", cmd_aes_ccm->key, cmd_aes_ccm->key_length,
+                            ' ');
+                    hexdump("Nonce", cmd_aes_ccm->nonce,
+                            cmd_aes_ccm->nonce_length, ' ');
+                    hexdump("AAD", cmd_aes_ccm->AAD, cmd_aes_ccm->AAD_length,
+                            ' ');
+                    hexdump("Data", cmd_aes_ccm->data.data,
+                            cmd_aes_ccm->data.header.len, ' ');
+                }
+                break;
+            }
+        case HostCmd_CMD_802_11_AUTO_TX:
+            {
+                HostCmd_DS_802_11_AUTO_TX *at =
+                    (HostCmd_DS_802_11_AUTO_TX *) (buf + S_DS_GEN);
+
+                if (le16_to_cpu(at->action) == HostCmd_ACT_GEN_GET) {
+                    if (S_DS_GEN + sizeof(at->action) == hostcmd->size) {
+                        printf("auto_tx not configured\n");
+                    } else {
+                        MrvlIEtypesHeader_t *header = &at->auto_tx.header;
+                        header->type = le16_to_cpu(header->type);
+                        header->len = le16_to_cpu(header->len);
+                        if ((S_DS_GEN + sizeof(at->action) +
+                             sizeof(MrvlIEtypesHeader_t) + header->len ==
+                             hostcmd->size) &&
+                            (header->type == TLV_TYPE_AUTO_TX)) {
+                            AutoTx_MacFrame_t *atmf =
+                                &at->auto_tx.auto_tx_mac_frame;
+                            printf("Interval: %d second(s)\n",
+                                   le16_to_cpu(atmf->interval));
+                            printf("Priority: %#x\n", atmf->priority);
+                            printf("Frame Length: %d\n",
+                                   le16_to_cpu(atmf->frame_len));
+                            printf
+                                ("Dest Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                                 atmf->dest_mac_addr[0], atmf->dest_mac_addr[1],
+                                 atmf->dest_mac_addr[2], atmf->dest_mac_addr[3],
+                                 atmf->dest_mac_addr[4],
+                                 atmf->dest_mac_addr[5]);
+                            printf
+                                ("Src Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                                 atmf->src_mac_addr[0], atmf->src_mac_addr[1],
+                                 atmf->src_mac_addr[2], atmf->src_mac_addr[3],
+                                 atmf->src_mac_addr[4], atmf->src_mac_addr[5]);
+
+                            hexdump("Frame Payload", atmf->payload,
+                                    le16_to_cpu(atmf->frame_len) -
+                                    MLAN_MAC_ADDR_LENGTH * 2, ' ');
+                        } else {
+                            printf("incorrect auto_tx command response\n");
+                        }
+                    }
+                }
+                break;
+            }
+        case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
+            {
+                HostCmd_DS_802_11_SUBSCRIBE_EVENT *se =
+                    (HostCmd_DS_802_11_SUBSCRIBE_EVENT *) (buf + S_DS_GEN);
+                if (le16_to_cpu(se->action) == HostCmd_ACT_GEN_GET) {
+                    int len =
+                        S_DS_GEN + sizeof(HostCmd_DS_802_11_SUBSCRIBE_EVENT);
+                    printf("\nEvent\t\tValue\tFreq\tsubscribed\n\n");
+                    while (len < hostcmd->size) {
+                        MrvlIEtypesHeader_t *header =
+                            (MrvlIEtypesHeader_t *) (buf + len);
+                        switch (le16_to_cpu(header->type)) {
+                        case TLV_TYPE_RSSI_LOW:
+                            {
+                                MrvlIEtypes_RssiThreshold_t *low_rssi =
+                                    (MrvlIEtypes_RssiThreshold_t *) (buf + len);
+                                printf("Beacon Low RSSI\t%d\t%d\t%s\n",
+                                       low_rssi->RSSI_value,
+                                       low_rssi->RSSI_freq,
+                                       (le16_to_cpu(se->events) & 0x0001) ?
+                                       "yes" : "no");
+                                break;
+                            }
+                        case TLV_TYPE_SNR_LOW:
+                            {
+                                MrvlIEtypes_SnrThreshold_t *low_snr =
+                                    (MrvlIEtypes_SnrThreshold_t *) (buf + len);
+                                printf("Beacon Low SNR\t%d\t%d\t%s\n",
+                                       low_snr->SNR_value,
+                                       low_snr->SNR_freq,
+                                       (le16_to_cpu(se->events) & 0x0002) ?
+                                       "yes" : "no");
+                                break;
+                            }
+                        case TLV_TYPE_FAILCOUNT:
+                            {
+                                MrvlIEtypes_FailureCount_t *failure_count =
+                                    (MrvlIEtypes_FailureCount_t *) (buf + len);
+                                printf("Failure Count\t%d\t%d\t%s\n",
+                                       failure_count->fail_value,
+                                       failure_count->fail_freq,
+                                       (le16_to_cpu(se->events) & 0x0004) ?
+                                       "yes" : "no");
+                                break;
+                            }
+                        case TLV_TYPE_BCNMISS:
+                            {
+                                MrvlIEtypes_BeaconsMissed_t *bcn_missed =
+                                    (MrvlIEtypes_BeaconsMissed_t *) (buf + len);
+                                printf("Beacon Missed\t%d\tN/A\t%s\n",
+                                       bcn_missed->beacon_missed,
+                                       (le16_to_cpu(se->events) & 0x0008) ?
+                                       "yes" : "no");
+                                break;
+                            }
+                        case TLV_TYPE_RSSI_HIGH:
+                            {
+                                MrvlIEtypes_RssiThreshold_t *high_rssi =
+                                    (MrvlIEtypes_RssiThreshold_t *) (buf + len);
+                                printf("Bcn High RSSI\t%d\t%d\t%s\n",
+                                       high_rssi->RSSI_value,
+                                       high_rssi->RSSI_freq,
+                                       (le16_to_cpu(se->events) & 0x0010) ?
+                                       "yes" : "no");
+                                break;
+                            }
+
+                        case TLV_TYPE_SNR_HIGH:
+                            {
+                                MrvlIEtypes_SnrThreshold_t *high_snr =
+                                    (MrvlIEtypes_SnrThreshold_t *) (buf + len);
+                                printf("Beacon High SNR\t%d\t%d\t%s\n",
+                                       high_snr->SNR_value,
+                                       high_snr->SNR_freq,
+                                       (le16_to_cpu(se->events) & 0x0020) ?
+                                       "yes" : "no");
+                                break;
+                            }
+                        case TLV_TYPE_RSSI_LOW_DATA:
+                            {
+                                MrvlIEtypes_RssiThreshold_t *low_rssi =
+                                    (MrvlIEtypes_RssiThreshold_t *) (buf + len);
+                                printf("Data Low RSSI\t%d\t%d\t%s\n",
+                                       low_rssi->RSSI_value,
+                                       low_rssi->RSSI_freq,
+                                       (le16_to_cpu(se->events) & 0x0040) ?
+                                       "yes" : "no");
+                                break;
+                            }
+                        case TLV_TYPE_SNR_LOW_DATA:
+                            {
+                                MrvlIEtypes_SnrThreshold_t *low_snr =
+                                    (MrvlIEtypes_SnrThreshold_t *) (buf + len);
+                                printf("Data Low SNR\t%d\t%d\t%s\n",
+                                       low_snr->SNR_value,
+                                       low_snr->SNR_freq,
+                                       (le16_to_cpu(se->events) & 0x0080) ?
+                                       "yes" : "no");
+                                break;
+                            }
+                        case TLV_TYPE_RSSI_HIGH_DATA:
+                            {
+                                MrvlIEtypes_RssiThreshold_t *high_rssi =
+                                    (MrvlIEtypes_RssiThreshold_t *) (buf + len);
+                                printf("Data High RSSI\t%d\t%d\t%s\n",
+                                       high_rssi->RSSI_value,
+                                       high_rssi->RSSI_freq,
+                                       (le16_to_cpu(se->events) & 0x0100) ?
+                                       "yes" : "no");
+                                break;
+                            }
+                        case TLV_TYPE_SNR_HIGH_DATA:
+                            {
+                                MrvlIEtypes_SnrThreshold_t *high_snr =
+                                    (MrvlIEtypes_SnrThreshold_t *) (buf + len);
+                                printf("Data High SNR\t%d\t%d\t%s\n",
+                                       high_snr->SNR_value,
+                                       high_snr->SNR_freq,
+                                       (le16_to_cpu(se->events) & 0x0200) ?
+                                       "yes" : "no");
+                                break;
+                            }
+                        case TLV_TYPE_LINK_QUALITY:
+                            {
+                                MrvlIEtypes_LinkQuality_t *link_qual =
+                                    (MrvlIEtypes_LinkQuality_t *) (buf + len);
+                                printf("Link Quality Parameters:\n");
+                                printf("------------------------\n");
+                                printf("Link Quality Event Subscribed\t%s\n",
+                                       (le16_to_cpu(se->events) & 0x0400) ?
+                                       "yes" : "no");
+                                printf("Link SNR Threshold   = %d\n",
+                                       le16_to_cpu(link_qual->link_SNR_thrs));
+                                printf("Link SNR Frequency   = %d\n",
+                                       le16_to_cpu(link_qual->link_SNR_freq));
+                                printf("Min Rate Value       = %d\n",
+                                       le16_to_cpu(link_qual->min_rate_val));
+                                printf("Min Rate Frequency   = %d\n",
+                                       le16_to_cpu(link_qual->min_rate_freq));
+                                printf("Tx Latency Value     = %ld\n",
+                                       le32_to_cpu(link_qual->tx_latency_val));
+                                printf("Tx Latency Threshold = %ld\n",
+                                       le32_to_cpu(link_qual->tx_latency_thrs));
+
+                                break;
+                            }
+                        case TLV_TYPE_PRE_BEACON_LOST:
+                            {
+                                MrvlIEtypes_PreBeaconLost_t *pre_bcn_lost =
+                                    (MrvlIEtypes_PreBeaconLost_t *) (buf + len);
+                                printf("------------------------\n");
+                                printf("Pre-Beacon Lost Event Subscribed\t%s\n",
+                                       (le16_to_cpu(se->events) & 0x0800) ?
+                                       "yes" : "no");
+                                printf("Pre-Beacon Lost: %d\n",
+                                       pre_bcn_lost->pre_beacon_lost);
+
+                                break;
+                            }
+                        default:
+                            printf
+                                ("unknown subscribed event TLV Type=%#x, Len=%d\n",
+                                 le16_to_cpu(header->type),
+                                 le16_to_cpu(header->len));
+                            break;
+                        }
+                        len +=
+                            sizeof(MrvlIEtypesHeader_t) +
+                            le16_to_cpu(header->len);
+                    }
+                }
+                break;
+            }
+        case HostCmd_CMD_MAC_REG_ACCESS:
+        case HostCmd_CMD_BBP_REG_ACCESS:
+        case HostCmd_CMD_RF_REG_ACCESS:
+        case HostCmd_CMD_PMIC_REG_ACCESS:
+        case HostCmd_CMD_CAU_REG_ACCESS:
+            {
+                HostCmd_DS_REG *preg = (HostCmd_DS_REG *) (buf + S_DS_GEN);
+                preg->action = le16_to_cpu(preg->action);
+                if (preg->action == HostCmd_ACT_GEN_GET) {
+                    preg->value = le32_to_cpu(preg->value);
+                    printf("value = 0x%08lx\n", preg->value);
+                }
+                break;
+            }
+
+        default:
+            printf("HOSTCMD_RESP: ReturnCode=%#04x, Result=%#04x\n",
+                   le16_to_cpu(hostcmd->command), le16_to_cpu(hostcmd->result));
+            break;
+        }
+    } else {
+        printf("HOSTCMD failed: ReturnCode=%#04x, Result=%#04x\n",
+               le16_to_cpu(hostcmd->command), le16_to_cpu(hostcmd->result));
+    }
+    return ret;
+}
+
+/** 
+ *  @brief Prepare ARP filter buffer 
+ *  @param buf		A pointer to the buffer    
+ *  @param length	A pointer to the length of buffer     
+ *  @return      	MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+prepare_arp_filter_buffer(t_u8 * buf, t_u16 * length)
+{
+    t_s8 line[256], *pos;
+    int ln = 0;
+    int ret = MLAN_STATUS_SUCCESS;
+    int arpfilter_found = 0;
+
+    memset(buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
+    while ((pos = mlan_config_get_line(line, sizeof(line), &ln))) {
+        if (strcmp(pos, "arpfilter={") == 0) {
+            arpfilter_found = 1;
+            mlan_get_hostcmd_data(&ln, buf, length);
+            break;
+        }
+    }
+    if (!arpfilter_found) {
+        fprintf(stderr, "mlanconfig: 'arpfilter' not found in conf file");
+        ret = MLAN_STATUS_FAILURE;
+    }
+    return ret;
+}
+
+/** 
+ *  @brief Prepare the hostcmd for register access
+ *  @param type     Register type
+ *  @param offset   Register offset
+ *  @param value    Pointer to value (NULL for read)
+ *  @param buf      Pointer to hostcmd buffer
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+prepare_hostcmd_regrdwr(t_u32 type, t_u32 offset, t_u32 * value, t_u8 * buf)
+{
+    HostCmd_DS_GEN *hostcmd;
+    HostCmd_DS_REG *preg;
+
+    hostcmd = (HostCmd_DS_GEN *) buf;
+    switch (type) {
+    case 1:
+        hostcmd->command = cpu_to_le16(HostCmd_CMD_MAC_REG_ACCESS);
+        break;
+    case 2:
+        hostcmd->command = cpu_to_le16(HostCmd_CMD_BBP_REG_ACCESS);
+        break;
+    case 3:
+        hostcmd->command = cpu_to_le16(HostCmd_CMD_RF_REG_ACCESS);
+        break;
+    case 4:
+        hostcmd->command = cpu_to_le16(HostCmd_CMD_PMIC_REG_ACCESS);
+        break;
+    case 5:
+        hostcmd->command = cpu_to_le16(HostCmd_CMD_CAU_REG_ACCESS);
+        break;
+    default:
+        printf("Invalid register set specified\n");
+        return -EINVAL;
+    }
+    preg = (HostCmd_DS_REG *) (buf + S_DS_GEN);
+    preg->action = (value) ? HostCmd_ACT_GEN_SET : HostCmd_ACT_GEN_GET;
+    preg->action = cpu_to_le16(preg->action);
+    preg->offset = cpu_to_le16((t_u16) offset);
+    if (value)
+        preg->value = cpu_to_le32(*value);
+    else
+        preg->value = 0;
+    hostcmd->size = cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_REG));
+    hostcmd->seq_num = 0;
+    hostcmd->result = 0;
+
+    return MLAN_STATUS_SUCCESS;
+}
diff --git a/wlan_src/mapp/mlanconfig/mlanhostcmd.h b/wlan_src/mapp/mlanconfig/mlanhostcmd.h
new file mode 100755
index 0000000..30412d9
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/mlanhostcmd.h
@@ -0,0 +1,333 @@
+/** @file  mlanhostcmd.h
+  *
+  * @brief This file contains command structures for mlanconfig application
+  * 
+  *  Copyright (C) 2008-2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+/************************************************************************
+Change log:
+     11/26/2008: initial version
+************************************************************************/
+#ifndef _MLANHOSTCMD_H_
+#define _MLANHOSTCMD_H_
+
+/** Find number of elements */
+#define NELEMENTS(x) (sizeof(x)/sizeof(x[0]))
+
+/** MLAN MAC Address Length */
+#define MLAN_MAC_ADDR_LENGTH     (6)
+/** Size of command buffer */
+#define MRVDRV_SIZE_OF_CMD_BUFFER		(2 * 1024)
+
+/** Command RET code, MSB is set to 1 */
+#define HostCmd_RET_BIT					0x8000
+/** General purpose action : Get */
+#define HostCmd_ACT_GEN_GET				0x0000
+/** General purpose action : Set */
+#define HostCmd_ACT_GEN_SET				0x0001
+/** General purpose action : Remove */
+#define HostCmd_ACT_GEN_REMOVE          0x0004
+
+/** Read/Write Mac register */
+#define HostCmd_CMD_MAC_REG_ACCESS            0x0019
+/** Read/Write BBP register */
+#define HostCmd_CMD_BBP_REG_ACCESS            0x001a
+/** Read/Write RF register */
+#define HostCmd_CMD_RF_REG_ACCESS             0x001b
+/** Host Command ID : PMIC register access */
+#define HostCmd_CMD_PMIC_REG_ACCESS           0x00ad
+/** Host Command ID : CAU register access */
+#define HostCmd_CMD_CAU_REG_ACCESS            0x00ed
+
+/** Host Command ID : 802.11 BG scan configuration */
+#define HostCmd_CMD_802_11_BG_SCAN_CONFIG     0x006b
+/** Host Command ID : Configuration data */
+#define HostCmd_CMD_CFG_DATA                  0x008f
+/** Host Command ID : 802.11 TPC adapt req */
+#define HostCmd_CMD_802_11_TPC_ADAPT_REQ      0x0060
+/** Host Command ID : 802.11 crypto */
+#define HostCmd_CMD_802_11_CRYPTO             0x0078
+/** Host Command ID : 802.11 auto Tx */
+#define HostCmd_CMD_802_11_AUTO_TX      	0x0082
+
+/** Host Command ID : 802.11 subscribe event */
+#define HostCmd_CMD_802_11_SUBSCRIBE_EVENT       0x0075
+
+/** TLV  type ID definition */
+#define PROPRIETARY_TLV_BASE_ID     0x0100
+/** TLV type : Beacon RSSI low */
+#define TLV_TYPE_RSSI_LOW           (PROPRIETARY_TLV_BASE_ID + 4)
+/** TLV type : Beacon SNR low */
+#define TLV_TYPE_SNR_LOW            (PROPRIETARY_TLV_BASE_ID + 5)
+/** TLV type : Fail count */
+#define TLV_TYPE_FAILCOUNT          (PROPRIETARY_TLV_BASE_ID + 6)
+/** TLV type : BCN miss */
+#define TLV_TYPE_BCNMISS            (PROPRIETARY_TLV_BASE_ID + 7)
+/** TLV type : Beacon RSSI high */
+#define TLV_TYPE_RSSI_HIGH          (PROPRIETARY_TLV_BASE_ID + 22)
+/** TLV type : Beacon SNR high */
+#define TLV_TYPE_SNR_HIGH           (PROPRIETARY_TLV_BASE_ID + 23)
+/** TLV type : Auto Tx */
+#define TLV_TYPE_AUTO_TX            (PROPRIETARY_TLV_BASE_ID + 24)
+/** TLV type :Link Quality */
+#define TLV_TYPE_LINK_QUALITY       (PROPRIETARY_TLV_BASE_ID + 36)
+/** TLV type : Data RSSI low */
+#define TLV_TYPE_RSSI_LOW_DATA      (PROPRIETARY_TLV_BASE_ID + 38)
+/** TLV type : Data SNR low */
+#define TLV_TYPE_SNR_LOW_DATA       (PROPRIETARY_TLV_BASE_ID + 39)
+/** TLV type : Data RSSI high */
+#define TLV_TYPE_RSSI_HIGH_DATA     (PROPRIETARY_TLV_BASE_ID + 40)
+/** TLV type : Data SNR high */
+#define TLV_TYPE_SNR_HIGH_DATA      (PROPRIETARY_TLV_BASE_ID + 41)
+/** TLV type: Pre-Beacon Lost */
+#define TLV_TYPE_PRE_BEACON_LOST    (PROPRIETARY_TLV_BASE_ID + 73)
+
+/* Define general hostcmd data structure */
+/** HostCmd_DS_GEN */
+typedef struct MAPP_HostCmd_DS_GEN
+{
+    /** Command */
+    t_u16 command;
+    /** Size */
+    t_u16 size;
+    /** Sequence number */
+    t_u16 seq_num;
+    /** Result */
+    t_u16 result;
+} __ATTRIB_PACK__ HostCmd_DS_GEN;
+
+typedef struct _HostCmd_DS_MEF_CFG
+{
+    /** Criteria */
+    t_u32 Criteria;
+    /** Number of entries */
+    t_u16 NumEntries;
+} __ATTRIB_PACK__ HostCmd_DS_MEF_CFG;
+
+typedef struct _MEF_CFG_DATA
+{
+    /** Size */
+    t_u16 size;
+    /** Data */
+    HostCmd_DS_MEF_CFG data;
+} __ATTRIB_PACK__ MEF_CFG_DATA;
+
+/** Size of HostCmd_DS_GEN */
+#define S_DS_GEN    sizeof(HostCmd_DS_GEN)
+
+/** HostCmd_DS_REG */
+typedef struct MAPP_HostCmd_DS_REG
+{
+    /** Read or write */
+    t_u16 action;
+    /** Register offset */
+    t_u16 offset;
+    /** Value */
+    t_u32 value;
+} __ATTRIB_PACK__ HostCmd_DS_REG;
+
+/** HostCmd_DS_802_11_CFG_DATA */
+typedef struct MAPP_HostCmd_DS_802_11_CFG_DATA
+{
+    /** Action */
+    t_u16 action;
+    /** Type */
+    t_u16 type;
+    /** Data length */
+    t_u16 data_len;
+    /** Data */
+    t_u8 data[1];
+} __ATTRIB_PACK__ HostCmd_DS_802_11_CFG_DATA;
+
+/** mlan_ioctl_11h_tpc_resp */
+typedef struct
+{
+    int status_code; /**< Firmware command result status code */
+    int tx_power;    /**< Reported TX Power from the TPC Report */
+    int link_margin; /**< Reported Link margin from the TPC Report */
+    int rssi;        /**< RSSI of the received TPC Report frame */
+} __ATTRIB_PACK__ mlan_ioctl_11h_tpc_resp;
+
+/** MrvlIEtypesHeader_t */
+typedef struct MrvlIEtypesHeader
+{
+    /** Header type */
+    t_u16 type;
+    /** Header length */
+    t_u16 len;
+} __ATTRIB_PACK__ MrvlIEtypesHeader_t;
+
+/** MrvlIEtypes_Data_t */
+typedef struct MrvlIEtypes_Data_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Data */
+    t_u8 data[1];
+} __ATTRIB_PACK__ MrvlIEtypes_Data_t;
+
+/** HostCmd_DS_802_11_CRYPTO */
+typedef struct MAPP_HostCmd_DS_802_11_CRYPTO
+{
+    t_u16 encdec;         /**< Decrypt=0, Encrypt=1 */
+    t_u16 algorithm;      /**< RC4=1 AES=2 , AES_KEY_WRAP=3 */
+    t_u16 key_IV_length;    /**< Length of Key IV (bytes)   */
+    t_u8 keyIV[32];       /**< Key IV */
+    t_u16 key_length;      /**< Length of Key (bytes) */
+    t_u8 key[32];         /**< Key */
+    MrvlIEtypes_Data_t data;       /**< Plain text if encdec=Encrypt, Ciphertext data if encdec=Decrypt*/
+} __ATTRIB_PACK__ HostCmd_DS_802_11_CRYPTO;
+
+/** HostCmd_DS_802_11_CRYPTO_AES_CCM */
+typedef struct MAPP_HostCmd_DS_802_11_CRYPTO_AES_CCM
+{
+    t_u16 encdec;         /**< Decrypt=0, Encrypt=1 */
+    t_u16 algorithm;      /**< AES_CCM=4 */
+    t_u16 key_length;      /**< Length of Key (bytes)  */
+    t_u8 key[32];         /**< Key  */
+    t_u16 nonce_length;    /**< Length of Nonce (bytes) */
+    t_u8 nonce[14];       /**< Nonce */
+    t_u16 AAD_length;      /**< Length of AAD (bytes) */
+    t_u8 AAD[32];         /**< AAD */
+    MrvlIEtypes_Data_t data;       /**< Plain text if encdec=Encrypt, Ciphertext data if encdec=Decrypt*/
+} __ATTRIB_PACK__ HostCmd_DS_802_11_CRYPTO_AES_CCM;
+
+/** AES CCM cipher test */
+#define CIPHER_TEST_AES_CCM (4)
+/** AutoTx_MacFrame_t */
+typedef struct AutoTx_MacFrame
+{
+    t_u16 interval;           /**< in seconds */
+    t_u8 priority;            /**< User Priority: 0~7, ignored if non-WMM */
+    t_u8 reserved;            /**< set to 0 */
+    t_u16 frame_len;           /**< Length of MAC frame payload */
+    t_u8 dest_mac_addr[MLAN_MAC_ADDR_LENGTH];           /**< Destination MAC address */
+    t_u8 src_mac_addr[MLAN_MAC_ADDR_LENGTH];            /**< Source MAC address */
+    t_u8 payload[];                       /**< Payload */
+} __ATTRIB_PACK__ AutoTx_MacFrame_t;
+
+/** MrvlIEtypes_AutoTx_t */
+typedef struct MrvlIEtypes_AutoTx
+{
+    MrvlIEtypesHeader_t header;             /**< Header */
+    AutoTx_MacFrame_t auto_tx_mac_frame;      /**< Auto Tx MAC frame */
+} __ATTRIB_PACK__ MrvlIEtypes_AutoTx_t;
+
+/** HostCmd_DS_802_11_AUTO_TX */
+typedef struct MAPP_HostCmd_DS_802_11_AUTO_TX
+{
+    /** Action */
+    t_u16 action;               /* 0 = ACT_GET; 1 = ACT_SET; */
+    MrvlIEtypes_AutoTx_t auto_tx;        /**< Auto Tx */
+} __ATTRIB_PACK__ HostCmd_DS_802_11_AUTO_TX;
+
+/** HostCmd_DS_802_11_SUBSCRIBE_EVENT */
+typedef struct MAPP_HostCmd_DS_802_11_SUBSCRIBE_EVENT
+{
+    /** Action */
+    t_u16 action;
+    /** Events */
+    t_u16 events;
+} __ATTRIB_PACK__ HostCmd_DS_802_11_SUBSCRIBE_EVENT;
+
+/** MrvlIEtypes_RssiParamSet_t */
+typedef struct MrvlIEtypes_RssiThreshold
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** RSSI value */
+    t_u8 RSSI_value;
+    /** RSSI frequency */
+    t_u8 RSSI_freq;
+} __ATTRIB_PACK__ MrvlIEtypes_RssiThreshold_t;
+
+/** MrvlIEtypes_SnrThreshold_t */
+typedef struct MrvlIEtypes_SnrThreshold
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** SNR value */
+    t_u8 SNR_value;
+    /** SNR frequency */
+    t_u8 SNR_freq;
+} __ATTRIB_PACK__ MrvlIEtypes_SnrThreshold_t;
+
+/** MrvlIEtypes_FailureCount_t */
+typedef struct MrvlIEtypes_FailureCount
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Failure value */
+    t_u8 fail_value;
+    /** Failure frequency */
+    t_u8 fail_freq;
+} __ATTRIB_PACK__ MrvlIEtypes_FailureCount_t;
+
+/** MrvlIEtypes_BeaconsMissed_t */
+typedef struct MrvlIEtypes_BeaconsMissed
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Number of beacons missed */
+    t_u8 beacon_missed;
+    /** Reserved */
+    t_u8 reserved;
+} __ATTRIB_PACK__ MrvlIEtypes_BeaconsMissed_t;
+
+/** MrvlIEtypes_LinkQuality_t */
+typedef struct MrvlIEtypes_LinkQuality
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Link SNR threshold */
+    t_u16 link_SNR_thrs;
+    /** Link SNR frequency */
+    t_u16 link_SNR_freq;
+    /** Minimum rate value */
+    t_u16 min_rate_val;
+    /** Minimum rate frequency */
+    t_u16 min_rate_freq;
+    /** Tx latency value */
+    t_u32 tx_latency_val;
+    /** Tx latency threshold */
+    t_u32 tx_latency_thrs;
+} __ATTRIB_PACK__ MrvlIEtypes_LinkQuality_t;
+
+/** MrvlIEtypes_PreBeaconLost_t */
+typedef struct MrvlIEtypes_PreBeaconLost
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Pre-Beacon Lost */
+    t_u8 pre_beacon_lost;
+    /** Reserved */
+    t_u8 reserved;
+} __ATTRIB_PACK__ MrvlIEtypes_PreBeaconLost_t;
+
+/* String helper functions */
+/** Convert char to hex integer */
+int hexval(t_s32 chr);
+/** Convert char to hex integer */
+t_u8 hexc2bin(t_s8 chr);
+/** Convert string to hex integer */
+t_u32 a2hex(t_s8 * s);
+/** Check the Hex String */
+int ishexstring(t_s8 * s);
+/** Convert String to integer */
+t_u32 a2hex_or_atoi(t_s8 * value);
+/** Convert String to Integer */
+int atoval(t_s8 * buf);
+/** Hump hex data */
+void hexdump(t_s8 * prompt, void *p, t_s32 len, t_s8 delim);
+/** Convert String to Hex */
+t_s8 *convert2hex(t_s8 * ptr, t_u8 * chr);
+
+int process_host_cmd_resp(t_u8 * buf);
+int prepare_host_cmd_buffer(char *cmd_name, t_u8 * buf);
+int prepare_arp_filter_buffer(t_u8 * buf, t_u16 * length);
+int prepare_cfg_data_buffer(int argc, char *argv[], t_u8 * buf);
+int prepare_hostcmd_regrdwr(t_u32 type, t_u32 offset, t_u32 * value,
+                            t_u8 * buf);
+
+#endif /* _MLANHOSTCMD_H_ */
diff --git a/wlan_src/mapp/mlanconfig/mlanmisc.c b/wlan_src/mapp/mlanconfig/mlanmisc.c
new file mode 100755
index 0000000..4e1a135
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/mlanmisc.c
@@ -0,0 +1,960 @@
+/** @file  mlanmisc.c
+  *
+  * @brief Program to prepare command buffer
+  * 
+  *  Copyright (C) 2008-2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+
+/************************************************************************
+Change log:
+     03/10/2009: initial version
+************************************************************************/
+
+#include    "mlanconfig.h"
+#include    "mlanhostcmd.h"
+#include    "mlanmisc.h"
+
+/********************************************************
+		Local Variables
+********************************************************/
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+extern t_s32 sockfd;  /**< socket */
+extern t_s8 dev_name[IFNAMSIZ + 1]; /**< device name */
+
+/********************************************************
+		Local Functions
+********************************************************/
+
+/**
+ *  @brief Helper function for process_getscantable_idx
+ *
+ *  @param pbuf     A pointer to the buffer
+ *  @param buf_len  buffer length    
+ *
+ *  @return         NA
+ *
+ */
+static void
+dump_scan_elems(const t_u8 * pbuf, uint buf_len)
+{
+    uint idx;
+    uint marker = 2 + pbuf[1];
+
+    for (idx = 0; idx < buf_len; idx++) {
+        if (idx % 0x10 == 0) {
+            printf("\n%04x: ", idx);
+        }
+
+        if (idx == marker) {
+            printf("|");
+            marker = idx + pbuf[idx + 1] + 2;
+        } else {
+            printf(" ");
+        }
+
+        printf("%02x ", pbuf[idx]);
+    }
+
+    printf("\n");
+}
+
+/**
+ *  @brief Helper function for process_getscantable_idx
+ *  Find next element
+ *
+ *  @param pp_ie_out    pointer of a IEEEtypes_Generic_t structure pointer              
+ *  @param p_buf_left   integer pointer, which contains the number of left p_buf
+ *
+ *  @return             MLAN_STATUS_SUCCESS on success, otherwise MLAN_STATUS_FAILURE
+ */
+static int
+scantable_elem_next(IEEEtypes_Generic_t ** pp_ie_out, int *p_buf_left)
+{
+    IEEEtypes_Generic_t *pie_gen;
+    t_u8 *p_next;
+
+    if (*p_buf_left < 2) {
+        return MLAN_STATUS_FAILURE;
+    }
+
+    pie_gen = *pp_ie_out;
+
+    p_next = (t_u8 *) pie_gen + (pie_gen->ieee_hdr.len
+                                 + sizeof(pie_gen->ieee_hdr));
+    *p_buf_left -= (p_next - (t_u8 *) pie_gen);
+
+    *pp_ie_out = (IEEEtypes_Generic_t *) p_next;
+
+    if (*p_buf_left <= 0) {
+        return MLAN_STATUS_FAILURE;
+    }
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+ /**
+  *  @brief Helper function for process_getscantable_idx
+  *         scantable find element
+  *
+  *  @param ie_buf       pointer of the IE buffer                
+  *  @param ie_buf_len   IE buffer length
+  *  @param ie_type      IE type
+  *  @param ppie_out     pointer to the IEEEtypes_Generic_t structure pointer
+  *  @return             MLAN_STATUS_SUCCESS on success, otherwise MLAN_STATUS_FAILURE
+  */
+static int
+scantable_find_elem(t_u8 * ie_buf,
+                    unsigned int ie_buf_len,
+                    IEEEtypes_ElementId_e ie_type,
+                    IEEEtypes_Generic_t ** ppie_out)
+{
+    int found;
+    unsigned int ie_buf_left;
+
+    ie_buf_left = ie_buf_len;
+
+    found = FALSE;
+
+    *ppie_out = (IEEEtypes_Generic_t *) ie_buf;
+
+    do {
+        found = ((*ppie_out)->ieee_hdr.element_id == ie_type);
+
+    } while (!found &&
+             (scantable_elem_next(ppie_out, (int *) &ie_buf_left) == 0));
+
+    if (!found) {
+        *ppie_out = NULL;
+    }
+
+    return (found ? MLAN_STATUS_SUCCESS : MLAN_STATUS_FAILURE);
+}
+
+ /**
+  *  @brief Helper function for process_getscantable_idx
+  *         It gets SSID from IE 
+  *
+  *  @param ie_buf       IE buffer
+  *  @param ie_buf_len   IE buffer length
+  *  @param pssid        SSID
+  *  @param ssid_buf_max size of SSID    
+  *  @return             MLAN_STATUS_SUCCESS on success, otherwise MLAN_STATUS_FAILURE
+  */
+static int
+scantable_get_ssid_from_ie(t_u8 * ie_buf,
+                           unsigned int ie_buf_len,
+                           t_u8 * pssid, unsigned int ssid_buf_max)
+{
+    int retval;
+    IEEEtypes_Generic_t *pie_gen;
+
+    retval = scantable_find_elem(ie_buf, ie_buf_len, SSID, &pie_gen);
+
+    memcpy(pssid, pie_gen->data, MIN(pie_gen->ieee_hdr.len, ssid_buf_max));
+
+    return retval;
+}
+
+/** 
+ *  @brief Provision the driver with a IEEE IE for use in the next join cmd
+ *
+ *  @param table_idx table index
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+static int
+process_getscantable_idx(int table_idx)
+{
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    t_u8 *pcurrent;
+    int bss_info_len, ret = 0;
+    char ssid[33];
+    t_u16 tmp_cap;
+    t_u8 tsf[8];
+    t_u16 beacon_interval;
+    t_u8 *scan_rsp_buf = NULL;
+    t_u16 cap_info;
+    wlan_ioctl_get_scan_table_info *prsp_info;
+    wlan_ioctl_get_scan_table_entry *prsp_entry;
+
+    scan_rsp_buf = (t_u8 *) malloc(SCAN_RESP_BUF_SIZE);
+    if (scan_rsp_buf == NULL) {
+        printf("Error: allocate memory for scan_rsp_buf failed\n");
+        return -ENOMEM;
+    }
+    memset(ssid, 0x00, sizeof(ssid));
+
+    prsp_info = (wlan_ioctl_get_scan_table_info *) scan_rsp_buf;
+
+    prsp_info->scan_number = table_idx;
+
+    if (get_priv_ioctl("getscantable",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        ret = -EOPNOTSUPP;
+        goto done;
+    }
+
+    /* 
+     * Set up and execute the ioctl call
+     */
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) prsp_info;
+    iwr.u.data.length = SCAN_RESP_BUF_SIZE;
+    iwr.u.data.flags = subioctl_val;
+
+    if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+        perror("mlanconfig: getscantable ioctl");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    prsp_entry
+        = (wlan_ioctl_get_scan_table_entry *) prsp_info->scan_table_entry_buf;
+
+    if (prsp_info->scan_number == 0) {
+        printf("mlanconfig: getscantable ioctl - index out of range\n");
+        ret = -EINVAL;
+        goto done;
+    }
+
+    pcurrent = prsp_info->scan_table_entry_buf;
+    pcurrent += (sizeof(prsp_entry->fixed_field_length) +
+                 prsp_entry->fixed_field_length);
+
+    bss_info_len = prsp_entry->bss_info_length;
+    pcurrent += sizeof(prsp_entry->bss_info_length);
+
+    /* time stamp is 8 byte long */
+    memcpy(tsf, pcurrent, sizeof(tsf));
+    pcurrent += sizeof(tsf);
+    bss_info_len -= sizeof(tsf);
+
+    /* beacon interval is 2 byte long */
+    memcpy(&beacon_interval, pcurrent, sizeof(beacon_interval));
+    /* endian convert needed here */
+    beacon_interval = le16_to_cpu(beacon_interval);
+    pcurrent += sizeof(beacon_interval);
+    bss_info_len -= sizeof(beacon_interval);
+
+    /* capability information is 2 byte long */
+    memcpy(&cap_info, pcurrent, sizeof(cap_info));
+    /* endian convert needed here */
+    cap_info = le16_to_cpu(cap_info);
+    pcurrent += sizeof(cap_info);
+    bss_info_len -= sizeof(cap_info);
+
+    scantable_get_ssid_from_ie(pcurrent,
+                               bss_info_len, (t_u8 *) ssid, sizeof(ssid));
+
+    printf("\n*** [%s], %02x:%02x:%02x:%02x:%02x:%2x\n",
+           ssid,
+           prsp_entry->fixed_fields.bssid[0], prsp_entry->fixed_fields.bssid[1],
+           prsp_entry->fixed_fields.bssid[2], prsp_entry->fixed_fields.bssid[3],
+           prsp_entry->fixed_fields.bssid[4],
+           prsp_entry->fixed_fields.bssid[5]);
+    memcpy(&tmp_cap, &cap_info, sizeof(tmp_cap));
+    printf("Channel = %d, SS = %d, CapInfo = 0x%04x, BcnIntvl = %d\n",
+           prsp_entry->fixed_fields.channel,
+           255 - prsp_entry->fixed_fields.rssi, tmp_cap, beacon_interval);
+
+    printf("TSF Values: AP(0x%02x%02x%02x%02x%02x%02x%02x%02x), ",
+           tsf[7], tsf[6], tsf[5], tsf[4], tsf[3], tsf[2], tsf[1], tsf[0]);
+
+    printf("Network(0x%016llx)\n", prsp_entry->fixed_fields.network_tsf);
+    printf("\n");
+    printf("Element Data (%d bytes)\n", bss_info_len);
+    printf("------------");
+    dump_scan_elems(pcurrent, bss_info_len);
+    printf("\n");
+
+  done:
+    if (scan_rsp_buf)
+        free(scan_rsp_buf);
+    return ret;
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+/** Maximum SDIO command-52 buffer length */
+#define CMD52_BUF_LEN    7
+
+/** 
+ *  @brief SD comand52 read/write
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+process_sdcmd52rw(int argc, char *argv[])
+{
+    struct iwreq iwr;
+    t_u8 buf[CMD52_BUF_LEN];
+    t_u32 tmp;
+    int ioctl_val, subioctl_val;
+
+    if (get_priv_ioctl("sdcmd52rw",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    if (argc == 5) {
+        buf[0] = 0;             /* CMD52 read */
+        iwr.u.data.length = CMD52_BUF_LEN - 1;
+    } else if (argc == 6) {
+        buf[0] = 1;             /* CMD52 write */
+        buf[6] = atoval(argv[5]);       /* dat */
+        iwr.u.data.length = CMD52_BUF_LEN;
+    } else {
+        fprintf(stderr, "Invalid number of parameters!\n");
+        return MLAN_STATUS_FAILURE;
+    }
+    buf[1] = atoval(argv[3]);   /* func */
+    tmp = atoval(argv[4]);      /* reg */
+    buf[2] = tmp & 0xff;
+    buf[3] = (tmp >> 8) & 0xff;
+    buf[4] = (tmp >> 16) & 0xff;
+    buf[5] = (tmp >> 24) & 0xff;
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.flags = subioctl_val;
+    iwr.u.data.pointer = (caddr_t) buf;
+
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        perror("mlanconfig");
+        fprintf(stderr,
+                "mlanconfig: CMD52 R/W not supported by "
+                "interface %s\n", dev_name);
+        return MLAN_STATUS_FAILURE;
+    }
+    printf("sdcmd52rw returns 0x%02X\n", buf[0]);
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** Maximum SDIO command-53 buffer length */
+#define CMD53_BUF_LEN    2000
+
+/** 
+ *  @brief SD comand53 read/write
+ *  
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+process_sdcmd53rw(int argc, char *argv[])
+{
+    struct iwreq iwr;
+    t_s8 *buf = NULL;
+    int addr, mode, blklen, blknum, i, rw;
+    int ioctl_val, subioctl_val;
+
+    if (get_priv_ioctl("sdcmd53rw",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    if (argc < 8) {
+        fprintf(stderr, "Invalid number of parameters!\n");
+        return MLAN_STATUS_FAILURE;
+    }
+
+    if (!(buf = malloc(CMD53_BUF_LEN)))
+        return -ENOMEM;
+    memset(buf, 0, CMD53_BUF_LEN);
+
+    if (argc == 8) {
+        rw = buf[0] = 0;        /* CMD53 read */
+    } else {
+        rw = buf[0] = 1;        /* CMD53 write */
+    }
+    buf[1] = atoval(argv[3]);   /* func */
+    addr = atoval(argv[4]);     /* address */
+    buf[2] = addr & 0xff;
+    buf[3] = (addr >> 8) & 0xff;
+    buf[4] = (addr >> 16) & 0xff;
+    buf[5] = (addr >> 24) & 0xff;
+    mode = atoval(argv[5]);     /* mode */
+    buf[6] = (t_u8) mode;
+    blklen = atoval(argv[6]);   /* block size */
+    buf[7] = blklen & 0xff;
+    buf[8] = (blklen >> 8) & 0xff;
+    blknum = atoval(argv[7]);   /* block number or byte number */
+    buf[9] = blknum & 0xff;
+    buf[10] = (blknum >> 8) & 0xff;
+    iwr.u.data.length = 11;
+    if (buf[0]) {
+        for (i = 0; i < (argc - 8); i++)
+            buf[11 + i] = atoval(argv[8 + i]);
+        iwr.u.data.length += (argc - 8);
+    }
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.flags = subioctl_val;
+    iwr.u.data.pointer = (caddr_t) buf;
+
+    if (ioctl(sockfd, ioctl_val, &iwr)) {
+        perror("mlanconfig");
+        fprintf(stderr,
+                "mlanconfig: CMD53 R/W not supported by "
+                "interface %s\n", dev_name);
+        free(buf);
+        return MLAN_STATUS_FAILURE;
+    }
+
+    if (mode) {
+        fprintf(stderr, "CMD53rw blklen = %d, blknum = %d\n", blklen, blknum);
+    } else {
+        blklen = 1;
+        fprintf(stderr, "CMD53rw bytelen = %d\n", blknum);
+    }
+    if (!rw)
+        hexdump("data", buf, blklen * blknum, ' ');
+
+    free(buf);
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Retrieve and display the contents of the driver scan table.
+ *
+ *  The ioctl to retrieve the scan table contents will be invoked, and portions
+ *   of the scan data will be displayed on stdout.  The entire beacon or 
+ *   probe response is also retrieved (if available in the driver).  This 
+ *   data would be needed in case the application was explicitly controlling
+ *   the association (inserting IEs, TLVs, etc).
+ *
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+process_getscantable(int argc, char *argv[])
+{
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    t_u8 *scan_rsp_buf = NULL;
+
+    unsigned int scan_start;
+    int idx, ret = 0;
+
+    t_u8 *pcurrent;
+    t_u8 *pnext;
+    IEEEtypes_ElementId_e *pelement_id;
+    t_u8 *pelement_len;
+    int bss_info_len;
+    int ssid_idx;
+    t_u8 *pbyte;
+    char ssid[33];
+    int ssid_len = 0;
+
+    IEEEtypes_CapInfo_t cap_info = { 0 };
+    t_u16 tmp_cap;
+    t_u8 tsf[8];
+    t_u16 beacon_interval;
+
+    IEEEtypes_VendorSpecific_t *pwpa_ie;
+    const t_u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
+
+    IEEEtypes_WmmParameter_t *pwmm_ie;
+    const t_u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
+    IEEEtypes_VendorSpecific_t *pwps_ie;
+    const t_u8 wps_oui[4] = { 0x00, 0x50, 0xf2, 0x04 };
+    char wmm_cap;
+    char wps_cap;
+    char dot11k_cap;
+    char dot11r_cap;
+    char priv_cap;
+    char ht_cap;
+
+    int displayed_info;
+
+    wlan_ioctl_get_scan_table_info *prsp_info;
+    wlan_ioctl_get_scan_table_entry *prsp_entry;
+
+    scan_rsp_buf = (t_u8 *) malloc(SCAN_RESP_BUF_SIZE);
+    if (scan_rsp_buf == NULL) {
+        printf("Error: allocate memory for scan_rsp_buf failed\n");
+        return -ENOMEM;
+    }
+    prsp_info = (wlan_ioctl_get_scan_table_info *) scan_rsp_buf;
+
+    if (get_priv_ioctl("getscantable",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        ret = -EOPNOTSUPP;
+        goto done;
+    }
+
+    if (argc > 3 && (strcmp(argv[3], "tsf") != 0)
+        && (strcmp(argv[3], "help") != 0)) {
+
+        idx = strtol(argv[3], NULL, 10);
+
+        if (idx >= 0) {
+            if (scan_rsp_buf)
+                free(scan_rsp_buf);
+            return process_getscantable_idx(idx);
+        }
+    }
+
+    displayed_info = FALSE;
+    scan_start = 1;
+
+    printf("---------------------------------------");
+    printf("---------------------------------------\n");
+    printf("# | ch  | ss  |       bssid       |   cap    |   SSID \n");
+    printf("---------------------------------------");
+    printf("---------------------------------------\n");
+
+    do {
+        prsp_info->scan_number = scan_start;
+
+        /* 
+         * Set up and execute the ioctl call
+         */
+        strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+        iwr.u.data.pointer = (caddr_t) prsp_info;
+        iwr.u.data.length = SCAN_RESP_BUF_SIZE;
+        iwr.u.data.flags = subioctl_val;
+
+        if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+            perror("mlanconfig: getscantable ioctl");
+            ret = -EFAULT;
+            goto done;
+        }
+
+        pcurrent = 0;
+        pnext = prsp_info->scan_table_entry_buf;
+
+        for (idx = 0; idx < prsp_info->scan_number; idx++) {
+
+            /* 
+             * Set pcurrent to pnext in case pad bytes are at the end
+             *   of the last IE we processed.
+             */
+            pcurrent = pnext;
+
+            prsp_entry = (wlan_ioctl_get_scan_table_entry *) pcurrent;
+
+            printf("%02u| %03d | %03d | %02x:%02x:%02x:%02x:%02x:%02x |",
+                   scan_start + idx,
+                   prsp_entry->fixed_fields.channel,
+                   255 - prsp_entry->fixed_fields.rssi,
+                   prsp_entry->fixed_fields.bssid[0],
+                   prsp_entry->fixed_fields.bssid[1],
+                   prsp_entry->fixed_fields.bssid[2],
+                   prsp_entry->fixed_fields.bssid[3],
+                   prsp_entry->fixed_fields.bssid[4],
+                   prsp_entry->fixed_fields.bssid[5]);
+
+            displayed_info = TRUE;
+
+            pcurrent += (sizeof(prsp_entry->fixed_field_length) +
+                         prsp_entry->fixed_field_length);
+
+            bss_info_len = prsp_entry->bss_info_length;
+            pcurrent += sizeof(prsp_entry->bss_info_length);
+            pnext = pcurrent + prsp_entry->bss_info_length;
+
+            if (bss_info_len >= (sizeof(tsf)
+                                 + sizeof(beacon_interval) + sizeof(cap_info))) {
+                /* time stamp is 8 byte long */
+                memcpy(tsf, pcurrent, sizeof(tsf));
+                pcurrent += sizeof(tsf);
+                bss_info_len -= sizeof(tsf);
+
+                /* beacon interval is 2 byte long */
+                memcpy(&beacon_interval, pcurrent, sizeof(beacon_interval));
+                /* endian convert needed here */
+                beacon_interval = le16_to_cpu(beacon_interval);
+                pcurrent += sizeof(beacon_interval);
+                bss_info_len -= sizeof(beacon_interval);
+
+                /* capability information is 2 byte long */
+                memcpy(&tmp_cap, pcurrent, sizeof(tmp_cap));
+                /* endian convert needed here */
+                tmp_cap = le16_to_cpu(tmp_cap);
+                memcpy(&cap_info, &tmp_cap, sizeof(cap_info));
+                pcurrent += sizeof(cap_info);
+                bss_info_len -= sizeof(cap_info);
+            }
+
+            wmm_cap = ' ';      /* M (WMM), C (WMM-Call Admission Control) */
+            wps_cap = ' ';      /* "S" */
+            dot11k_cap = ' ';   /* "K" */
+            dot11r_cap = ' ';   /* "R" */
+            ht_cap = ' ';       /* "N" */
+
+            /* "P" for Privacy (WEP) since "W" is WPA, and "2" is RSN/WPA2 */
+            priv_cap = cap_info.privacy ? 'P' : ' ';
+
+            while (bss_info_len >= 2) {
+                pelement_id = (IEEEtypes_ElementId_e *) pcurrent;
+                pelement_len = pcurrent + 1;
+                pcurrent += 2;
+
+                switch (*pelement_id) {
+
+                case SSID:
+                    if (*pelement_len &&
+                        *pelement_len <= MRVDRV_MAX_SSID_LENGTH) {
+                        memcpy(ssid, pcurrent, *pelement_len);
+                        ssid_len = *pelement_len;
+                    }
+                    break;
+
+                case WPA_IE:
+                    pwpa_ie = (IEEEtypes_VendorSpecific_t *) pelement_id;
+                    if ((memcmp
+                         (pwpa_ie->vend_hdr.oui, wpa_oui,
+                          sizeof(pwpa_ie->vend_hdr.oui)) == 0)
+                        && (pwpa_ie->vend_hdr.oui_type == wpa_oui[3])) {
+                        /* WPA IE found, 'W' for WPA */
+                        priv_cap = 'W';
+                    } else {
+                        pwmm_ie = (IEEEtypes_WmmParameter_t *) pelement_id;
+                        if ((memcmp(pwmm_ie->vend_hdr.oui,
+                                    wmm_oui,
+                                    sizeof(pwmm_ie->vend_hdr.oui)) == 0)
+                            && (pwmm_ie->vend_hdr.oui_type == wmm_oui[3])) {
+                            /* Check the subtype: 1 == parameter, 0 == info */
+                            if ((pwmm_ie->vend_hdr.oui_subtype == 1)
+                                && pwmm_ie->ac_params[WMM_AC_VO].aci_aifsn.acm) {
+                                /* Call admission on VO; 'C' for CAC */
+                                wmm_cap = 'C';
+                            } else {
+                                /* No CAC; 'M' for uh, WMM */
+                                wmm_cap = 'M';
+                            }
+                        } else {
+                            pwps_ie =
+                                (IEEEtypes_VendorSpecific_t *) pelement_id;
+                            if ((memcmp
+                                 (pwps_ie->vend_hdr.oui, wps_oui,
+                                  sizeof(pwps_ie->vend_hdr.oui)) == 0)
+                                && (pwps_ie->vend_hdr.oui_type == wps_oui[3])) {
+                                wps_cap = 'S';
+                            }
+                        }
+                    }
+                    break;
+
+                case RSN_IE:
+                    /* RSN IE found; '2' for WPA2 (RSN) */
+                    priv_cap = '2';
+                    break;
+                case HT_CAPABILITY:
+                    ht_cap = 'N';
+                    break;
+
+                default:
+                    break;
+                }
+
+                pcurrent += *pelement_len;
+                bss_info_len -= (2 + *pelement_len);
+            }
+
+            /* "A" for Adhoc "I" for Infrastructure, "D" for DFS (Spectrum
+               Mgmt) */
+            printf(" %c%c%c%c%c%c%c%c | ", cap_info.ibss ? 'A' : 'I', priv_cap, /* P 
+                                                                                   (WEP), 
+                                                                                   W 
+                                                                                   (WPA), 
+                                                                                   2 
+                                                                                   (WPA2) 
+                                                                                 */
+                   cap_info.spectrum_mgmt ? 'D' : ' ', wmm_cap, /* M (WMM), C
+                                                                   (WMM-Call
+                                                                   Admission
+                                                                   Control) */
+                   dot11k_cap,  /* K */
+                   dot11r_cap,  /* R */
+                   wps_cap,     /* S */
+                   ht_cap);     /* N */
+
+            /* Print out the ssid or the hex values if non-printable */
+            for (ssid_idx = 0; ssid_idx < ssid_len; ssid_idx++) {
+                if (isprint(ssid[ssid_idx])) {
+                    printf("%c", ssid[ssid_idx]);
+                } else {
+                    printf("\\%02x", ssid[ssid_idx]);
+                }
+            }
+
+            printf("\n");
+
+            if (argc > 3 && strcmp(argv[3], "tsf") == 0) {
+                /* TSF is a u64, some formatted printing libs have trouble
+                   printing long longs, so cast and dump as bytes */
+                pbyte = (t_u8 *) & prsp_entry->fixed_fields.network_tsf;
+                printf("    TSF=%02x%02x%02x%02x%02x%02x%02x%02x\n",
+                       pbyte[7], pbyte[6], pbyte[5], pbyte[4],
+                       pbyte[3], pbyte[2], pbyte[1], pbyte[0]);
+            }
+        }
+
+        scan_start += prsp_info->scan_number;
+
+    } while (prsp_info->scan_number);
+
+    if (displayed_info == TRUE) {
+        if (argc > 3 && strcmp(argv[3], "help") == 0) {
+            printf("\n\n"
+                   "Capability Legend (Not all may be supported)\n"
+                   "-----------------\n"
+                   " I [ Infrastructure ]\n"
+                   " A [ Ad-hoc ]\n"
+                   " W [ WPA IE ]\n"
+                   " 2 [ WPA2/RSN IE ]\n"
+                   " M [ WMM IE ]\n"
+                   " C [ Call Admission Control - WMM IE, VO ACM set ]\n"
+                   " D [ Spectrum Management - DFS (11h) ]\n"
+                   " K [ 11k ]\n"
+                   " R [ 11r ]\n" " S [ WPS ]\n" " N [ HT (11n) ]\n" "\n\n");
+        }
+    } else {
+        printf("< No Scan Results >\n");
+    }
+
+  done:
+    if (scan_rsp_buf)
+        free(scan_rsp_buf);
+    return ret;
+}
+
+/** Maximum channel scratch */
+#define MAX_CHAN_SCRATCH  100
+
+/** Maximum number of probes to send on each channel */
+#define MAX_PROBES  10
+/**
+ *  @brief Request a scan from the driver and display the scan table afterwards
+ *
+ *  Command line interface for performing a specific immediate scan based
+ *    on the following keyword parsing:
+ *
+ *     chan=[chan#][band][mode] where band is [a,b,g,n] and mode is 
+ *                              blank for active or 'p' for passive
+ *     bssid=xx:xx:xx:xx:xx:xx  specify a BSSID filter for the scan
+ *     ssid="[SSID]"            specify a SSID filter for the scan
+ *     keep=[0 or 1]            keep the previous scan results (1), discard (0)
+ *     dur=[scan time]          time to scan for each channel in milliseconds
+ *     probes=[#]               number of probe requests to send on each chan
+ *     type=[1,2,3]             BSS type: 1 (Infra), 2(Adhoc), 3(Any)
+ *
+ *  Any combination of the above arguments can be supplied on the command line.
+ *    If the chan token is absent, a full channel scan will be completed by 
+ *    the driver.  If the dur or probes tokens are absent, the drivers default
+ *    setting will be used.  The bssid and ssid fields, if blank, 
+ *    will produce an unfiltered scan. The type field will default to 3 (Any)
+ *    and the keep field will default to 0 (Discard).  
+ *
+ *  @param argc     number of arguments
+ *  @param argv     A pointer to arguments array    
+ *
+ *  @return         MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+int
+process_setuserscan(int argc, char *argv[])
+{
+    wlan_ioctl_user_scan_cfg scan_req;
+    int ioctl_val, subioctl_val;
+    struct iwreq iwr;
+    char *parg_tok;
+    char *pchan_tok;
+    char *parg_cookie;
+    char *pchan_cookie;
+    int arg_idx;
+    int chan_parse_idx;
+    int chan_cmd_idx;
+    char chan_scratch[MAX_CHAN_SCRATCH];
+    char *pscratch;
+    int tmp_idx;
+    int scan_time;
+    int num_ssid;
+    unsigned int mac[ETH_ALEN];
+
+    memset(&scan_req, 0x00, sizeof(scan_req));
+    chan_cmd_idx = 0;
+    scan_time = 0;
+    num_ssid = 0;
+
+    if (get_priv_ioctl("setuserscan",
+                       &ioctl_val, &subioctl_val) == MLAN_STATUS_FAILURE) {
+        return -EOPNOTSUPP;
+    }
+
+    for (arg_idx = 0; arg_idx < argc; arg_idx++) {
+        if (strncmp(argv[arg_idx], "chan=", strlen("chan=")) == 0) {
+            /* 
+             *  "chan" token string handler
+             */
+            parg_tok = argv[arg_idx] + strlen("chan=");
+
+            if (strlen(parg_tok) > MAX_CHAN_SCRATCH) {
+
+                printf("Error: Specified channels exceeds max limit\n");
+                return MLAN_STATUS_FAILURE;
+            }
+
+            while ((parg_tok = strtok_r(parg_tok, ",", &parg_cookie)) != NULL) {
+
+                memset(chan_scratch, 0x00, sizeof(chan_scratch));
+                pscratch = chan_scratch;
+
+                for (chan_parse_idx = 0;
+                     chan_parse_idx < strlen(parg_tok); chan_parse_idx++) {
+                    if (isalpha(*(parg_tok + chan_parse_idx))) {
+                        *pscratch++ = ' ';
+                    }
+
+                    *pscratch++ = *(parg_tok + chan_parse_idx);
+                }
+                *pscratch = 0;
+                parg_tok = NULL;
+
+                pchan_tok = chan_scratch;
+
+                while ((pchan_tok = strtok_r(pchan_tok, " ",
+                                             &pchan_cookie)) != NULL) {
+                    if (isdigit(*pchan_tok)) {
+                        scan_req.chan_list[chan_cmd_idx].chan_number
+                            = atoi(pchan_tok);
+                    } else {
+                        switch (toupper(*pchan_tok)) {
+                        case 'A':
+                            scan_req.chan_list[chan_cmd_idx].radio_type = 1;
+                            break;
+                        case 'B':
+                        case 'G':
+                        case 'N':
+                            scan_req.chan_list[chan_cmd_idx].radio_type = 0;
+                            break;
+                        case 'P':
+                            scan_req.chan_list[chan_cmd_idx].scan_type = 1;
+                            break;
+                        default:
+                            printf("Error: Band type not supported!\n");
+                            return -EOPNOTSUPP;
+                        }
+                    }
+                    pchan_tok = NULL;
+                }
+                chan_cmd_idx++;
+            }
+        } else if (strncmp(argv[arg_idx], "bssid=", strlen("bssid=")) == 0) {
+            /* 
+             *  "bssid" token string handler
+             */
+            sscanf(argv[arg_idx] + strlen("bssid="), "%2x:%2x:%2x:%2x:%2x:%2x",
+                   mac + 0, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5);
+
+            for (tmp_idx = 0; tmp_idx < NELEMENTS(mac); tmp_idx++) {
+                scan_req.specific_bssid[tmp_idx] = (t_u8) mac[tmp_idx];
+            }
+        } else if (strncmp(argv[arg_idx], "keep=", strlen("keep=")) == 0) {
+            /* 
+             *  "keep" token string handler
+             */
+            scan_req.keep_previous_scan = atoi(argv[arg_idx] + strlen("keep="));
+        } else if (strncmp(argv[arg_idx], "dur=", strlen("dur=")) == 0) {
+            /* 
+             *  "dur" token string handler
+             */
+            scan_time = atoi(argv[arg_idx] + strlen("dur="));
+            scan_req.chan_list[0].scan_time = scan_time;
+        } else if (strncmp(argv[arg_idx], "ssid=", strlen("ssid=")) == 0) {
+            /* 
+             *  "ssid" token string handler
+             */
+            if (num_ssid < MRVDRV_MAX_SSID_LIST_LENGTH) {
+                strncpy(scan_req.ssid_list[num_ssid].ssid,
+                        argv[arg_idx] + strlen("ssid="),
+                        sizeof(scan_req.ssid_list[num_ssid].ssid));
+
+                scan_req.ssid_list[num_ssid].max_len = 0;
+
+                num_ssid++;
+            }
+        } else if (strncmp(argv[arg_idx], "wc=", strlen("wc=")) == 0) {
+
+            if (num_ssid < MRVDRV_MAX_SSID_LIST_LENGTH) {
+                /* 
+                 *  "wc" token string handler
+                 */
+                pscratch = strrchr(argv[arg_idx], ',');
+
+                if (pscratch) {
+                    *pscratch = 0;
+                    pscratch++;
+
+                    if (isdigit(*pscratch)) {
+                        scan_req.ssid_list[num_ssid].max_len = atoi(pscratch);
+                    } else {
+                        scan_req.ssid_list[num_ssid].max_len = *pscratch;
+                    }
+                } else {
+                    /* Standard wildcard matching */
+                    scan_req.ssid_list[num_ssid].max_len = 0xFF;
+                }
+
+                strncpy(scan_req.ssid_list[num_ssid].ssid,
+                        argv[arg_idx] + strlen("wc="),
+                        sizeof(scan_req.ssid_list[num_ssid].ssid));
+
+                num_ssid++;
+            }
+        } else if (strncmp(argv[arg_idx], "probes=", strlen("probes=")) == 0) {
+            /* 
+             *  "probes" token string handler
+             */
+            scan_req.num_probes = atoi(argv[arg_idx] + strlen("probes="));
+            if (scan_req.num_probes > MAX_PROBES) {
+                fprintf(stderr, "Invalid probes (> %d)\n", MAX_PROBES);
+                return -EOPNOTSUPP;
+            }
+        } else if (strncmp(argv[arg_idx], "type=", strlen("type=")) == 0) {
+            /* 
+             *  "type" token string handler
+             */
+            scan_req.bss_mode = atoi(argv[arg_idx] + strlen("type="));
+            switch (scan_req.bss_mode) {
+            case MLAN_SCAN_MODE_BSS:
+            case MLAN_SCAN_MODE_IBSS:
+                break;
+            case MLAN_SCAN_MODE_ANY:
+            default:
+                /* Set any unknown types to ANY */
+                scan_req.bss_mode = MLAN_SCAN_MODE_ANY;
+                break;
+            }
+        }
+    }
+
+    /* 
+     * Update all the channels to have the same scan time
+     */
+    for (tmp_idx = 1; tmp_idx < chan_cmd_idx; tmp_idx++) {
+        scan_req.chan_list[tmp_idx].scan_time = scan_time;
+    }
+
+    strncpy(iwr.ifr_name, dev_name, IFNAMSIZ);
+    iwr.u.data.pointer = (caddr_t) & scan_req;
+    iwr.u.data.length = sizeof(scan_req);
+    iwr.u.data.flags = subioctl_val;
+
+    if (ioctl(sockfd, ioctl_val, &iwr) < 0) {
+        perror("mlanconfig: setuserscan ioctl");
+        return -EFAULT;
+    }
+
+    process_getscantable(0, 0);
+
+    return MLAN_STATUS_SUCCESS;
+}
diff --git a/wlan_src/mapp/mlanconfig/mlanmisc.h b/wlan_src/mapp/mlanconfig/mlanmisc.h
new file mode 100755
index 0000000..a9450fa
--- /dev/null
+++ b/wlan_src/mapp/mlanconfig/mlanmisc.h
@@ -0,0 +1,618 @@
+/** @file  mlanmisc.h
+  *
+  * @brief This file contains command definitions for application
+  * 
+  *  Copyright (C) 2008-2009, Marvell International Ltd.
+  *  All Rights Reserved
+  */
+/************************************************************************
+Change log:
+     03/10/2009: initial version
+************************************************************************/
+
+#ifndef _MLANMISC_H_
+#define _MLANMISC_H_
+
+/** Maximum size of IEEE Information Elements */
+#define IEEE_MAX_IE_SIZE  256
+
+/** Maximum scan response buffer size */
+#define SCAN_RESP_BUF_SIZE 2000
+
+#ifdef FALSE
+#undef FALSE
+#endif
+
+#ifdef TRUE
+#undef TRUE
+#endif
+
+#ifndef MIN
+/** Find minimum value */
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif /* MIN */
+
+#ifndef MAX
+/** Find maximum value */
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif /* MAX */
+
+/** Type enumeration of WMM AC_QUEUES */
+typedef enum _mlan_wmm_ac_e
+{
+    WMM_AC_BK,
+    WMM_AC_BE,
+    WMM_AC_VI,
+    WMM_AC_VO
+} __ATTRIB_PACK__ mlan_wmm_ac_e;
+
+/** Maximum length of SSID */
+#define MRVDRV_MAX_SSID_LENGTH          32
+/** Enumeration for scan mode */
+enum
+{
+    MLAN_SCAN_MODE_UNCHANGED = 0,
+    MLAN_SCAN_MODE_BSS,
+    MLAN_SCAN_MODE_IBSS,
+    MLAN_SCAN_MODE_ANY
+};
+
+/** Length of ethernet address */
+#ifndef ETH_ALEN
+#define ETH_ALEN            6
+#endif
+/** Maximum length of SSID list */
+#define MRVDRV_MAX_SSID_LIST_LENGTH         10
+
+/** Maximum number of channels that can be sent in a setuserscan ioctl */
+#define WLAN_IOCTL_USER_SCAN_CHAN_MAX  50
+
+/** IEEE Type definitions  */
+typedef enum _IEEEtypes_ElementId_e
+{
+    SSID = 0,
+    SUPPORTED_RATES = 1,
+    FH_PARAM_SET = 2,
+    DS_PARAM_SET = 3,
+    CF_PARAM_SET = 4,
+
+    IBSS_PARAM_SET = 6,
+
+    COUNTRY_INFO = 7,
+
+    POWER_CONSTRAINT = 32,
+    POWER_CAPABILITY = 33,
+    TPC_REQUEST = 34,
+    TPC_REPORT = 35,
+    SUPPORTED_CHANNELS = 36,
+    CHANNEL_SWITCH_ANN = 37,
+    QUIET = 40,
+    IBSS_DFS = 41,
+    HT_CAPABILITY = 45,
+    HT_OPERATION = 61,
+    BSSCO_2040 = 72,
+    OVERLAPBSSSCANPARAM = 74,
+    EXT_CAPABILITY = 127,
+
+    ERP_INFO = 42,
+    EXTENDED_SUPPORTED_RATES = 50,
+
+    VENDOR_SPECIFIC_221 = 221,
+    WMM_IE = VENDOR_SPECIFIC_221,
+
+    WPS_IE = VENDOR_SPECIFIC_221,
+
+    WPA_IE = VENDOR_SPECIFIC_221,
+    RSN_IE = 48,
+} __ATTRIB_PACK__ IEEEtypes_ElementId_e;
+
+/** Capability Bit Map*/
+#ifdef BIG_ENDIAN
+typedef struct _IEEEtypes_CapInfo_t
+{
+    t_u8 rsrvd1:2;
+    t_u8 dsss_ofdm:1;
+    t_u8 rsvrd2:2;
+    t_u8 short_slot_time:1;
+    t_u8 rsrvd3:1;
+    t_u8 spectrum_mgmt:1;
+    t_u8 chan_agility:1;
+    t_u8 pbcc:1;
+    t_u8 short_preamble:1;
+    t_u8 privacy:1;
+    t_u8 cf_poll_rqst:1;
+    t_u8 cf_pollable:1;
+    t_u8 ibss:1;
+    t_u8 ess:1;
+} __ATTRIB_PACK__ IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t;
+#else
+typedef struct _IEEEtypes_CapInfo_t
+{
+    /** Capability Bit Map : ESS */
+    t_u8 ess:1;
+    /** Capability Bit Map : IBSS */
+    t_u8 ibss:1;
+    /** Capability Bit Map : CF pollable */
+    t_u8 cf_pollable:1;
+    /** Capability Bit Map : CF poll request */
+    t_u8 cf_poll_rqst:1;
+    /** Capability Bit Map : privacy */
+    t_u8 privacy:1;
+    /** Capability Bit Map : Short preamble */
+    t_u8 short_preamble:1;
+    /** Capability Bit Map : PBCC */
+    t_u8 pbcc:1;
+    /** Capability Bit Map : Channel agility */
+    t_u8 chan_agility:1;
+    /** Capability Bit Map : Spectrum management */
+    t_u8 spectrum_mgmt:1;
+    /** Capability Bit Map : Reserved */
+    t_u8 rsrvd3:1;
+    /** Capability Bit Map : Short slot time */
+    t_u8 short_slot_time:1;
+    /** Capability Bit Map : APSD */
+    t_u8 apsd:1;
+    /** Capability Bit Map : Reserved */
+    t_u8 rsvrd2:1;
+    /** Capability Bit Map : DSS OFDM */
+    t_u8 dsss_ofdm:1;
+    /** Capability Bit Map : Reserved */
+    t_u8 rsrvd1:2;
+} __ATTRIB_PACK__ IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t;
+#endif /* BIG_ENDIAN */
+
+/** IEEE IE header */
+typedef struct _IEEEtypes_Header_t
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 len;
+} __ATTRIB_PACK__ IEEEtypes_Header_t, *pIEEEtypes_Header_t;
+
+/** Vendor specific IE header */
+typedef struct _IEEEtypes_VendorHeader_t
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 len;
+    /** OUI */
+    t_u8 oui[3];
+    /** OUI type */
+    t_u8 oui_type;
+    /** OUI subtype */
+    t_u8 oui_subtype;
+    /** Version */
+    t_u8 version;
+} __ATTRIB_PACK__ IEEEtypes_VendorHeader_t, *pIEEEtypes_VendorHeader_t;
+
+/** Vendor specific IE */
+typedef struct _IEEEtypes_VendorSpecific_t
+{
+    /** Vendor specific IE header */
+    IEEEtypes_VendorHeader_t vend_hdr;
+    /** IE Max - size of previous fields */
+    t_u8 data[IEEE_MAX_IE_SIZE - sizeof(IEEEtypes_VendorHeader_t)];
+}
+__ATTRIB_PACK__ IEEEtypes_VendorSpecific_t, *pIEEEtypes_VendorSpecific_t;
+
+/** IEEE IE */
+typedef struct _IEEEtypes_Generic_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** IE Max - size of previous fields */
+    t_u8 data[IEEE_MAX_IE_SIZE - sizeof(IEEEtypes_Header_t)];
+}
+__ATTRIB_PACK__ IEEEtypes_Generic_t, *pIEEEtypes_Generic_t;
+
+/** Size of a TSPEC.  Used to allocate necessary buffer space in commands */
+#define WMM_TSPEC_SIZE              63
+
+/** Maximum number of AC QOS queues available in the driver/firmware */
+#define MAX_AC_QUEUES               4
+
+/** Extra IE bytes allocated in messages for appended IEs after a TSPEC */
+#define WMM_ADDTS_EXTRA_IE_BYTES    256
+
+/**
+ *  @brief Enumeration for the command result from an ADDTS or DELTS command
+ */
+typedef enum
+{
+    TSPEC_RESULT_SUCCESS = 0,
+    TSPEC_RESULT_EXEC_FAILURE = 1,
+    TSPEC_RESULT_TIMEOUT = 2,
+    TSPEC_RESULT_DATA_INVALID = 3,
+} __ATTRIB_PACK__ mlan_wmm_tspec_result_e;
+
+/**
+ *  @brief Enumeration for the action field in the Queue configure command
+ */
+typedef enum
+{
+    WMM_QUEUE_CONFIG_ACTION_GET = 0,
+    WMM_QUEUE_CONFIG_ACTION_SET = 1,
+    WMM_QUEUE_CONFIG_ACTION_DEFAULT = 2,
+
+    WMM_QUEUE_CONFIG_ACTION_MAX
+} __ATTRIB_PACK__ mlan_wmm_queue_config_action_e;
+
+/**
+ *   @brief Enumeration for the action field in the queue stats command
+ */
+typedef enum
+{
+    WMM_STATS_ACTION_START = 0,
+    WMM_STATS_ACTION_STOP = 1,
+    WMM_STATS_ACTION_GET_CLR = 2,
+    WMM_STATS_ACTION_SET_CFG = 3,       /* Not currently used */
+    WMM_STATS_ACTION_GET_CFG = 4,       /* Not currently used */
+
+    WMM_STATS_ACTION_MAX
+} __ATTRIB_PACK__ mlan_wmm_stats_action_e;
+
+/** Data structure of WMM QoS information */
+typedef struct _IEEEtypes_WmmQosInfo_t
+{
+#ifdef BIG_ENDIAN
+    /** QoS UAPSD */
+    t_u8 qos_uapsd:1;
+    /** Reserved */
+    t_u8 reserved:3;
+    /** Parameter set count */
+    t_u8 para_set_count:4;
+#else
+    /** Parameter set count */
+    t_u8 para_set_count:4;
+    /** Reserved */
+    t_u8 reserved:3;
+    /** QoS UAPSD */
+    t_u8 qos_uapsd:1;
+#endif
+} __ATTRIB_PACK__ IEEEtypes_WmmQosInfo_t, *pIEEEtypes_WmmQosInfo_t;
+
+/** Data structure of WMM Aci/Aifsn */
+typedef struct _IEEEtypes_WmmAciAifsn_t
+{
+#ifdef BIG_ENDIAN
+    /** Reserved */
+    t_u8 reserved:1;
+    /** Aci */
+    t_u8 aci:2;
+    /** Acm */
+    t_u8 acm:1;
+    /** Aifsn */
+    t_u8 aifsn:4;
+#else
+    /** Aifsn */
+    t_u8 aifsn:4;
+    /** Acm */
+    t_u8 acm:1;
+    /** Aci */
+    t_u8 aci:2;
+    /** Reserved */
+    t_u8 reserved:1;
+#endif
+} __ATTRIB_PACK__ IEEEtypes_WmmAciAifsn_t, *pIEEEtypes_WmmAciAifsn_t;
+
+/** Data structure of WMM ECW */
+typedef struct _IEEEtypes_WmmEcw_t
+{
+#ifdef BIG_ENDIAN
+    /** Maximum Ecw */
+    t_u8 ecw_max:4;
+    /** Minimum Ecw */
+    t_u8 ecw_min:4;
+#else
+    /** Minimum Ecw */
+    t_u8 ecw_min:4;
+    /** Maximum Ecw */
+    t_u8 ecw_max:4;
+#endif
+} __ATTRIB_PACK__ IEEEtypes_WmmEcw_t, *pIEEEtypes_WmmEcw_t;
+
+/** Data structure of WMM AC parameters  */
+typedef struct _IEEEtypes_WmmAcParameters_t
+{
+    IEEEtypes_WmmAciAifsn_t aci_aifsn;      /**< AciAifSn */
+    IEEEtypes_WmmEcw_t ecw;                 /**< Ecw */
+    t_u16 tx_op_limit;                      /**< Tx op limit */
+} __ATTRIB_PACK__ IEEEtypes_WmmAcParameters_t, *pIEEEtypes_WmmAcParameters_t;
+
+/** Data structure of WMM Info IE  */
+typedef struct _IEEEtypes_WmmInfo_t
+{
+
+    /**
+     * WMM Info IE - Vendor Specific Header:
+     *   element_id  [221/0xdd]
+     *   Len         [7] 
+     *   Oui         [00:50:f2]
+     *   OuiType     [2]
+     *   OuiSubType  [0]
+     *   Version     [1]
+     */
+    IEEEtypes_VendorHeader_t vend_hdr;
+
+    /** QoS information */
+    IEEEtypes_WmmQosInfo_t qos_info;
+
+} __ATTRIB_PACK__ IEEEtypes_WmmInfo_t, *pIEEEtypes_WmmInfo_t;
+
+/** Data structure of WMM parameter IE  */
+typedef struct _IEEEtypes_WmmParameter_t
+{
+    /**
+     * WMM Parameter IE - Vendor Specific Header:
+     *   element_id  [221/0xdd]
+     *   Len         [24] 
+     *   Oui         [00:50:f2]
+     *   OuiType     [2]
+     *   OuiSubType  [1]
+     *   Version     [1]
+     */
+    IEEEtypes_VendorHeader_t vend_hdr;
+
+    /** QoS information */
+    IEEEtypes_WmmQosInfo_t qos_info;
+    /** Reserved */
+    t_u8 reserved;
+
+    /** AC Parameters Record WMM_AC_BE, WMM_AC_BK, WMM_AC_VI, WMM_AC_VO */
+    IEEEtypes_WmmAcParameters_t ac_params[MAX_AC_QUEUES];
+
+} __ATTRIB_PACK__ IEEEtypes_WmmParameter_t, *pIEEEtypes_WmmParameter_t;
+
+/**
+ *  @brief IOCTL structure to send an ADDTS request and retrieve the response.
+ *
+ *  IOCTL structure from the application layer relayed to firmware to
+ *    instigate an ADDTS management frame with an appropriate TSPEC IE as well
+ *    as any additional IEs appended in the ADDTS Action frame.
+ *
+ *  @sa wlan_wmm_addts_req_ioctl
+ */
+typedef struct
+{
+    mlan_wmm_tspec_result_e commandResult;          /**< Firmware execution result */
+    t_u32 timeout_ms;                               /**< Timeout value in milliseconds */
+    t_u8 ieeeStatusCode;                            /**< IEEE status code */
+    t_u8 tspecData[WMM_TSPEC_SIZE];                 /**< TSPEC to send in the ADDTS */
+    t_u8 addtsExtraIEBuf[WMM_ADDTS_EXTRA_IE_BYTES]; /**< ADDTS extra IE buffer */
+} wlan_ioctl_wmm_addts_req_t;
+
+/**
+ *  @brief IOCTL structure to send a DELTS request.
+ *
+ *  IOCTL structure from the application layer relayed to firmware to
+ *    instigate an DELTS management frame with an appropriate TSPEC IE.
+ *
+ *  @sa wlan_wmm_delts_req_ioctl
+ */
+typedef struct
+{
+    mlan_wmm_tspec_result_e commandResult;  /**< Firmware execution result */
+    t_u8 ieeeReasonCode;                    /**< IEEE reason code sent, unused for WMM */
+    t_u8 tspecData[WMM_TSPEC_SIZE];         /**< TSPEC to send in the DELTS */
+} wlan_ioctl_wmm_delts_req_t;
+
+/**
+ *  @brief IOCTL structure to configure a specific AC Queue's parameters
+ *
+ *  IOCTL structure from the application layer relayed to firmware to
+ *    get, set, or default the WMM AC queue parameters.
+ *
+ *  - msduLifetimeExpiry is ignored if set to 0 on a set command
+ *
+ *  @sa wlan_wmm_queue_config_ioctl
+ */
+typedef struct
+{
+    mlan_wmm_queue_config_action_e action;  /**< Set, Get, or Default */
+    mlan_wmm_ac_e accessCategory;           /**< WMM_AC_BK(0) to WMM_AC_VO(3) */
+    t_u16 msduLifetimeExpiry;               /**< lifetime expiry in TUs */
+    t_u8 supportedRates[10];                /**< Not supported yet */
+} wlan_ioctl_wmm_queue_config_t;
+
+/** Number of bins in the histogram for the HostCmd_DS_WMM_QUEUE_STATS */
+#define WMM_STATS_PKTS_HIST_BINS  7
+
+/**
+ *  @brief IOCTL structure to start, stop, and get statistics for a WMM AC
+ *
+ *  IOCTL structure from the application layer relayed to firmware to
+ *    start or stop statistical collection for a given AC.  Also used to
+ *    retrieve and clear the collected stats on a given AC.
+ *
+ *  @sa wlan_wmm_queue_stats_ioctl
+ */
+typedef struct
+{
+    mlan_wmm_stats_action_e action;  /**< Start, Stop, or Get  */
+    mlan_wmm_ac_e accessCategory;    /**< WMM_AC_BK(0) to WMM_AC_VO(3) */
+    t_u16 pktCount;      /**< Number of successful packets transmitted */
+    t_u16 pktLoss;       /**< Packets lost; not included in pktCount   */
+    t_u32 avgQueueDelay; /**< Average Queue delay in microseconds */
+    t_u32 avgTxDelay;    /**< Average Transmission delay in microseconds */
+    t_u16 usedTime;      /**< Calculated used time - units of 32 microseconds */
+    t_u16 policedTime;   /**< Calculated policed time - units of 32 microseconds */
+
+    /** @brief Queue Delay Histogram; number of packets per queue delay range
+     *
+     *  [0] -  0ms <= delay < 5ms
+     *  [1] -  5ms <= delay < 10ms
+     *  [2] - 10ms <= delay < 20ms
+     *  [3] - 20ms <= delay < 30ms
+     *  [4] - 30ms <= delay < 40ms
+     *  [5] - 40ms <= delay < 50ms
+     *  [6] - 50ms <= delay < msduLifetime (TUs)
+     */
+    t_u16 delayHistogram[WMM_STATS_PKTS_HIST_BINS];
+} wlan_ioctl_wmm_queue_stats_t;
+
+/**
+ *  @brief IOCTL and command sub structure for a Traffic stream status.
+ */
+typedef struct
+{
+    t_u8 tid;               /**< TSID: Range: 0->7 */
+    t_u8 valid;             /**< TSID specified is valid  */
+    t_u8 accessCategory;    /**< AC TSID is active on */
+    t_u8 userPriority;      /**< UP specified for the TSID */
+
+    t_u8 psb;               /**< Power save mode for TSID: 0 (legacy), 1 (UAPSD) */
+    t_u8 flowDir;           /**< Upstream (0), Downlink(1), Bidirectional(3) */
+    t_u16 mediumTime;       /**< Medium time granted for the TSID */
+} HostCmd_DS_WMM_TS_STATUS,
+    wlan_ioctl_wmm_ts_status_t, wlan_cmd_wmm_ts_status_t;
+
+/**
+ *  @brief IOCTL sub structure for a specific WMM AC Status
+ */
+typedef struct
+{
+    /** WMM Acm */
+    t_u8 wmmAcm;
+    /** Flow required flag */
+    t_u8 flowRequired;
+    /** Flow created flag */
+    t_u8 flowCreated;
+    /** Disabled flag */
+    t_u8 disabled;
+    /** delivery enabled */
+    t_u8 deliveryEnabled;
+    /** trigger enabled */
+    t_u8 triggerEnabled;
+} wlan_ioctl_wmm_queue_status_ac_t;
+
+/**
+ *  @brief IOCTL structure to retrieve the WMM AC Queue status
+ *
+ *  IOCTL structure from the application layer to retrieve:
+ *     - ACM bit setting for the AC
+ *     - Firmware status (flow required, flow created, flow disabled)
+ *
+ *  @sa wlan_wmm_queue_status_ioctl
+ */
+typedef struct
+{
+    /** WMM AC queue status */
+    wlan_ioctl_wmm_queue_status_ac_t acStatus[MAX_AC_QUEUES];
+} wlan_ioctl_wmm_queue_status_t;
+
+typedef struct _wlan_get_scan_table_fixed
+{
+    /** BSSID of this network */
+    t_u8 bssid[MLAN_MAC_ADDR_LENGTH];
+    /** Channel this beacon/probe response was detected */
+    t_u8 channel;
+    /** RSSI for the received packet */
+    t_u8 rssi;
+    /** TSF value from the firmware at packet reception */
+    t_u64 network_tsf;
+} wlan_get_scan_table_fixed;
+
+/**
+ *  Structure passed in the wlan_ioctl_get_scan_table_info for each
+ *    BSS returned in the WLAN_GET_SCAN_RESP IOCTL
+ */
+typedef struct _wlan_ioctl_get_scan_table_entry
+{
+    /**
+     *  Fixed field length included in the response.
+     *
+     *  Length value is included so future fixed fields can be added to the
+     *   response without breaking backwards compatibility.  Use the length
+     *   to find the offset for the bssInfoLength field, not a sizeof() calc.
+     */
+    t_u32 fixed_field_length;
+
+    /**
+     *  Always present, fixed length data fields for the BSS
+     */
+    wlan_get_scan_table_fixed fixed_fields;
+
+    /**
+     *  Length of the BSS Information (probe resp or beacon) that
+     *    follows starting at bssInfoBuffer
+     */
+    t_u32 bss_info_length;
+
+    /**
+     *  Probe response or beacon scanned for the BSS.
+     *
+     *  Field layout:
+     *   - TSF              8 octets
+     *   - Beacon Interval  2 octets
+     *   - Capability Info  2 octets
+     *
+     *   - IEEE Infomation Elements; variable number & length per 802.11 spec
+     */
+    t_u8 bss_info_buffer[1];
+} wlan_ioctl_get_scan_table_entry;
+
+/**
+ *  Sructure to retrieve the scan table
+ */
+typedef struct
+{
+    /**
+     *  - Zero based scan entry to start retrieval in command request
+     *  - Number of scans entries returned in command response
+     */
+    t_u32 scan_number;
+    /**
+     * Buffer marker for multiple wlan_ioctl_get_scan_table_entry structures.
+     *   Each struct is padded to the nearest 32 bit boundary.
+     */
+    t_u8 scan_table_entry_buf[1];
+} wlan_ioctl_get_scan_table_info;
+
+typedef struct
+{
+    t_u8 chan_number;  /**< Channel Number to scan */
+    t_u8 radio_type;   /**< Radio type: 'B/G' Band = 0, 'A' Band = 1 */
+    t_u8 scan_type;    /**< Scan type: Active = 0, Passive = 1 */
+    t_u8 reserved;    /**< Reserved */
+    t_u32 scan_time;   /**< Scan duration in milliseconds; if 0 default used */
+} __ATTRIB_PACK__ wlan_ioctl_user_scan_chan;
+
+typedef struct
+{
+    char ssid[MRVDRV_MAX_SSID_LENGTH + 1];  /**< SSID */
+    t_u8 max_len;                              /**< Maximum length of SSID */
+} __ATTRIB_PACK__ wlan_ioctl_user_scan_ssid;
+
+typedef struct
+{
+
+    /** Flag set to keep the previous scan table intact */
+    t_u8 keep_previous_scan;    /* Do not erase the existing scan results */
+
+    /** BSS mode to be sent in the firmware command */
+    t_u8 bss_mode;
+
+    /** Configure the number of probe requests for active chan scans */
+    t_u8 num_probes;
+
+    /** Reserved */
+    t_u8 reserved;
+
+    /** BSSID filter sent in the firmware command to limit the results */
+    t_u8 specific_bssid[ETH_ALEN];
+    /** SSID filter list used in the to limit the scan results */
+    wlan_ioctl_user_scan_ssid ssid_list[MRVDRV_MAX_SSID_LIST_LENGTH];
+
+    /** Variable number (fixed maximum) of channels to scan up */
+    wlan_ioctl_user_scan_chan chan_list[WLAN_IOCTL_USER_SCAN_CHAN_MAX];
+
+} __ATTRIB_PACK__ wlan_ioctl_user_scan_cfg;
+
+int process_sdcmd52rw(int argc, char *argv[]);
+int process_sdcmd53rw(int argc, char *argv[]);
+int process_setuserscan(int argc, char *argv[]);
+int process_getscantable(int argc, char *argv[]);
+
+#endif /* _MLANMISC_H_ */
diff --git a/wlan_src/mlan/mlan.h b/wlan_src/mlan/mlan.h
new file mode 100755
index 0000000..14dcfd6
--- /dev/null
+++ b/wlan_src/mlan/mlan.h
@@ -0,0 +1,23 @@
+/** @file mlan.h
+ *
+ *  @brief This file declares all APIs that will be called from MOAL module.
+ *  It also defines the data structures used for APIs between MLAN and MOAL.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    10/13/2008: initial version
+    11/07/2008: split mlan.h into mlan_decl.h & mlan_ioctl.h
+******************************************************/
+
+#ifndef _MLAN_H_
+#define _MLAN_H_
+
+#include "mlan_decl.h"
+#include "mlan_ioctl.h"
+#include "mlan_ieee.h"
+
+#endif /* !_MLAN_H_ */
diff --git a/wlan_src/mlan/mlan_11d.c b/wlan_src/mlan/mlan_11d.c
new file mode 100755
index 0000000..f808608
--- /dev/null
+++ b/wlan_src/mlan/mlan_11d.c
@@ -0,0 +1,1298 @@
+/** @file mlan_11d.c
+ *
+ *  @brief This file contains functions for 802.11D.
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+/********************************************************
+Change log:
+    10/21/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+
+/********************************************************
+                Local Variables
+********************************************************/
+
+/** Default Tx power */
+#define TX_PWR_DEFAULT  10
+
+/** Universal region code */
+#define UNIVERSAL_REGION_CODE   0xff
+
+/** Region code mapping */
+typedef struct _region_code_mapping
+{
+    /** Region */
+    t_u8 region[COUNTRY_CODE_LEN];
+    /** Code */
+    t_u8 code;
+} region_code_mapping_t;
+
+/** Region code mapping table */
+static region_code_mapping_t region_code_mapping[] = {
+    {"US ", 0x10},              /* US FCC */
+    {"CA ", 0x20},              /* IC Canada */
+    {"SG ", 0x10},              /* Singapore */
+    {"EU ", 0x30},              /* ETSI */
+    {"AU ", 0x30},              /* Australia */
+    {"KR ", 0x30},              /* Republic Of Korea */
+    {"FR ", 0x32},              /* France */
+    {"JP ", 0x40},              /* Japan */
+    {"JP ", 0x41},              /* Japan */
+    {"JP ", 0xFF},              /* Japan special */
+};
+
+/* Following two structures define the supported channels */
+/** Channels for 802.11b/g */
+static chan_freq_power_t channel_freq_power_UN_BG[] = {
+    {1, 2412, TX_PWR_DEFAULT},
+    {2, 2417, TX_PWR_DEFAULT},
+    {3, 2422, TX_PWR_DEFAULT},
+    {4, 2427, TX_PWR_DEFAULT},
+    {5, 2432, TX_PWR_DEFAULT},
+    {6, 2437, TX_PWR_DEFAULT},
+    {7, 2442, TX_PWR_DEFAULT},
+    {8, 2447, TX_PWR_DEFAULT},
+    {9, 2452, TX_PWR_DEFAULT},
+    {10, 2457, TX_PWR_DEFAULT},
+    {11, 2462, TX_PWR_DEFAULT},
+    {12, 2467, TX_PWR_DEFAULT},
+    {13, 2472, TX_PWR_DEFAULT},
+    {14, 2484, TX_PWR_DEFAULT}
+};
+
+/** Channels for 802.11a/j */
+static chan_freq_power_t channel_freq_power_UN_AJ[] = {
+    {8, 5040, TX_PWR_DEFAULT},
+    {12, 5060, TX_PWR_DEFAULT},
+    {16, 5080, TX_PWR_DEFAULT},
+    {34, 5170, TX_PWR_DEFAULT},
+    {38, 5190, TX_PWR_DEFAULT},
+    {42, 5210, TX_PWR_DEFAULT},
+    {46, 5230, TX_PWR_DEFAULT},
+    {36, 5180, TX_PWR_DEFAULT},
+    {40, 5200, TX_PWR_DEFAULT},
+    {44, 5220, TX_PWR_DEFAULT},
+    {48, 5240, TX_PWR_DEFAULT},
+    {52, 5260, TX_PWR_DEFAULT},
+    {56, 5280, TX_PWR_DEFAULT},
+    {60, 5300, TX_PWR_DEFAULT},
+    {64, 5320, TX_PWR_DEFAULT},
+    {100, 5500, TX_PWR_DEFAULT},
+    {104, 5520, TX_PWR_DEFAULT},
+    {108, 5540, TX_PWR_DEFAULT},
+    {112, 5560, TX_PWR_DEFAULT},
+    {116, 5580, TX_PWR_DEFAULT},
+    {120, 5600, TX_PWR_DEFAULT},
+    {124, 5620, TX_PWR_DEFAULT},
+    {128, 5640, TX_PWR_DEFAULT},
+    {132, 5660, TX_PWR_DEFAULT},
+    {136, 5680, TX_PWR_DEFAULT},
+    {140, 5700, TX_PWR_DEFAULT},
+    {149, 5745, TX_PWR_DEFAULT},
+    {153, 5765, TX_PWR_DEFAULT},
+    {157, 5785, TX_PWR_DEFAULT},
+    {161, 5805, TX_PWR_DEFAULT},
+    {165, 5825, TX_PWR_DEFAULT},
+/*  {240, 4920, TX_PWR_DEFAULT}, 
+    {244, 4940, TX_PWR_DEFAULT}, 
+    {248, 4960, TX_PWR_DEFAULT}, 
+    {252, 4980, TX_PWR_DEFAULT}, 
+channels for 11J JP 10M channel gap */
+};
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+/** 
+ *  @brief This function converts a lowercase character to uppercase
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param c            Input character
+ *
+ *  @return     Corresponding uppercase character
+ */
+static t_u8
+wlan_11d_lower_to_upper(pmlan_adapter pmadapter, t_u8 c)
+{
+    t_u8 upper;
+
+    ENTER();
+
+    if (c >= 'a' && c <= 'z')
+        upper = c - 0x20;
+    else
+        upper = c;
+
+    LEAVE();
+    return upper;
+}
+
+/** 
+ *  @brief This function convert region string to code integer
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param region   	Region string
+ *
+ *  @return		Region id
+ */
+static t_u8
+wlan_11d_region_2_code(pmlan_adapter pmadapter, t_u8 * region)
+{
+    t_u8 i;
+    t_u8 size = sizeof(region_code_mapping) / sizeof(region_code_mapping_t);
+
+    ENTER();
+
+    for (i = 0; i < COUNTRY_CODE_LEN && region[i]; i++)
+        region[i] = wlan_11d_lower_to_upper(pmadapter, region[i]);
+
+    /* Look for region in mapping table */
+    for (i = 0; i < size; i++) {
+        if (!memcmp(region, region_code_mapping[i].region, COUNTRY_CODE_LEN)) {
+            LEAVE();
+            return (region_code_mapping[i].code);
+        }
+    }
+
+    LEAVE();
+    /* Default is US */
+    return (region_code_mapping[0].code);
+}
+
+/** 
+ *  @brief This function converts interger code to region string
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param code     	Region code
+ *
+ *  @return		Region string
+ */
+static t_u8 *
+wlan_11d_code_2_region(pmlan_adapter pmadapter, t_u8 code)
+{
+    t_u8 i;
+    t_u8 size = sizeof(region_code_mapping) / sizeof(region_code_mapping_t);
+
+    ENTER();
+
+    /* Look for code in mapping table */
+    for (i = 0; i < size; i++) {
+        if (region_code_mapping[i].code == code) {
+            LEAVE();
+            return (region_code_mapping[i].region);
+        }
+    }
+
+    LEAVE();
+    /* Default is US */
+    return (region_code_mapping[0].region);
+}
+
+/** 
+ *  @brief This function Checks if chan txpwr is learned from AP/IBSS
+ *
+ *  @param pmadapter            A pointer to mlan_adapter structure
+ *  @param chan                 Channel number
+ *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t     
+ *
+ *  @return                     MTRUE or MFALSE
+ */
+static t_u8
+wlan_11d_channel_known(pmlan_adapter pmadapter,
+                       t_u8 chan, parsed_region_chan_11d_t * parsed_region_chan)
+{
+    chan_power_11d_t *pchan_pwr = parsed_region_chan->chan_pwr;
+    t_u8 no_of_chan = parsed_region_chan->no_of_chan;
+    t_u8 i = 0;
+
+    ENTER();
+
+    HEXDUMP("11D: parsed_region_chan", (t_u8 *) pchan_pwr,
+            sizeof(chan_power_11d_t) * no_of_chan);
+
+    /* Search channel */
+    for (i = 0; i < no_of_chan; i++) {
+        if (chan == pchan_pwr[i].chan) {
+            PRINTM(MINFO, "11D: Found chan:%d\n", chan);
+            LEAVE();
+            return MTRUE;
+        }
+    }
+
+    PRINTM(MERROR, "11D: Could not find chan:%d\n", chan);
+    LEAVE();
+    return MFALSE;
+}
+
+/** 
+ *  @brief This function sets domain info to FW
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_11d_set_domain_info(mlan_private * pmpriv)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* Send cmd to FW to set domain info */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11D_DOMAIN_INFO,
+                           HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
+    if (ret)
+        PRINTM(MERROR, "11D: Failed to download domain Info\n");
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function generates parsed_region_chan from Domain Info
+ *           learned from AP/IBSS
+ *
+ *  @param pmadapter            Pointer to mlan_adapter structure
+ *  @param region_chan          Pointer to region_chan_t
+ *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t
+ *
+ *  @return                     N/A
+ */
+static t_void
+wlan_11d_generate_parsed_region_chan(pmlan_adapter pmadapter,
+                                     region_chan_t * region_chan,
+                                     parsed_region_chan_11d_t *
+                                     parsed_region_chan)
+{
+    chan_freq_power_t *cfp;
+    t_u8 i;
+
+    ENTER();
+
+    /* Region channel must be provided */
+    if (!region_chan) {
+        PRINTM(MINFO, "11D: region_chan is MNULL\n");
+        LEAVE();
+        return;
+    }
+
+    /* Get channel-frequecy-power trio */
+    cfp = region_chan->pcfp;
+    if (!cfp) {
+        PRINTM(MINFO, "11D: cfp equal MNULL \n");
+        LEAVE();
+        return;
+    }
+
+    /* Set band, region and country code */
+    parsed_region_chan->band = region_chan->band;
+    parsed_region_chan->region = region_chan->region;
+    memcpy(parsed_region_chan->country_code,
+           wlan_11d_code_2_region(pmadapter, region_chan->region),
+           COUNTRY_CODE_LEN);
+
+    PRINTM(MINFO, "11D: region[0x%x] band[%d]\n", parsed_region_chan->region,
+           parsed_region_chan->band);
+
+    /* Set channel and power */
+    for (i = 0; i < region_chan->num_cfp; i++, cfp++) {
+        parsed_region_chan->chan_pwr[i].chan = (t_u8) cfp->channel;
+        parsed_region_chan->chan_pwr[i].pwr = (t_u8) cfp->max_tx_power;
+        PRINTM(MINFO, "11D: Chan[%d] Pwr[%d]\n",
+               parsed_region_chan->chan_pwr[i].chan,
+               parsed_region_chan->chan_pwr[i].pwr);
+    }
+    parsed_region_chan->no_of_chan = region_chan->num_cfp;
+
+    PRINTM(MINFO, "11D: no_of_chan[%d]\n", parsed_region_chan->no_of_chan);
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function generates domain_info from parsed_region_chan
+ *
+ *  @param pmadapter            Pointer to mlan_adapter structure
+ *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t
+ *  @param domain_info          Pointer to wlan_802_11d_domain_reg_t
+ *
+ *  @return                     MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_11d_generate_domain_info(pmlan_adapter pmadapter,
+                              parsed_region_chan_11d_t * parsed_region_chan,
+                              wlan_802_11d_domain_reg_t * domain_info)
+{
+    t_u8 no_of_sub_band = 0;
+    t_u8 no_of_chan = parsed_region_chan->no_of_chan;
+    t_u8 no_of_parsed_chan = 0;
+    t_u8 first_chan = 0, next_chan = 0, max_pwr = 0;
+    t_u8 i, flag = 0;
+
+    ENTER();
+
+    /* Set country code */
+    memcpy(domain_info->country_code,
+           parsed_region_chan->country_code, COUNTRY_CODE_LEN);
+
+    PRINTM(MINFO, "11D: no_of_chan=%d\n", no_of_chan);
+    HEXDUMP("11D: parsed_region_chan", (t_u8 *) parsed_region_chan,
+            sizeof(parsed_region_chan_11d_t));
+
+    /* Set channel and power */
+    for (i = 0; i < no_of_chan; i++) {
+        if (!flag) {
+            flag = 1;
+            next_chan = first_chan = parsed_region_chan->chan_pwr[i].chan;
+            max_pwr = parsed_region_chan->chan_pwr[i].pwr;
+            no_of_parsed_chan = 1;
+            continue;
+        }
+
+        if (parsed_region_chan->chan_pwr[i].chan == next_chan + 1 &&
+            parsed_region_chan->chan_pwr[i].pwr == max_pwr) {
+            next_chan++;
+            no_of_parsed_chan++;
+        } else {
+            domain_info->sub_band[no_of_sub_band].first_chan = first_chan;
+            domain_info->sub_band[no_of_sub_band].no_of_chan =
+                no_of_parsed_chan;
+            domain_info->sub_band[no_of_sub_band].max_tx_pwr = max_pwr;
+            no_of_sub_band++;
+            no_of_parsed_chan = 1;
+            next_chan = first_chan = parsed_region_chan->chan_pwr[i].chan;
+            max_pwr = parsed_region_chan->chan_pwr[i].pwr;
+        }
+    }
+
+    if (flag) {
+        domain_info->sub_band[no_of_sub_band].first_chan = first_chan;
+        domain_info->sub_band[no_of_sub_band].no_of_chan = no_of_parsed_chan;
+        domain_info->sub_band[no_of_sub_band].max_tx_pwr = max_pwr;
+        no_of_sub_band++;
+    }
+    domain_info->no_of_sub_band = no_of_sub_band;
+
+    PRINTM(MINFO, "11D: no_of_sub_band=0x%x\n", domain_info->no_of_sub_band);
+    HEXDUMP("11D: domain_info", (t_u8 *) domain_info,
+            COUNTRY_CODE_LEN + 1 +
+            sizeof(IEEEtypes_SubbandSet_t) * no_of_sub_band);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function updates the channel power table with the channel 
+ *            present in BSSDescriptor.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pbss_desc    A pointer to BSSDescriptor_t
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_11d_update_chan_pwr_table(mlan_private * pmpriv,
+                               BSSDescriptor_t * pbss_desc)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    parsed_region_chan_11d_t *parsed_region_chan =
+        &pmadapter->parsed_region_chan;
+    t_u16 i;
+    t_u8 tx_power = 0;
+    t_u8 chan;
+
+    ENTER();
+
+    chan = pbss_desc->phy_param_set.ds_param_set.current_chan;
+
+    tx_power = wlan_get_txpwr_of_chan_from_cfp(pmpriv, chan);
+
+    if (!tx_power) {
+        PRINTM(MMSG, "11D: Invalid channel\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Check whether the channel already exists in channel power table of
+       parsed region */
+    for (i = 0; ((i < parsed_region_chan->no_of_chan) &&
+                 (i < MAX_NO_OF_CHAN)); i++) {
+        if (parsed_region_chan->chan_pwr[i].chan == chan) {
+            /* Channel already exists update the tx_power */
+            parsed_region_chan->chan_pwr[i].pwr =
+                MIN(parsed_region_chan->chan_pwr[i].pwr, tx_power);
+            break;
+        }
+    }
+
+    if (i == parsed_region_chan->no_of_chan && i < MAX_NO_OF_CHAN) {
+        /* Channel not found. Update the channel in the channel-power table */
+        parsed_region_chan->chan_pwr[i].chan = chan;
+        parsed_region_chan->chan_pwr[i].pwr = tx_power;
+        parsed_region_chan->no_of_chan++;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function finds the no_of_chan-th chan after the first_chan
+ *
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *  @param band       Band
+ *  @param first_chan First channel number
+ *  @param no_of_chan Number of channels
+ *  @param chan       Pointer to the returned no_of_chan-th chan number
+ *
+ *  @return           MTRUE or MFALSE
+ */
+static t_u8
+wlan_11d_get_chan(pmlan_adapter pmadapter, t_u8 band, t_u8 first_chan,
+                  t_u8 no_of_chan, t_u8 * chan)
+{
+    chan_freq_power_t *cfp = MNULL;
+    t_u8 i;
+    t_u8 cfp_no = 0;
+
+    ENTER();
+    if (band & (BAND_B | BAND_G | BAND_GN)) {
+        cfp = channel_freq_power_UN_BG;
+        cfp_no = sizeof(channel_freq_power_UN_BG) / sizeof(chan_freq_power_t);
+    } else if (band & (BAND_A | BAND_AN)) {
+        cfp = channel_freq_power_UN_AJ;
+        cfp_no = sizeof(channel_freq_power_UN_AJ) / sizeof(chan_freq_power_t);
+    } else {
+        PRINTM(MERROR, "11D: Wrong Band[%d]\n", band);
+        LEAVE();
+        return MFALSE;
+    }
+    /* Locate the first_chan */
+    for (i = 0; i < cfp_no; i++) {
+        if (cfp && ((cfp + i)->channel == first_chan)) {
+            PRINTM(MINFO, "11D: first_chan found\n");
+            break;
+        }
+    }
+
+    if (i < cfp_no) {
+        /* Check if beyond the boundary */
+        if (i + no_of_chan < cfp_no) {
+            /* Get first_chan + no_of_chan */
+            *chan = (t_u8) (cfp + i + no_of_chan)->channel;
+            LEAVE();
+            return MTRUE;
+        }
+    }
+
+    LEAVE();
+    return MFALSE;
+}
+
+/** 
+ *  @brief This function parses country information for region channel
+ *
+ *  @param pmadapter            Pointer to mlan_adapter structure
+ *  @param country_info         Country information
+ *  @param band                 Chan band
+ *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t     
+ *
+ *  @return                     MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_11d_parse_domain_info(pmlan_adapter pmadapter,
+                           IEEEtypes_CountryInfoFullSet_t * country_info,
+                           t_u8 band,
+                           parsed_region_chan_11d_t * parsed_region_chan)
+{
+    t_u8 no_of_sub_band, no_of_chan;
+    t_u8 last_chan, first_chan, cur_chan = 0;
+    t_u8 idx = 0;
+    t_u8 j, i;
+
+    ENTER();
+
+    /* 
+     * Validation Rules:
+     *    1. Valid Region Code
+     *    2. First Chan increment
+     *    3. Channel range no overlap
+     *    4. Channel is valid?
+     *    5. Channel is supported by Region?
+     *    6. Others
+     */
+
+    HEXDUMP("country_info", (t_u8 *) country_info, 30);
+
+    if (!(*(country_info->country_code)) ||
+        (country_info->len <= COUNTRY_CODE_LEN)) {
+        /* No region info or wrong region info: treat as no 11D info */
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Step 1: Check region_code */
+    parsed_region_chan->region =
+        wlan_11d_region_2_code(pmadapter, country_info->country_code);
+
+    PRINTM(MINFO, "11D: region code=0x%x\n", (t_u8) parsed_region_chan->region);
+    HEXDUMP("11D: Country Code", (t_u8 *) country_info->country_code,
+            COUNTRY_CODE_LEN);
+
+    parsed_region_chan->band = band;
+
+    memcpy(parsed_region_chan->country_code,
+           country_info->country_code, COUNTRY_CODE_LEN);
+
+    no_of_sub_band = (country_info->len - COUNTRY_CODE_LEN) /
+        sizeof(IEEEtypes_SubbandSet_t);
+
+    for (j = 0, last_chan = 0; j < no_of_sub_band; j++) {
+
+        if (country_info->sub_band[j].first_chan <= last_chan) {
+            /* Step2&3: Check First Chan Num increment and no overlap */
+            PRINTM(MINFO, "11D: Chan[%d>%d] Overlap\n",
+                   country_info->sub_band[j].first_chan, last_chan);
+            continue;
+        }
+
+        first_chan = country_info->sub_band[j].first_chan;
+        no_of_chan = country_info->sub_band[j].no_of_chan;
+
+        for (i = 0; idx < MAX_NO_OF_CHAN && i < no_of_chan; i++) {
+            /* Step 4 : Channel is supported? */
+            if (wlan_11d_get_chan(pmadapter, band, first_chan, i, &cur_chan) ==
+                MFALSE) {
+                /* Chan is not found in UN table */
+                PRINTM(MWARN, "11D: chan is not supported: %d\n", i);
+                break;
+            }
+
+            last_chan = cur_chan;
+
+            /* Step 5: We don't need to check if cur_chan is supported by mrvl
+               in region */
+            parsed_region_chan->chan_pwr[idx].chan = cur_chan;
+            parsed_region_chan->chan_pwr[idx].pwr =
+                country_info->sub_band[j].max_tx_pwr;
+            idx++;
+        }
+
+        /* Step 6: Add other checking if any */
+    }
+
+    parsed_region_chan->no_of_chan = idx;
+
+    PRINTM(MINFO, "11D: no_of_chan=0x%x\n", parsed_region_chan->no_of_chan);
+    HEXDUMP("11D: parsed_region_chan", (t_u8 *) parsed_region_chan,
+            2 + COUNTRY_CODE_LEN + sizeof(parsed_region_chan_11d_t) * idx);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function processes the country info present in BSSDescriptor.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pbss_desc     A pointer to BSSDescriptor_t
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_11d_process_country_info(mlan_private * pmpriv,
+                              BSSDescriptor_t * pbss_desc)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    parsed_region_chan_11d_t region_chan;
+    parsed_region_chan_11d_t *parsed_region_chan =
+        &pmadapter->parsed_region_chan;
+    t_u16 i, j, num_chan_added = 0;
+
+    ENTER();
+
+    memset(&region_chan, 0, sizeof(parsed_region_chan_11d_t));
+
+    /* Parse 11D country info */
+    wlan_11d_parse_domain_info(pmadapter, &pbss_desc->country_info,
+                               (t_u8) pbss_desc->bss_band, &region_chan);
+
+    if (parsed_region_chan->no_of_chan != 0) {
+        /* 
+         * Check if the channel number already exists in the 
+         * chan-power table of parsed_region_chan
+         */
+        for (i = 0; (i < region_chan.no_of_chan && i < MAX_NO_OF_CHAN); i++) {
+            for (j = 0; (j < parsed_region_chan->no_of_chan &&
+                         j < MAX_NO_OF_CHAN); j++) {
+                /* 
+                 * Channel already exists, update the tx power with minimum 
+                 * value among existing tx_power and new tx power
+                 */
+                if (region_chan.chan_pwr[i].chan ==
+                    parsed_region_chan->chan_pwr[j].chan) {
+                    parsed_region_chan->chan_pwr[j].pwr =
+                        MIN(parsed_region_chan->chan_pwr[j].pwr,
+                            region_chan.chan_pwr[i].pwr);
+                    break;
+                }
+            }
+
+            if (j == parsed_region_chan->no_of_chan && j < MAX_NO_OF_CHAN) {
+                /* 
+                 * Channel does not exist in the channel power table, 
+                 * update this new chan and tx_power to the channel power table
+                 */
+                parsed_region_chan->chan_pwr[parsed_region_chan->no_of_chan +
+                                             num_chan_added].chan =
+                    region_chan.chan_pwr[i].chan;
+                parsed_region_chan->chan_pwr[parsed_region_chan->no_of_chan +
+                                             num_chan_added].pwr =
+                    region_chan.chan_pwr[i].pwr;
+                num_chan_added++;
+            }
+        }
+        parsed_region_chan->no_of_chan += num_chan_added;
+    } else {
+        /* Parsed region is empty, copy the first one */
+        memcpy(parsed_region_chan,
+               &region_chan, sizeof(parsed_region_chan_11d_t));
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/********************************************************
+                Global functions
+********************************************************/
+
+/** 
+ *  @brief This function converts channel to frequency
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param chan         Channel number
+ *  @param band         Band
+ *
+ *  @return             Channel frequency
+ */
+t_u32
+wlan_11d_chan_2_freq(pmlan_adapter pmadapter, t_u8 chan, t_u8 band)
+{
+    chan_freq_power_t *cf;
+    t_u16 cnt;
+    t_u16 i;
+    t_u32 freq = 0;
+
+    ENTER();
+
+    /* Get channel-frequency-power trios */
+    if (band & (BAND_A | BAND_AN)) {
+        cf = channel_freq_power_UN_AJ;
+        cnt = sizeof(channel_freq_power_UN_AJ) / sizeof(chan_freq_power_t);
+    } else {
+        cf = channel_freq_power_UN_BG;
+        cnt = sizeof(channel_freq_power_UN_BG) / sizeof(chan_freq_power_t);
+    }
+
+    /* Locate channel and return corresponding frequency */
+    for (i = 0; i < cnt; i++) {
+        if (chan == cf[i].channel)
+            freq = cf[i].freq;
+    }
+
+    LEAVE();
+    return freq;
+}
+
+/** 
+ *  @brief This function setups scan channels
+ *
+ *  @param pmpriv       Pointer to mlan_private structure
+ *  @param band         Band
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_11d_set_universaltable(mlan_private * pmpriv, t_u8 band)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    t_u16 size = sizeof(chan_freq_power_t);
+    t_u16 i = 0;
+
+    ENTER();
+
+    memset(pmadapter->universal_channel, 0,
+           sizeof(pmadapter->universal_channel));
+
+    if (band & (BAND_B | BAND_G | BAND_GN))
+        /* If band B, G or N */
+    {
+        /* Set channel-frequency-power */
+        pmadapter->universal_channel[i].num_cfp =
+            (t_u8) (sizeof(channel_freq_power_UN_BG) / size);
+        PRINTM(MINFO, "11D: BG-band num_cfp=%d\n",
+               pmadapter->universal_channel[i].num_cfp);
+
+        pmadapter->universal_channel[i].pcfp = channel_freq_power_UN_BG;
+        pmadapter->universal_channel[i].valid = MTRUE;
+
+        /* Set region code */
+        pmadapter->universal_channel[i].region = UNIVERSAL_REGION_CODE;
+
+        /* Set band */
+        if (band & BAND_GN)
+            pmadapter->universal_channel[i].band = BAND_G;
+        else
+            pmadapter->universal_channel[i].band =
+                (band & BAND_G) ? BAND_G : BAND_B;
+        i++;
+    }
+
+    if (band & (BAND_A | BAND_AN)) {
+        /* If band A */
+
+        /* Set channel-frequency-power */
+        pmadapter->universal_channel[i].num_cfp =
+            sizeof(channel_freq_power_UN_AJ) / size;
+        PRINTM(MINFO, "11D: AJ-band num_cfp=%d\n",
+               pmadapter->universal_channel[i].num_cfp);
+
+        pmadapter->universal_channel[i].pcfp = channel_freq_power_UN_AJ;
+
+        pmadapter->universal_channel[i].valid = MTRUE;
+
+        /* Set region code */
+        pmadapter->universal_channel[i].region = UNIVERSAL_REGION_CODE;
+
+        /* Set band */
+        pmadapter->universal_channel[i].band = BAND_A;
+        i++;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function gets if 11D is enabled
+ *
+ *  @param pmpriv       Pointer to mlan_private structure
+ *
+ *  @return             ENABLE_11D or DISABLE_11D
+ */
+state_11d_t
+wlan_11d_get_state(mlan_private * pmpriv)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    wlan_802_11d_state_t *state = &pmadapter->state_11d;
+    ENTER();
+    LEAVE();
+    return (state->enable_11d);
+}
+
+/** 
+ *  @brief This function calculates the scan type for channels
+ *
+ *  @param pmadapter            A pointer to mlan_adapter structure
+ *  @param chan                 Chan number
+ *  @param parsed_region_chan   Pointer to parsed_region_chan_11d_t     
+ *
+ *  @return                     PASSIVE if chan is unknown; ACTIVE if chan is known
+ */
+t_u8
+wlan_11d_get_scan_type(pmlan_adapter pmadapter,
+                       t_u8 chan, parsed_region_chan_11d_t * parsed_region_chan)
+{
+    t_u8 scan_type = HostCmd_SCAN_TYPE_PASSIVE;
+
+    ENTER();
+
+    if (wlan_11d_channel_known(pmadapter, chan, parsed_region_chan)) {
+        /* Channel found */
+        PRINTM(MINFO, "11D: Channel found and doing Active Scan\n");
+        scan_type = HostCmd_SCAN_TYPE_ACTIVE;
+    } else
+        PRINTM(MINFO, "11D: Channel not found and doing Passive Scan\n");
+
+    LEAVE();
+    return scan_type;
+}
+
+/** 
+ *  @brief Initialize internal variable for 11D
+ *
+ *  @param pmadapter    Pointer to mlan_adapter structure
+ *
+ *  @return             N/A
+ */
+t_void
+wlan_11d_init(mlan_adapter * pmadapter)
+{
+    wlan_802_11d_state_t *state = &pmadapter->state_11d;
+
+    ENTER();
+
+    /* Start in disabled mode */
+    state->enable_11d = DISABLE_11D;
+    state->user_enable_11d = DISABLE_11D;
+
+    memset(&(pmadapter->parsed_region_chan), 0,
+           sizeof(parsed_region_chan_11d_t));
+    memset(&(pmadapter->universal_channel), 0, sizeof(region_chan_t));
+    memset(&(pmadapter->domain_reg), 0, sizeof(wlan_802_11d_domain_reg_t));
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function enable/disable 11D
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pioctl_buf   A pointer to MLAN IOCTl Request buffer
+ *  @param flag         11D status
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_11d_enable(mlan_private * pmpriv, t_void * pioctl_buf, state_11d_t flag)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    wlan_802_11d_state_t *state = &pmadapter->state_11d;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    state_11d_t enable = flag;
+
+    ENTER();
+
+    memset(&pmadapter->parsed_region_chan, 0, sizeof(parsed_region_chan_11d_t));
+
+    /* Send cmd to FW to enable/disable 11D function */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_SNMP_MIB,
+                           HostCmd_ACT_GEN_SET,
+                           Dot11D_i, (t_void *) pioctl_buf, &enable);
+
+    if (ret) {
+        if (flag)
+            PRINTM(MERROR, "11D: Failed to enable 11D\n");
+        else
+            PRINTM(MERROR, "11D: Failed to disable 11D\n");
+    } else {
+        state->enable_11d = flag;
+        /* Set user enable flag if called from ioctl */
+        if (pioctl_buf)
+            state->user_enable_11d = flag;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function setups scan channels
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param band         band
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+wlan_set_universal_table(mlan_private * pmpriv, t_u8 band)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    t_u16 size = sizeof(chan_freq_power_t);
+    t_u16 i = 0;
+
+    ENTER();
+
+    memset(pmadapter->universal_channel, 0,
+           sizeof(pmadapter->universal_channel));
+
+    if (band & (BAND_B | BAND_G | BAND_GN)) {
+        pmadapter->universal_channel[i].num_cfp =
+            (t_u8) (sizeof(channel_freq_power_UN_BG) / size);
+        PRINTM(MINFO, "11D: BG-band num_cfp=%d\n",
+               pmadapter->universal_channel[i].num_cfp);
+
+        pmadapter->universal_channel[i].pcfp = channel_freq_power_UN_BG;
+        pmadapter->universal_channel[i].valid = MTRUE;
+        pmadapter->universal_channel[i].region = UNIVERSAL_REGION_CODE;
+        if (band & BAND_GN)
+            pmadapter->universal_channel[i].band = BAND_G;
+        else
+            pmadapter->universal_channel[i].band =
+                (band & BAND_G) ? BAND_G : BAND_B;
+        i++;
+    }
+
+    if (band & (BAND_A | BAND_AN)) {
+        pmadapter->universal_channel[i].num_cfp =
+            sizeof(channel_freq_power_UN_AJ) / size;
+        PRINTM(MINFO, "11D: AJ-band num_cfp=%d\n",
+               pmadapter->universal_channel[i].num_cfp);
+        pmadapter->universal_channel[i].pcfp = channel_freq_power_UN_AJ;
+
+        pmadapter->universal_channel[i].valid = MTRUE;
+        pmadapter->universal_channel[i].region = UNIVERSAL_REGION_CODE;
+        pmadapter->universal_channel[i].band = BAND_A;
+        i++;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function implements command CMD_802_11D_DOMAIN_INFO
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pcmd         A pointer to HostCmd_DS_COMMAND structure of 
+ *                        command buffer
+ *  @param cmd_action   Command action 
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_802_11d_domain_info(mlan_private * pmpriv,
+                             HostCmd_DS_COMMAND * pcmd, t_u16 cmd_action)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    HostCmd_DS_802_11D_DOMAIN_INFO *pdomain_info = &pcmd->params.domain_info;
+    MrvlIEtypes_DomainParamSet_t *domain = &pdomain_info->domain;
+    t_u8 no_of_sub_band = pmadapter->domain_reg.no_of_sub_band;
+
+    ENTER();
+
+    PRINTM(MINFO, "11D: no_of_sub_band=0x%x\n", no_of_sub_band);
+
+    pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO);
+    pdomain_info->action = wlan_cpu_to_le16(cmd_action);
+    if (cmd_action == HostCmd_ACT_GEN_GET) {
+        /* Dump domain info */
+        pcmd->size = wlan_cpu_to_le16(sizeof(pdomain_info->action) + S_DS_GEN);
+        HEXDUMP("11D: 802_11D_DOMAIN_INFO", (t_u8 *) pcmd,
+                wlan_le16_to_cpu(pcmd->size));
+        LEAVE();
+        return MLAN_STATUS_SUCCESS;
+    }
+
+    /* Set domain info fields */
+    domain->header.type = wlan_cpu_to_le16(TLV_TYPE_DOMAIN);
+    memcpy(domain->country_code,
+           pmadapter->domain_reg.country_code, sizeof(domain->country_code));
+
+    domain->header.len = ((no_of_sub_band * sizeof(IEEEtypes_SubbandSet_t)) +
+                          sizeof(domain->country_code));
+
+    if (no_of_sub_band) {
+        memcpy(domain->sub_band,
+               pmadapter->domain_reg.sub_band,
+               no_of_sub_band * sizeof(IEEEtypes_SubbandSet_t));
+
+        pcmd->size = wlan_cpu_to_le16(sizeof(pdomain_info->action) +
+                                      domain->header.len +
+                                      sizeof(MrvlIEtypesHeader_t) + S_DS_GEN);
+    } else {
+        pcmd->size = wlan_cpu_to_le16(sizeof(pdomain_info->action) + S_DS_GEN);
+    }
+    domain->header.len = wlan_cpu_to_le16(domain->header.len);
+
+    HEXDUMP("11D: 802_11D_DOMAIN_INFO", (t_u8 *) pcmd,
+            wlan_le16_to_cpu(pcmd->size));
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handle response of CMD_802_11D_DOMAIN_INFO
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         Pointer to command response buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_ret_802_11d_domain_info(mlan_private * pmpriv, HostCmd_DS_COMMAND * resp)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    HostCmd_DS_802_11D_DOMAIN_INFO_RSP *domain_info =
+        &resp->params.domain_info_resp;
+    MrvlIEtypes_DomainParamSet_t *domain = &domain_info->domain;
+    t_u16 action = wlan_le16_to_cpu(domain_info->action);
+    t_u8 no_of_sub_band = 0;
+
+    ENTER();
+
+    /* Dump domain info response data */
+    HEXDUMP("11D: DOMAIN Info Rsp Data", (t_u8 *) resp, resp->size);
+
+    no_of_sub_band =
+        (t_u8) ((wlan_le16_to_cpu(domain->header.len) -
+                 3) / sizeof(IEEEtypes_SubbandSet_t));
+    /* Country code is 3 bytes */
+
+    PRINTM(MINFO, "11D Domain Info Resp: no_of_sub_band=%d\n", no_of_sub_band);
+
+    if (no_of_sub_band > MRVDRV_MAX_SUBBAND_802_11D) {
+        PRINTM(MWARN, "11D: Invalid number of subbands %d returned!!\n",
+               no_of_sub_band);
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    switch (action) {
+    case HostCmd_ACT_GEN_SET:  /* Proc Set Action */
+        break;
+    case HostCmd_ACT_GEN_GET:
+        break;
+    default:
+        PRINTM(MERROR, "11D: Invalid Action:%d\n", domain_info->action);
+        ret = MLAN_STATUS_FAILURE;
+        break;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function generates 11D info from user specified regioncode 
+ *         and download to FW
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param band         Band to create
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_11d_create_dnld_countryinfo(mlan_private * pmpriv, t_u8 band)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    region_chan_t *region_chan;
+    parsed_region_chan_11d_t parsed_region_chan;
+    t_u8 j;
+
+    ENTER();
+
+    PRINTM(MINFO, "11D: Band[%d]\n", band);
+
+    /* Update parsed_region_chan; download domain info to FW */
+
+    /* Find region channel */
+    for (j = 0;
+         j <
+         sizeof(pmadapter->region_channel) /
+         sizeof(pmadapter->region_channel[0]); j++) {
+        region_chan = &pmadapter->region_channel[j];
+
+        PRINTM(MINFO, "11D: [%d] region_chan->Band[%d]\n", j,
+               region_chan->band);
+
+        if (!region_chan || !region_chan->valid || !region_chan->pcfp)
+            continue;
+        switch (region_chan->band) {
+        case BAND_A:
+            switch (band) {
+            case BAND_A:
+            case BAND_AN:
+            case BAND_A | BAND_AN:
+                break;
+            default:
+                continue;
+            }
+            break;
+        case BAND_B:
+        case BAND_G:
+            switch (band) {
+            case BAND_B:
+            case BAND_G:
+            case BAND_G | BAND_B:
+            case BAND_GN:
+            case BAND_G | BAND_GN:
+            case BAND_B | BAND_G | BAND_GN:
+                break;
+            default:
+                continue;
+            }
+            break;
+        default:
+            continue;
+        }
+        break;
+    }
+
+    /* Check if region channel found */
+    if (j >= sizeof(pmadapter->region_channel) /
+        sizeof(pmadapter->region_channel[0])) {
+        PRINTM(MERROR, "11D: region_chan not found. Band[%d]\n", band);
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Generate parsed region channel info from region channel */
+    memset(&parsed_region_chan, 0, sizeof(parsed_region_chan_11d_t));
+    wlan_11d_generate_parsed_region_chan(pmadapter, region_chan,
+                                         &parsed_region_chan);
+
+    /* Generate domain info from parsed region channel info */
+    memset(&pmadapter->domain_reg, 0, sizeof(wlan_802_11d_domain_reg_t));
+    wlan_11d_generate_domain_info(pmadapter, &parsed_region_chan,
+                                  &pmadapter->domain_reg);
+
+    /* Set domain info */
+    ret = wlan_11d_set_domain_info(pmpriv);
+    if (ret) {
+        PRINTM(MERROR, "11D: Error setting domain info in FW\n");
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function parses country info from AP and 
+ *           download country info to FW
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pbss_desc     A pointer to BSS descriptor
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_11d_parse_dnld_countryinfo(mlan_private * pmpriv,
+                                BSSDescriptor_t * pbss_desc)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    parsed_region_chan_11d_t region_chan;
+    parsed_region_chan_11d_t bssdesc_region_chan;
+    t_u32 i, j;
+
+    ENTER();
+
+    /* Only valid if 11D is enabled */
+    if (wlan_11d_get_state(pmpriv) == ENABLE_11D) {
+
+        memset(&pmadapter->domain_reg, 0, sizeof(wlan_802_11d_domain_reg_t));
+        memset(&region_chan, 0, sizeof(parsed_region_chan_11d_t));
+        memset(&bssdesc_region_chan, 0, sizeof(parsed_region_chan_11d_t));
+
+        memcpy(&region_chan,
+               &pmadapter->parsed_region_chan,
+               sizeof(parsed_region_chan_11d_t));
+
+        if (pbss_desc) {
+            /* Parse domain info if available */
+            ret =
+                wlan_11d_parse_domain_info(pmadapter, &pbss_desc->country_info,
+                                           pbss_desc->bss_band,
+                                           &bssdesc_region_chan);
+
+            if (ret == MLAN_STATUS_SUCCESS) {
+                /* Update the channel-power table */
+                for (i = 0; ((i < bssdesc_region_chan.no_of_chan)
+                             && (i < MAX_NO_OF_CHAN)); i++) {
+
+                    for (j = 0; ((j < region_chan.no_of_chan)
+                                 && (j < MAX_NO_OF_CHAN)); j++) {
+                        /* 
+                         * Channel already exists, so overwrite existing 
+                         * tx power with the tx_power received from 
+                         * country info of the current AP
+                         */
+                        if (region_chan.chan_pwr[i].chan ==
+                            bssdesc_region_chan.chan_pwr[j].chan) {
+                            region_chan.chan_pwr[j].pwr =
+                                bssdesc_region_chan.chan_pwr[i].pwr;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        /* Generate domain info */
+        wlan_11d_generate_domain_info(pmadapter, &region_chan,
+                                      &pmadapter->domain_reg);
+
+        /* Set domain info */
+        ret = wlan_11d_set_domain_info(pmpriv);
+        if (ret) {
+            PRINTM(MERROR, "11D: Error setting domain info in FW\n");
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function prepares domain info from scan table and 
+ *         downloads the domain info command to the FW.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_11d_prepare_dnld_domain_info_cmd(mlan_private * pmpriv)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    IEEEtypes_CountryInfoFullSet_t *pcountry_full = MNULL;
+    t_u32 idx;
+
+    ENTER();
+
+    /* Only valid if 11D is enabled */
+    if (wlan_11d_get_state(pmpriv) == ENABLE_11D &&
+        pmadapter->num_in_scan_table != 0) {
+        for (idx = 0; idx < pmadapter->num_in_scan_table; idx++) {
+            pcountry_full = &pmadapter->pscan_table[idx].country_info;
+
+            if (*(pcountry_full->country_code) == 0 ||
+                (pcountry_full->len <= COUNTRY_CODE_LEN)) {
+                /* Country info not found in the BSS descriptor */
+                ret =
+                    wlan_11d_update_chan_pwr_table(pmpriv,
+                                                   &pmadapter->
+                                                   pscan_table[idx]);
+            } else {
+                /* Country info found in the BSS Descriptor */
+                ret =
+                    wlan_11d_process_country_info(pmpriv,
+                                                  &pmadapter->pscan_table[idx]);
+            }
+        }
+
+        /* Check if connected */
+        if (pmpriv->media_connected == MTRUE) {
+            ret =
+                wlan_11d_parse_dnld_countryinfo(pmpriv,
+                                                &pmpriv->curr_bss_params.
+                                                bss_descriptor);
+        } else {
+            ret = wlan_11d_parse_dnld_countryinfo(pmpriv, MNULL);
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
diff --git a/wlan_src/mlan/mlan_11h.c b/wlan_src/mlan/mlan_11h.c
new file mode 100755
index 0000000..8c38b18
--- /dev/null
+++ b/wlan_src/mlan/mlan_11h.c
@@ -0,0 +1,1263 @@
+/** @file mlan_11h.c
+ *
+ *  @brief This file contains functions for 802.11H.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/*************************************************************
+Change Log:
+    03/26/2009: initial version
+************************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_ioctl.h"
+#include "mlan_meas.h"
+#include "mlan_11h.h"
+
+/*
+ * Constants
+ */
+
+/** Default IBSS DFS recovery interval (in TBTTs); used for adhoc start */
+#define WLAN_11H_DEFAULT_DFS_RECOVERY_INTERVAL   100
+
+/** Default 11h power constraint used to offset the maximum transmit power */
+#define WLAN_11H_TPC_POWERCONSTRAINT  0
+
+/** 11h TPC Power capability minimum setting, sent in TPC_INFO command to fw */
+#define WLAN_11H_TPC_POWERCAPABILITY_MIN     5
+
+/** 11h TPC Power capability maximum setting, sent in TPC_INFO command to fw */
+#define WLAN_11H_TPC_POWERCAPABILITY_MAX     20
+
+/** Regulatory requirement for the duration of a channel availability check */
+#define WLAN_11H_CHANNEL_AVAIL_CHECK_DURATION    60000  /* in ms */
+
+/** U-NII sub-band config : Start Channel = 36, NumChans = 4 */
+static const
+    IEEEtypes_SupportChan_Subband_t wlan_11h_unii_lower_band = { 36, 4 };
+
+/** U-NII sub-band config : Start Channel = 52, NumChans = 4 */
+static const
+    IEEEtypes_SupportChan_Subband_t wlan_11h_unii_middle_band = { 52, 4 };
+
+/** U-NII sub-band config : Start Channel = 100, NumChans = 11 */
+static const
+    IEEEtypes_SupportChan_Subband_t wlan_11h_unii_mid_upper_band = { 100, 11 };
+
+/** U-NII sub-band config : Start Channel = 149, NumChans = 4 */
+static const
+    IEEEtypes_SupportChan_Subband_t wlan_11h_unii_upper_band = { 149, 4 };
+
+/*
+ * Local types
+ */
+
+/** Internally passed structure used to send a CMD_802_11_TPC_INFO command */
+typedef struct
+{
+    t_u8 chan;                  /**< Channel to which the power constraint applies */
+    t_u8 power_constraint;      /**< Local power constraint to send to firmware */
+} wlan_11h_tpc_info_param_t;
+
+/**
+ *  @brief Utility function to get a random number based on the underlying OS
+ *
+ *  @return random integer
+ */
+static int
+wlan_11h_get_random_num(t_void)
+{
+    return 112233;
+
+}
+
+/**
+ *  @brief Convert an IEEE formatted IE to 16-bit ID/Len Marvell
+ *         proprietary format
+ *
+ *  @param pout_buf Output parameter: Buffer to output Marvell formatted IE
+ *  @param pin_ie   Pointer to IEEE IE to be converted to Marvell format
+ *
+ *  @return         Number of bytes output to pout_buf parameter return
+ */
+static int
+wlan_11h_convert_ieee_to_mrvl_ie(char *pout_buf, const char *pin_ie)
+{
+    MrvlIEtypesHeader_t mrvl_ie_hdr;
+    char *ptmp_buf = pout_buf;
+
+    ENTER();
+    /* Assign the Element Id and Len to the Marvell struct attributes */
+    mrvl_ie_hdr.type = wlan_cpu_to_le16(pin_ie[0]);
+    mrvl_ie_hdr.len = wlan_cpu_to_le16(pin_ie[1]);
+
+    /* If the element ID is zero, return without doing any copying */
+    if (!mrvl_ie_hdr.type)
+        return 0;
+
+    /* Copy the header to the buffer pointer */
+    memcpy(ptmp_buf, &mrvl_ie_hdr, sizeof(mrvl_ie_hdr));
+
+    /* Increment the temp buffer pointer by the size appended */
+    ptmp_buf += sizeof(mrvl_ie_hdr);
+
+    /* Append the data section of the IE; length given by the IEEE IE length */
+    memcpy(ptmp_buf, pin_ie + 2, pin_ie[1]);
+
+    LEAVE();
+    /* Return the number of bytes appended to pout_buf */
+    return (sizeof(mrvl_ie_hdr) + pin_ie[1]);
+}
+
+/**
+ *  @brief Setup the IBSS DFS element passed to the firmware in adhoc start
+ *         and join commands
+ *
+ *  The DFS Owner and recovery fields are set to be our MAC address and
+ *    a predetermined constant recovery value.  If we are joining an adhoc
+ *    network, these values are replaced with the existing IBSS values.
+ *    They are valid only when starting a new IBSS.
+ *
+ *  The IBSS DFS Element is variable in size based on the number of
+ *    channels supported in our current region.
+ *
+ *  @param priv Private driver information structure
+ *  @param pdfs Output parameter: Pointer to the IBSS DFS element setup by
+ *              this function.
+ *
+ *  @return
+ *    - Length of the returned element in pdfs output parameter
+ *    - 0 if returned element is not setup
+ */
+static int
+wlan_11h_set_ibss_dfs_ie(mlan_private * priv, IEEEtypes_IBSS_DFS_t * pdfs)
+{
+    int num_chans = 0;
+    MeasRptBasicMap_t initial_map;
+    mlan_adapter *adapter = priv->adapter;
+
+    ENTER();
+    PRINTM(MINFO, "11h: IBSS DFS Element, 11D parsed region: %c%c (0x%x)\n",
+           adapter->parsed_region_chan.country_code[0],
+           adapter->parsed_region_chan.country_code[1],
+           adapter->parsed_region_chan.region);
+
+    memset(pdfs, 0x00, sizeof(IEEEtypes_IBSS_DFS_t));
+
+    /* 
+     * A basic measurement report is included with each channel in the
+     *   map field.  Initial value for the map for each supported channel
+     *   is with only the unmeasured bit set.
+     */
+    memset(&initial_map, 0x00, sizeof(initial_map));
+    initial_map.unmeasured = 1;
+
+    /* Set the DFS Owner and recovery interval fields */
+    memcpy(pdfs->dfs_owner, priv->curr_addr, sizeof(pdfs->dfs_owner));
+    pdfs->dfs_recovery_interval = WLAN_11H_DEFAULT_DFS_RECOVERY_INTERVAL;
+
+    for (; (num_chans < adapter->parsed_region_chan.no_of_chan)
+         && (num_chans < WLAN_11H_MAX_IBSS_DFS_CHANNELS); num_chans++) {
+        pdfs->channel_map[num_chans].channel_number =
+            adapter->parsed_region_chan.chan_pwr[num_chans].chan;
+
+        /* 
+         * Set the inital map field with a basic measurement
+         */
+        pdfs->channel_map[num_chans].rpt_map = initial_map;
+    }
+
+    /* 
+     * If we have an established channel map, include it and return
+     *   a valid DFS element
+     */
+    if (num_chans) {
+        PRINTM(MINFO, "11h: Added %d channels to IBSS DFS Map\n", num_chans);
+
+        pdfs->element_id = IBSS_DFS;
+        pdfs->len =
+            (sizeof(pdfs->dfs_owner) + sizeof(pdfs->dfs_recovery_interval)
+             + num_chans * sizeof(IEEEtypes_ChannelMap_t));
+
+        return (pdfs->len + sizeof(pdfs->len) + sizeof(pdfs->element_id));
+    }
+
+    /* Ensure the element is zeroed out for an invalid return */
+    memset(pdfs, 0x00, sizeof(IEEEtypes_IBSS_DFS_t));
+
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Setup the Supported Channel IE sent in association requests
+ *
+ *  The Supported Channels IE is required to be sent when the spectrum
+ *    management capability (11h) is enabled.  The element contains a
+ *    starting channel and number of channels tuple for each sub-band
+ *    the STA supports.  This information is based on the operating region.
+ *
+ *  @param priv      Private driver information structure
+ *  @param psup_chan Output parameter: Pointer to the Supported Chan element
+ *                   setup by this function.
+ *
+ *  @return
+ *    - Length of the returned element in psup_chan output parameter
+ *    - 0 if returned element is not setup
+ */
+static int
+wlan_11h_set_supp_channels_ie(mlan_private * priv,
+                              IEEEtypes_SupportedChannels_t * psup_chan)
+{
+    int num_subbands = 0;
+    int ret_len = 0;
+
+    ENTER();
+    memset(psup_chan, 0x00, sizeof(IEEEtypes_SupportedChannels_t));
+
+    /* 
+     * Set the supported channel elements based on the region code,
+     *   incrementing num_subbands for each sub-band we append to the
+     *   element.
+     */
+    switch (priv->adapter->region_code) {
+    case 0x10:                 /* USA FCC */
+    case 0x20:                 /* Canada IC */
+        psup_chan->subband[num_subbands++] = wlan_11h_unii_lower_band;
+        psup_chan->subband[num_subbands++] = wlan_11h_unii_middle_band;
+        psup_chan->subband[num_subbands++] = wlan_11h_unii_mid_upper_band;
+        psup_chan->subband[num_subbands++] = wlan_11h_unii_upper_band;
+        break;
+    case 0x30:                 /* Europe ETSI */
+        psup_chan->subband[num_subbands++] = wlan_11h_unii_lower_band;
+        psup_chan->subband[num_subbands++] = wlan_11h_unii_middle_band;
+        psup_chan->subband[num_subbands++] = wlan_11h_unii_mid_upper_band;
+        break;
+    default:
+        break;
+    }
+
+    /* 
+     * If we have setup any supported subbands in the element, return a
+     *    valid IE along with its size, else return 0.
+     */
+    if (num_subbands) {
+        psup_chan->element_id = SUPPORTED_CHANNELS;
+        psup_chan->len = num_subbands * sizeof(IEEEtypes_SupportChan_Subband_t);
+
+        ret_len = (psup_chan->len
+                   + sizeof(psup_chan->len) + sizeof(psup_chan->element_id));
+
+        HEXDUMP("11h: SupChan", (t_u8 *) psup_chan, ret_len);
+    }
+
+    LEAVE();
+    return ret_len;
+}
+
+/**
+ *  @brief Prepare CMD_802_11_TPC_ADAPT_REQ firmware command
+ *
+ *  @param priv      Private driver information structure
+ *  @param pcmd_ptr  Output parameter: Pointer to the command being prepared
+ *                   for the firmware
+ *  @param pinfo_buf HostCmd_DS_802_11_TPC_ADAPT_REQ passed as void data block
+ *
+ *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+wlan_11h_cmd_tpc_request(mlan_private * priv,
+                         HostCmd_DS_COMMAND * pcmd_ptr,
+                         const t_void * pinfo_buf)
+{
+    ENTER();
+
+    memcpy(&pcmd_ptr->params.tpc_req, pinfo_buf,
+           sizeof(HostCmd_DS_802_11_TPC_ADAPT_REQ));
+
+    pcmd_ptr->params.tpc_req.req.timeout =
+        wlan_cpu_to_le16(pcmd_ptr->params.tpc_req.req.timeout);
+
+    /* Converted to little endian in wlan_11h_cmd_process */
+    pcmd_ptr->size = sizeof(HostCmd_DS_802_11_TPC_ADAPT_REQ) + S_DS_GEN;
+
+    HEXDUMP("11h: 11_TPC_ADAPT_REQ:", (t_u8 *) pcmd_ptr, (int) pcmd_ptr->size);
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Prepare CMD_802_11_TPC_INFO firmware command
+ *
+ *  @param priv      Private driver information structure
+ *  @param pcmd_ptr  Output parameter: Pointer to the command being prepared 
+ *                   for the firmware
+ *  @param pinfo_buf wlan_11h_tpc_info_param_t passed as void data block
+ *
+ *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+wlan_11h_cmd_tpc_info(mlan_private * priv,
+                      HostCmd_DS_COMMAND * pcmd_ptr, const t_void * pinfo_buf)
+{
+    HostCmd_DS_802_11_TPC_INFO *ptpc_info = &pcmd_ptr->params.tpc_info;
+    MrvlIEtypes_LocalPowerConstraint_t *pconstraint =
+        &ptpc_info->local_constraint;
+    MrvlIEtypes_PowerCapability_t *pcap = &ptpc_info->power_cap;
+
+    wlan_11h_state_t *pstate = &priv->adapter->state_11h;
+    const wlan_11h_tpc_info_param_t *ptpc_info_param =
+        (wlan_11h_tpc_info_param_t *) pinfo_buf;
+
+    ENTER();
+
+    pcap->min_power = pstate->min_tx_power_capability;
+    pcap->max_power = pstate->max_tx_power_capability;
+    pcap->header.len = wlan_cpu_to_le16(2);
+    pcap->header.type = wlan_cpu_to_le16(TLV_TYPE_POWER_CAPABILITY);
+
+    pconstraint->chan = ptpc_info_param->chan;
+    pconstraint->constraint = ptpc_info_param->power_constraint;
+    pconstraint->header.type = wlan_cpu_to_le16(TLV_TYPE_POWER_CONSTRAINT);
+    pconstraint->header.len = wlan_cpu_to_le16(2);
+
+    /* Converted to little endian in wlan_11h_cmd_process */
+    pcmd_ptr->size = sizeof(HostCmd_DS_802_11_TPC_INFO) + S_DS_GEN;
+
+    HEXDUMP("11h: TPC INFO", (t_u8 *) pcmd_ptr, (int) pcmd_ptr->size);
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief  Prepare CMD_802_11_CHAN_SW_ANN firmware command
+ *
+ *  @param priv      Private driver information structure
+ *  @param pcmd_ptr  Output parameter: Pointer to the command being 
+ *                   prepared to for firmware
+ *  @param pinfo_buf HostCmd_DS_802_11_CHAN_SW_ANN passed as void data block
+ *
+ *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+wlan_11h_cmd_chan_sw_ann(mlan_private * priv,
+                         HostCmd_DS_COMMAND * pcmd_ptr,
+                         const t_void * pinfo_buf)
+{
+    const HostCmd_DS_802_11_CHAN_SW_ANN *pch_sw_ann =
+        (HostCmd_DS_802_11_CHAN_SW_ANN *) pinfo_buf;
+
+    ENTER();
+
+    /* Converted to little endian in wlan_11h_cmd_process */
+    pcmd_ptr->size = sizeof(HostCmd_DS_802_11_CHAN_SW_ANN) + S_DS_GEN;
+
+    memcpy(&pcmd_ptr->params.chan_sw_ann, pch_sw_ann,
+           sizeof(HostCmd_DS_802_11_CHAN_SW_ANN));
+
+    PRINTM(MINFO, "11h: ChSwAnn: %#x-%u, Seq=%u, Ret=%u\n",
+           pcmd_ptr->command, pcmd_ptr->size, pcmd_ptr->seq_num,
+           pcmd_ptr->result);
+    PRINTM(MINFO, "11h: ChSwAnn: Ch=%d, Cnt=%d, Mode=%d\n",
+           pch_sw_ann->new_chan, pch_sw_ann->switch_count,
+           pch_sw_ann->switch_mode);
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Set the local power constraint in the firmware
+ *
+ *  Construct and send a CMD_802_11_TPC_INFO command with the local power
+ *    constraint.
+ *
+ *  @param priv             Private driver information structure
+ *  @param channel          Channel to which the power constraint applies
+ *  @param power_constraint Power constraint to be applied on the channel
+ *
+ *  @return                 MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+wlan_11h_set_local_power_constraint(mlan_private * priv,
+                                    t_u8 channel, t_u8 power_constraint)
+{
+    int ret = MLAN_STATUS_SUCCESS;
+    wlan_11h_tpc_info_param_t tpc_info_param;
+
+    ENTER();
+    tpc_info_param.chan = channel;
+    tpc_info_param.power_constraint = power_constraint;
+
+    PRINTM(MINFO, "11h: Set Local Constraint = %d\n",
+           tpc_info_param.power_constraint);
+
+    ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_TPC_INFO,
+                           HostCmd_ACT_GEN_SET, 0, 0, &tpc_info_param);
+
+    if (ret) {
+        PRINTM(MINFO, "11h: Err: Send TPC_INFO CMD: %d\n", ret);
+        ret = MLAN_STATUS_FAILURE;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief  Utility function to process a join to an infrastructure BSS
+ *
+ *  @param priv          Private driver information structure
+ *  @param ppbuffer      Output parameter: Pointer to the TLV output buffer,
+ *                       modified on return to point after the appended 11h TLVs
+ *  @param channel       Channel on which we are joining the BSS
+ *  @param p11h_bss_info Pointer to the 11h BSS information for this network
+ *                       that was parsed out of the scan response.
+ *
+ *  @return              Integer number of bytes appended to the TLV output
+ *                       buffer (ppbuffer)
+ */
+static int
+wlan_11h_process_infra_join(mlan_private * priv,
+                            t_u8 ** ppbuffer,
+                            t_u32 channel, wlan_11h_bss_info_t * p11h_bss_info)
+{
+    MrvlIEtypesHeader_t ie_header;
+    IEEEtypes_SupportedChannels_t sup_chan_ie;
+    int ret_len = 0;
+    int sup_chan_len = 0;
+
+    ENTER();
+
+    /* Null Checks */
+    if (!ppbuffer)
+        return 0;
+    if (!(*ppbuffer))
+        return 0;
+
+    /* Set the local constraint configured in the firmware */
+    wlan_11h_set_local_power_constraint(priv, channel,
+                                        (p11h_bss_info->
+                                         power_constraint.local_constraint));
+
+    /* Setup the Supported Channels IE */
+    sup_chan_len = wlan_11h_set_supp_channels_ie(priv, &sup_chan_ie);
+
+    /* 
+     * If we returned a valid Supported Channels IE, wrap and append it
+     */
+    if (sup_chan_len) {
+        /* Wrap the supported channels IE with a passthrough TLV type */
+        ie_header.type = wlan_cpu_to_le16(TLV_TYPE_PASSTHROUGH);
+        ie_header.len = sup_chan_len;
+        memcpy(*ppbuffer, &ie_header, sizeof(ie_header));
+
+        /* Increment the return size and the return buffer pointer param */
+        *ppbuffer += sizeof(ie_header);
+        ret_len += sizeof(ie_header);
+
+        /* Copy the supported channels IE to the output buf, advance pointer */
+        memcpy(*ppbuffer, &sup_chan_ie, sup_chan_len);
+        *ppbuffer += sup_chan_len;
+        ret_len += sup_chan_len;
+    }
+
+    LEAVE();
+    return ret_len;
+}
+
+/**
+ *  @brief Utility function to process a start or join to an adhoc network
+ *
+ *  Add the elements to the TLV buffer needed in the start/join adhoc commands:
+ *       - IBSS DFS IE
+ *       - Quiet IE
+ *
+ *  Also send the local constraint to the firmware in a TPC_INFO command.
+ *
+ *  @param priv          Private driver information structure
+ *  @param ppbuffer      Output parameter: Pointer to the TLV output buffer,
+ *                       modified on return to point after the appended 11h TLVs
+ *  @param channel       Channel on which we are starting/joining the IBSS
+ *  @param p11h_bss_info Pointer to the 11h BSS information for this network
+ *                       that was parsed out of the scan response.  NULL
+ *                       indicates we are starting the adhoc network
+ *
+ *  @return              Integer number of bytes appended to the TLV output
+ *                       buffer (ppbuffer)
+ */
+static int
+wlan_11h_process_adhoc(mlan_private * priv,
+                       t_u8 ** ppbuffer,
+                       t_u32 channel, wlan_11h_bss_info_t * p11h_bss_info)
+{
+    IEEEtypes_IBSS_DFS_t dfs_elem;
+    int size_appended;
+    int ret_len = 0;
+    t_s8 local_constraint = 0;
+    mlan_adapter *adapter = priv->adapter;
+
+    ENTER();
+
+    /* Format our own IBSS DFS Element.  Include our channel map fields */
+    wlan_11h_set_ibss_dfs_ie(priv, &dfs_elem);
+
+    if (p11h_bss_info) {
+        /* 
+         * Copy the DFS Owner/Recovery Interval from the BSS we are joining
+         */
+        memcpy(dfs_elem.dfs_owner,
+               p11h_bss_info->ibss_dfs.dfs_owner, sizeof(dfs_elem.dfs_owner));
+        dfs_elem.dfs_recovery_interval =
+            p11h_bss_info->ibss_dfs.dfs_recovery_interval;
+    }
+
+    /* Append the dfs element to the TLV buffer */
+    size_appended = wlan_11h_convert_ieee_to_mrvl_ie((char *) *ppbuffer,
+                                                     (char *) &dfs_elem);
+
+    HEXDUMP("11h: IBSS-DFS", (t_u8 *) * ppbuffer, size_appended);
+    *ppbuffer += size_appended;
+    ret_len += size_appended;
+
+    /* 
+     * Check to see if we are joining a network.  Join is indicated by the
+     *   BSS Info pointer being valid (not NULL)
+     */
+    if (p11h_bss_info) {
+        /* 
+         * If there was a quiet element, include it in adhoc join command
+         */
+        if (p11h_bss_info->quiet.element_id == QUIET) {
+            size_appended
+                = wlan_11h_convert_ieee_to_mrvl_ie((char *) *ppbuffer,
+                                                   (char *) &p11h_bss_info->
+                                                   quiet);
+            HEXDUMP("11h: Quiet", (t_u8 *) * ppbuffer, size_appended);
+            *ppbuffer += size_appended;
+            ret_len += size_appended;
+        }
+
+        /* Copy the local constraint from the network */
+        local_constraint = p11h_bss_info->power_constraint.local_constraint;
+    } else {
+        /* 
+         * If we are the adhoc starter, we can add a quiet element
+         */
+        if (adapter->state_11h.quiet_ie.quiet_period) {
+            size_appended = wlan_11h_convert_ieee_to_mrvl_ie((char *) *ppbuffer,
+                                                             (char *) &adapter->
+                                                             state_11h.
+                                                             quiet_ie);
+            HEXDUMP("11h: Quiet", (t_u8 *) * ppbuffer, size_appended);
+            *ppbuffer += size_appended;
+            ret_len += size_appended;
+
+            /* Use the local_constraint configured in the driver state */
+            local_constraint = adapter->state_11h.usr_def_power_constraint;
+        }
+    }
+
+    /* Set the local constraint configured in the firmware */
+    wlan_11h_set_local_power_constraint(priv, channel, local_constraint);
+
+    LEAVE();
+    return ret_len;
+}
+
+/**
+ *  @brief Return whether the driver is currently setup to use 11h for
+ *         adhoc start.
+ *
+ *  Association/Join commands are dynamic in that they enable 11h in the
+ *    driver/firmware when they are detected in the existing BSS.
+ *
+ *  @param priv  Private driver information structure
+ *
+ *  @return
+ *    - MTRUE if 11h is enabled
+ *    - MFALSE otherwise
+ */
+static int
+wlan_11h_is_enabled(mlan_private * priv)
+{
+    wlan_11h_state_t *pstate_11h = &priv->adapter->state_11h;
+
+    return (pstate_11h->is_11h_enabled ? MTRUE : MFALSE);
+}
+
+/**
+ *  @brief Query 11h firmware enabled state.
+ *
+ *  Return whether the firmware currently has 11h extensions enabled
+ *
+ *  @param priv  Private driver information structure
+ *
+ *  @return
+ *    - MTRUE if 11h has been activated in the firmware
+ *    - MFALSE otherwise
+ *
+ *  @sa wlan_11h_activate
+ */
+int
+wlan_11h_is_active(mlan_private * priv)
+{
+    wlan_11h_state_t *pstate_11h = &priv->adapter->state_11h;
+
+    return (pstate_11h->is_11h_active ? MTRUE : MFALSE);
+}
+
+/**
+ *  @brief Disable the transmit interface and record the state.
+ *
+ *  @param priv  Private driver information structure
+ *
+ *  @return      t_void
+ */
+t_void
+wlan_11h_tx_disable(mlan_private * priv)
+{
+    wlan_11h_state_t *pstate_11h = &priv->adapter->state_11h;
+
+    ENTER();
+    pstate_11h->tx_disabled = MTRUE;
+    LEAVE();
+}
+
+/**
+ *  @brief Enable the transmit interface and record the state.
+ *
+ *  @param priv  Private driver information structure
+ *
+ *  @return      t_void
+ */
+t_void
+wlan_11h_tx_enable(mlan_private * priv)
+{
+    wlan_11h_state_t *pstate_11h = &priv->adapter->state_11h;
+
+    ENTER();
+    pstate_11h->tx_disabled = MFALSE;
+    LEAVE();
+}
+
+/**
+ *  @brief Enable or Disable the 11h extensions in the firmware
+ *
+ *  @param priv  Private driver information structure
+ *  @param flag  Enable 11h if MTRUE, disable otherwise
+ *
+ *  @return      MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+wlan_11h_activate(mlan_private * priv, t_u32 flag)
+{
+    wlan_11h_state_t *pstate_11h = &priv->adapter->state_11h;
+    int enable = flag ? 1 : 0;
+    int ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* 
+     * Send cmd to FW to enable/disable 11h function in firmware
+     */
+    ret = wlan_prepare_cmd(priv,
+                           HostCmd_CMD_802_11_SNMP_MIB,
+                           HostCmd_ACT_GEN_SET, Dot11H_i, MNULL, &enable);
+
+    if (ret)
+        ret = MLAN_STATUS_FAILURE;
+    else
+        /* Set boolean flag in driver 11h state */
+        pstate_11h->is_11h_active = flag;
+
+    PRINTM(MINFO, "11h: %s\n", enable ? "Activate" : "Deactivate");
+
+    LEAVE();
+
+    return ret;
+}
+
+/**
+ *
+ *  @brief Initialize the 11h parameters and enable 11h when starting an IBSS
+ *
+ *  @param adapter mlan_adapter structure
+ *
+ *  @return      t_void
+ */
+t_void
+wlan_11h_init(mlan_adapter * adapter)
+{
+    wlan_11h_state_t *pstate_11h = &adapter->state_11h;
+    IEEEtypes_Quiet_t *pquiet = &adapter->state_11h.quiet_ie;
+
+    ENTER();
+
+    pstate_11h->usr_def_power_constraint = WLAN_11H_TPC_POWERCONSTRAINT;
+    pstate_11h->min_tx_power_capability = WLAN_11H_TPC_POWERCAPABILITY_MIN;
+    pstate_11h->max_tx_power_capability = WLAN_11H_TPC_POWERCAPABILITY_MAX;
+
+    /* 
+     * By default, the driver should have its preference set as 11h being
+     *    activated when starting an ad hoc network.  For infrastructure
+     *    and ad hoc join, 11h will be sensed and activated accordingly.
+     */
+    pstate_11h->is_11h_enabled = MTRUE;
+
+    /* 
+     * On power up, the firmware should have 11h support inactive.
+     */
+    pstate_11h->is_11h_active = MFALSE;
+
+    /* Initialize quiet_ie */
+    memset(pquiet, 0, sizeof(IEEEtypes_Quiet_t));
+
+    pquiet->element_id = QUIET;
+    pquiet->len = (sizeof(pquiet->quiet_count) + sizeof(pquiet->quiet_period)
+                   + sizeof(pquiet->quiet_duration)
+                   + sizeof(pquiet->quiet_offset));
+    LEAVE();
+}
+
+/**
+ *  @brief Retrieve a randomly selected starting channel if needed for 11h
+ *
+ *  If 11h is enabled and an A-Band channel start band preference
+ *    configured in the driver, the start channel must be random in order
+ *    to meet with
+ *
+ *  @param priv  Private driver information structure
+ *
+ *  @return      Integer starting channel
+ */
+int
+wlan_11h_get_adhoc_start_channel(mlan_private * priv)
+{
+    unsigned int start_chn;
+    mlan_adapter *adapter = priv->adapter;
+    int region;
+    int rand_entry;
+    region_chan_t *chn_tbl;
+
+    ENTER();
+
+    /* 
+     * Set start_chn to the Default.  Used if 11h is disabled or the band
+     *   does not require 11h support.
+     */
+    start_chn = DEFAULT_AD_HOC_CHANNEL;
+
+    /* 
+     * Check that we are looking for a channel in the A Band
+     */
+    if ((adapter->adhoc_start_band & BAND_A)
+        || (adapter->adhoc_start_band & BAND_AN)
+        ) {
+        /* 
+         * Set default to the A Band default. Used if random selection fails
+         *   or if 11h is not enabled
+         */
+        start_chn = DEFAULT_AD_HOC_CHANNEL_A;
+
+        /* 
+         * Check that 11h is enabled in the driver
+         */
+        if (wlan_11h_is_enabled(priv)) {
+            /* 
+             * Search the region_channel tables for a channel table
+             *   that is marked for the A Band.
+             */
+            for (region = 0; (region < MAX_REGION_CHANNEL_NUM); region++) {
+                chn_tbl = &adapter->region_channel[region];
+
+                /* Check if table is valid and marked for A Band */
+                if (chn_tbl->valid
+                    && chn_tbl->region == adapter->region_code
+                    && chn_tbl->band & BAND_A) {
+                    /* 
+                     * Set the start channel.  Get a random number and
+                     *   use it to pick an entry in the table between 0
+                     *   and the number of channels in the table (NumCFP).
+                     */
+                    rand_entry = wlan_11h_get_random_num() % chn_tbl->num_cfp;
+                    start_chn = chn_tbl->pcfp[rand_entry].channel;
+                }
+            }
+        }
+    }
+
+    PRINTM(MINFO, "11h: %s: AdHoc Channel set to %u\n",
+           wlan_11h_is_enabled(priv) ? "Enabled" : "Disabled", start_chn);
+
+    LEAVE();
+
+    return start_chn;
+}
+
+/**
+ *  @brief Check if the current region's regulations require the input channel
+ *         to be scanned for radar.
+ *
+ *  Based on statically defined requirements for sub-bands per regulatory
+ *    agency requirements.
+ *
+ *  Used in adhoc start to determine if channel availability check is required
+ *
+ *  @param priv    Private driver information structure
+ *  @param channel Channel to determine radar detection requirements
+ *
+ *  @return
+ *    - MTRUE if radar detection is required
+ *    - MFALSE otherwise
+ *
+ *  @sa wlan_11h_radar_detected
+ */
+int
+wlan_11h_radar_detect_required(mlan_private * priv, t_u8 channel)
+{
+    int required;
+
+    ENTER();
+
+    /* 
+     * Assume that radar detection is required unless exempted below.
+     *   No checks for 11h or measurement code  being enabled is placed here
+     *   since regulatory requirements exist whether we support them or not.
+     */
+    required = MTRUE;
+
+    switch (priv->adapter->region_code) {
+    case 0x10:                 /* USA FCC */
+    case 0x20:                 /* Canada IC */
+        /* 
+         * FCC does not yet require radar detection in the
+         *   5.25-5.35 (U-NII middle) band
+         */
+        if (channel < wlan_11h_unii_middle_band.start_chan ||
+            channel >= wlan_11h_unii_mid_upper_band.start_chan) {
+            required = MFALSE;
+        }
+        break;
+    case 0x30:                 /* Europe ETSI */
+        /* 
+         * Radar detection is not required in the
+         *   5.15-5.25 (U-NII lower) and 5.725-5.825 (U-NII upper) bands
+         */
+        if (channel < wlan_11h_unii_middle_band.start_chan ||
+            channel >= wlan_11h_unii_upper_band.start_chan) {
+            /* Radar detection not required */
+            required = MFALSE;
+        }
+        break;
+    default:
+        break;
+    }
+
+    PRINTM(MINFO, "11h: Radar detection in region %#02x "
+           "is %srequired for channel %d\n",
+           priv->adapter->region_code, (required ? "" : "NOT "), channel);
+
+    if (required == MTRUE && priv->media_connected == MTRUE
+        && priv->curr_bss_params.bss_descriptor.channel == channel) {
+        required = MFALSE;
+
+        PRINTM(MINFO, "11h: Radar detection not required. "
+               "Already operating on the channel");
+    }
+
+    LEAVE();
+    return required;
+}
+
+/**
+ *  @brief Perform a radar measurement and report the result if required on
+ *         given channel
+ *
+ *  Check to see if the provided channel requires a channel availability
+ *    check (60 second radar detection measurement).  If required, perform
+ *    measurement, stalling calling thread until the measurement completes
+ *    and then report result.
+ *
+ *  Used when starting an adhoc network.
+ *
+ *  @param priv    Private driver information structure
+ *  @param channel Channel on which to perform radar measurement
+ *
+ *  @return
+ *    - MTRUE if radar has been detected
+ *    - MFALSE if radar detection is not required or radar has not been detected
+ *
+ *  @sa wlan_11h_radar_detect_required
+ */
+int
+wlan_11h_radar_detected(mlan_private * priv, t_u8 channel)
+{
+    int ret;
+    HostCmd_DS_MEASUREMENT_REQUEST meas_req;
+    HostCmd_DS_MEASUREMENT_REPORT meas_rpt;
+
+    ENTER();
+
+    /* 
+     * If the channel requires radar, default the return value to it being
+     *   detected.
+     */
+    ret = wlan_11h_radar_detect_required(priv, channel);
+
+    memset(&meas_req, 0x00, sizeof(meas_req));
+    memset(&meas_rpt, 0x00, sizeof(meas_rpt));
+
+    /* 
+     * Send a basic measurement request on the indicated channel for the
+     *   required channel availability check time.
+     */
+    meas_req.meas_type = WLAN_MEAS_BASIC;
+    meas_req.req.basic.channel = channel;
+    meas_req.req.basic.duration = WLAN_11H_CHANNEL_AVAIL_CHECK_DURATION;
+
+    /* 
+     * Set the STA that we are requesting the measurement from to our own
+     *   mac address, causing our firmware to perform the measurement itself
+     */
+    memcpy(meas_req.mac_addr, priv->curr_addr, sizeof(meas_req.mac_addr));
+
+    /* 
+     * Send the measurement request and timeout duration to wait for
+     *   the command to spend until the measurement report is received
+     *   from the firmware.  If the command fails, the default ret value set
+     *   above will be returned.
+     */
+    if (!wlan_meas_util_send_req(priv, &meas_req,
+                                 meas_req.req.basic.duration, &meas_rpt)) {
+        /* 
+         * If the report indicates no measurement was done, leave the default
+         *   return value alone.
+         */
+        if (!meas_rpt.rpt.basic.map.unmeasured)
+            /* 
+             * Set the return value based on the radar indication bit
+             */
+            ret = meas_rpt.rpt.basic.map.radar ? MTRUE : MFALSE;
+
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Process an TLV buffer for a pending BSS Adhoc start command.
+ *
+ *  Activate 11h functionality in the firmware if driver has is enabled
+ *    for 11h (configured by the application via IOCTL).
+ *
+ *  @param priv          Private driver information structure
+ *  @param ppbuffer      Output parameter: Pointer to the TLV output buffer, 
+ *                       modified on return to point after the appended 11h TLVs
+ *  @param pcap_info     Pointer to the capability info for the BSS to join
+ *  @param channel       Channel on which we are starting the IBSS
+ *  @param p11h_bss_info Input/Output parameter: Pointer to the 11h BSS 
+ *                       information for this network that we are establishing.
+ *                       11h sensed flag set on output if warranted.
+ *
+ *  @return              Integer number of bytes appended to the TLV output
+ *                       buffer (ppbuffer)
+ *
+ */
+int
+wlan_11h_process_start(mlan_private * priv,
+                       t_u8 ** ppbuffer,
+                       IEEEtypes_CapInfo_t * pcap_info,
+                       t_u32 channel, wlan_11h_bss_info_t * p11h_bss_info)
+{
+    mlan_adapter *adapter = priv->adapter;
+    int ret = 0;
+
+    ENTER();
+    if (wlan_11h_is_enabled(priv)
+        && ((adapter->adhoc_start_band & BAND_A)
+            || (adapter->adhoc_start_band & BAND_AN)
+        )
+        ) {
+        if (wlan_11d_get_state(priv) == DISABLE_11D) {
+            /* No use having 11h enabled without 11d enabled */
+            wlan_11d_enable(priv, MNULL, ENABLE_11D);
+            wlan_11d_create_dnld_countryinfo(priv, adapter->adhoc_start_band);
+        }
+
+        /* Activate 11h functions in firmware, turns on capability bit */
+        wlan_11h_activate(priv, MTRUE);
+        pcap_info->spectrum_mgmt = 1;
+
+        /* Set flag indicating this BSS we are starting is using 11h */
+        p11h_bss_info->sensed_11h = MTRUE;
+
+        ret = wlan_11h_process_adhoc(priv, ppbuffer, channel, MNULL);
+    } else {
+        /* Deactivate 11h functions in the firmware */
+        wlan_11h_activate(priv, MFALSE);
+        pcap_info->spectrum_mgmt = 0;
+    }
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Process an TLV buffer for a pending BSS Join command for
+ *         both adhoc and infra networks
+ *
+ *  The TLV command processing for a BSS join for either adhoc or
+ *    infrastructure network is performed with this function.  The
+ *    capability bits are inspected for the IBSS flag and the appropriate
+ *    local routines are called to setup the necessary TLVs.
+ *
+ *  Activate 11h functionality in the firmware if the spectrum management
+ *    capability bit is found in the network information for the BSS we are
+ *    joining.
+ *
+ *  @param priv          Private driver information structure
+ *  @param ppbuffer      Output parameter: Pointer to the TLV output buffer, 
+ *                       modified on return to point after the appended 11h TLVs
+ *  @param pcap_info     Pointer to the capability info for the BSS to join
+ *  @param channel       Channel on which we are joining the BSS
+ *  @param p11h_bss_info Pointer to the 11h BSS information for this
+ *                       network that was parsed out of the scan response.
+ *
+ *  @return              Integer number of bytes appended to the TLV output
+ *                       buffer (ppbuffer), MLAN_STATUS_FAILURE (-1), 
+ *                       or MLAN_STATUS_SUCCESS (0)
+ */
+int
+wlan_11h_process_join(mlan_private * priv,
+                      t_u8 ** ppbuffer,
+                      IEEEtypes_CapInfo_t * pcap_info,
+                      t_u32 channel, wlan_11h_bss_info_t * p11h_bss_info)
+{
+    int ret = 0;
+
+    ENTER();
+
+    if (priv->media_connected == MTRUE) {
+        if (wlan_11h_is_active(priv) == p11h_bss_info->sensed_11h) {
+            /* Assume DFS parameters are the same for roaming as long as the
+               current & next APs have the same spectrum mgmt capability bit
+               setting */
+            ret = MLAN_STATUS_SUCCESS;
+
+        } else {
+            /* No support for roaming between DFS/non-DFS yet */
+            ret = MLAN_STATUS_FAILURE;
+        }
+
+        LEAVE();
+        return ret;
+    }
+
+    if (p11h_bss_info->sensed_11h) {
+        /* No use having 11h enabled without 11d enabled */
+        wlan_11d_enable(priv, MNULL, ENABLE_11D);
+        wlan_11d_parse_dnld_countryinfo(priv, priv->pattempted_bss_desc);
+
+        /* Activate 11h functions in firmware, turns on capability bit */
+        wlan_11h_activate(priv, MTRUE);
+        pcap_info->spectrum_mgmt = 1;
+
+        if (pcap_info->ibss) {
+            PRINTM(MINFO, "11h: Adhoc join: Sensed\n");
+            ret = wlan_11h_process_adhoc(priv, ppbuffer, channel,
+                                         p11h_bss_info);
+        } else {
+            PRINTM(MINFO, "11h: Infra join: Sensed\n");
+            ret = wlan_11h_process_infra_join(priv, ppbuffer,
+                                              channel, p11h_bss_info);
+        }
+    } else {
+        /* Deactivate 11h functions in the firmware */
+        wlan_11h_activate(priv, MFALSE);
+        pcap_info->spectrum_mgmt = 0;
+    }
+
+    LEAVE();
+
+    return ret;
+}
+
+/**
+ *
+ *  @brief  Prepare the HostCmd_DS_Command structure for an 11h command.
+ *
+ *  Use the Command field to determine if the command being set up is for
+ *     11h and call one of the local command handlers accordingly for:
+ *
+ *        - HostCmd_CMD_802_11_TPC_ADAPT_REQ
+ *        - HostCmd_CMD_802_11_TPC_INFO
+ *        - HostCmd_CMD_802_11_CHAN_SW_ANN
+ *
+ *  @param priv      Private driver information structure
+ *  @param pcmd_ptr  Output parameter: Pointer to the command being prepared 
+ *                   for the firmware
+ *  @param pinfo_buf Void buffer pass through with data necessary for a
+ *                   specific command type
+ *
+ *  @return          MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ *
+ *  @sa wlan_11h_cmd_tpc_request
+ *  @sa wlan_11h_cmd_tpc_info
+ *  @sa wlan_11h_cmd_chan_sw_ann
+ */
+int
+wlan_11h_cmd_process(mlan_private * priv,
+                     HostCmd_DS_COMMAND * pcmd_ptr, const t_void * pinfo_buf)
+{
+    int ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+    switch (pcmd_ptr->command) {
+    case HostCmd_CMD_802_11_TPC_ADAPT_REQ:
+        ret = wlan_11h_cmd_tpc_request(priv, pcmd_ptr, pinfo_buf);
+        break;
+    case HostCmd_CMD_802_11_TPC_INFO:
+        ret = wlan_11h_cmd_tpc_info(priv, pcmd_ptr, pinfo_buf);
+        break;
+    case HostCmd_CMD_802_11_CHAN_SW_ANN:
+        ret = wlan_11h_cmd_chan_sw_ann(priv, pcmd_ptr, pinfo_buf);
+        break;
+    default:
+        ret = MLAN_STATUS_FAILURE;
+    }
+
+    pcmd_ptr->command = wlan_cpu_to_le16(pcmd_ptr->command);
+    pcmd_ptr->size = wlan_cpu_to_le16(pcmd_ptr->size);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Handle the command response from the firmware if from an 11h command
+ *
+ *  Use the Command field to determine if the command response being
+ *    is for 11h.  Call the local command response handler accordingly for:
+ *
+ *        - HostCmd_CMD_802_11_TPC_ADAPT_REQ
+ *        - HostCmd_CMD_802_11_TPC_INFO
+ *        - HostCmd_CMD_802_11_CHAN_SW_ANN
+ *
+ *  @param priv  Private driver information structure
+ *  @param resp  HostCmd_DS_COMMAND struct returned from the firmware
+ *               command
+ *
+ *  @return      MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+wlan_11h_cmdresp_process(mlan_private * priv, const HostCmd_DS_COMMAND * resp)
+{
+    int ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+    switch (resp->command) {
+    case HostCmd_CMD_802_11_TPC_ADAPT_REQ:
+        HEXDUMP("11h: TPC REQUEST Rsp:", (t_u8 *) resp, (int) resp->size);
+        memcpy(priv->adapter->curr_cmd->pdata_buf,
+               &resp->params.tpc_req, sizeof(HostCmd_DS_802_11_TPC_ADAPT_REQ));
+        break;
+
+    case HostCmd_CMD_802_11_TPC_INFO:
+        HEXDUMP("11h: TPC INFO Rsp Data:", (t_u8 *) resp, (int) resp->size);
+        break;
+
+    case HostCmd_CMD_802_11_CHAN_SW_ANN:
+        PRINTM(MINFO, "11h: Ret ChSwAnn: Sz=%u, Seq=%u, Ret=%u\n",
+               resp->size, resp->seq_num, resp->result);
+        break;
+
+    default:
+        ret = MLAN_STATUS_FAILURE;
+    }
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Process an element from a scan response, copy relevant info for 11h
+ *
+ *  @param p11h_bss_info Output parameter: Pointer to the 11h BSS information
+ *                       for the network that is being processed
+ *  @param pelement      Pointer to the current IE we are inspecting for 11h
+ *                       relevance
+ *
+ *  @return              MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+wlan_11h_process_bss_elem(wlan_11h_bss_info_t * p11h_bss_info,
+                          const t_u8 * pelement)
+{
+    int ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+    switch (*pelement) {
+    case POWER_CONSTRAINT:
+        PRINTM(MINFO, "11h: Power Constraint IE Found\n");
+        p11h_bss_info->sensed_11h = 1;
+        memcpy(&p11h_bss_info->power_constraint, pelement,
+               sizeof(IEEEtypes_PowerConstraint_t));
+        break;
+
+    case POWER_CAPABILITY:
+        PRINTM(MINFO, "11h: Power Capability IE Found\n");
+        p11h_bss_info->sensed_11h = 1;
+        memcpy(&p11h_bss_info->power_capability, pelement,
+               sizeof(IEEEtypes_PowerCapability_t));
+        break;
+
+    case TPC_REPORT:
+        PRINTM(MINFO, "11h: Tpc Report IE Found\n");
+        p11h_bss_info->sensed_11h = 1;
+        memcpy(&p11h_bss_info->tpc_report, pelement,
+               sizeof(IEEEtypes_TPCReport_t));
+        break;
+
+    case CHANNEL_SWITCH_ANN:
+        p11h_bss_info->sensed_11h = 1;
+        PRINTM(MINFO, "11h: Channel Switch Ann IE Found\n");
+        break;
+
+    case QUIET:
+        PRINTM(MINFO, "11h: Quiet IE Found\n");
+        p11h_bss_info->sensed_11h = 1;
+        memcpy(&p11h_bss_info->quiet, pelement, sizeof(IEEEtypes_Quiet_t));
+        break;
+
+    case IBSS_DFS:
+        PRINTM(MINFO, "11h: Ibss Dfs IE Found\n");
+        p11h_bss_info->sensed_11h = 1;
+        memcpy(&p11h_bss_info->ibss_dfs, pelement,
+               sizeof(IEEEtypes_IBSS_DFS_t));
+        break;
+
+    case SUPPORTED_CHANNELS:
+    case TPC_REQUEST:
+        /* 
+         * These elements are not in beacons/probe responses.  Included here
+         *   to cover set of enumerated 11h elements.
+         */
+        break;
+
+    default:
+        ret = MLAN_STATUS_FAILURE;
+    }
+    LEAVE();
+    return ret;
+}
diff --git a/wlan_src/mlan/mlan_11h.h b/wlan_src/mlan/mlan_11h.h
new file mode 100755
index 0000000..71550a9
--- /dev/null
+++ b/wlan_src/mlan/mlan_11h.h
@@ -0,0 +1,73 @@
+/** @file mlan_11h.h
+ *
+ *  @brief This header file contains data structures and 
+ *  function declarations of 802.11h
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/*************************************************************
+Change Log:
+    03/26/2009: initial creation
+*************************************************************/
+
+#ifndef _MLAN_11H_
+#define _MLAN_11H_
+
+/**
+ *  11H APIs
+ */
+
+/** Initialize the 11h software module */
+extern void wlan_11h_init(mlan_adapter * pmadapter);
+
+/** Return 1 if 11h is active in the firmware, 0 if it is inactive */
+extern int wlan_11h_is_active(mlan_private * priv);
+
+/** Activate 11h extensions in the firmware */
+extern int wlan_11h_activate(mlan_private * priv, t_u32 flag);
+
+/** Enable the tx interface and record the new transmit state */
+extern void wlan_11h_tx_enable(mlan_private * priv);
+
+/** Enable the tx interface and record the new transmit state */
+extern void wlan_11h_tx_disable(mlan_private * priv);
+
+/** Check if radar detection is required on the specified channel */
+extern int wlan_11h_radar_detect_required(mlan_private * priv, t_u8 channel);
+
+/** Perform a standard availibility check on the specified channel */
+extern int wlan_11h_radar_detected(mlan_private * priv, t_u8 channel);
+
+/** Get an initial random channel to start an adhoc network on */
+extern int wlan_11h_get_adhoc_start_channel(mlan_private * priv);
+
+/** Add any 11h TLVs necessary to complete a join command (adhoc or infra) */
+extern int wlan_11h_process_join(mlan_private * priv,
+                                 t_u8 ** ppbuffer,
+                                 IEEEtypes_CapInfo_t * pcap_info,
+                                 t_u32 channel,
+                                 wlan_11h_bss_info_t * p11h_bss_info);
+
+/** Add any 11h TLVs necessary to complete an adhoc start command */
+extern int wlan_11h_process_start(mlan_private * priv,
+                                  t_u8 ** ppbuffer,
+                                  IEEEtypes_CapInfo_t * pcap_info,
+                                  t_u32 channel,
+                                  wlan_11h_bss_info_t * p11h_bss_info);
+
+/** Receive IEs from scan processing and record any needed info for 11h */
+int wlan_11h_process_bss_elem(wlan_11h_bss_info_t * p11h_bss_info,
+                              const t_u8 * pelement);
+
+/** Complete the firmware command preparation for an 11h command function */
+extern int wlan_11h_cmd_process(mlan_private * priv,
+                                HostCmd_DS_COMMAND * pcmd_ptr,
+                                const t_void * pinfo_buf);
+
+/** Process the response of an 11h firmware command */
+extern int wlan_11h_cmdresp_process(mlan_private * priv,
+                                    const HostCmd_DS_COMMAND * resp);
+
+#endif /*_MLAN_11H_ */
diff --git a/wlan_src/mlan/mlan_11n.c b/wlan_src/mlan/mlan_11n.c
new file mode 100755
index 0000000..3aafcd5
--- /dev/null
+++ b/wlan_src/mlan/mlan_11n.c
@@ -0,0 +1,1454 @@
+/** @file mlan_11n.c
+ *
+ *  @brief This file contains functions for 11n handling.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    11/10/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+
+/********************************************************
+    Local Variables
+********************************************************/
+
+/********************************************************
+    Global Variables
+********************************************************/
+
+/********************************************************
+    Local Functions
+********************************************************/
+
+/** 
+ *
+ *  @brief set/get max tx buf size
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return				MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_11n_ioctl_max_tx_buf_size(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_11n_cfg *cfg = MNULL;
+
+    ENTER();
+
+    cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        if ((cfg->param.tx_buf_size == MLAN_TX_DATA_BUF_SIZE_2K) ||
+            (cfg->param.tx_buf_size == MLAN_TX_DATA_BUF_SIZE_4K) ||
+            (cfg->param.tx_buf_size == MLAN_TX_DATA_BUF_SIZE_8K)) {
+            pmadapter->max_tx_buf_size = (t_u16) cfg->param.tx_buf_size;
+        } else
+            ret = MLAN_STATUS_FAILURE;
+    } else
+        cfg->param.tx_buf_size = (t_u32) pmadapter->max_tx_buf_size;
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/get htcapinfo configuration 
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return				MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_11n_ioctl_htusrcfg(IN pmlan_adapter pmadapter,
+                        IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_11n_cfg *cfg = MNULL;
+
+    ENTER();
+
+    cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;
+
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        if (((cfg->param.htcap_cfg & ~IGN_HW_DEV_CAP) &
+             pmpriv->adapter->hw_dot_11n_dev_cap)
+            != (cfg->param.htcap_cfg & ~IGN_HW_DEV_CAP))
+            ret = MLAN_STATUS_FAILURE;
+        else
+            pmadapter->usr_dot_11n_dev_cap = cfg->param.htcap_cfg;
+        PRINTM(MINFO, "UsrDot11nCap 0x%x\n", pmadapter->usr_dot_11n_dev_cap);
+    } else {
+        cfg->param.htcap_cfg = pmadapter->usr_dot_11n_dev_cap;
+        PRINTM(MINFO, "UsrDot11nCap 0x%x\n", cfg->param.htcap_cfg);
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Enable/Disable AMSDU AGGR CTRL
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return				MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_11n_ioctl_amsdu_aggr_ctrl(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_11n_cfg *cfg = MNULL;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    PRINTM(MERROR, "Prepare the command\n");
+    cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_SET)
+        cmd_action = HostCmd_ACT_GEN_SET;
+    else
+        cmd_action = HostCmd_ACT_GEN_GET;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_AMSDU_AGGR_CTRL,
+                           cmd_action,
+                           0,
+                           (t_void *) pioctl_req,
+                           (t_void *) & cfg->param.amsdu_aggr_ctrl);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/get 11n configuration 
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return				MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_11n_ioctl_httxcfg(IN pmlan_adapter pmadapter,
+                       IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_11n_cfg *cfg = MNULL;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_SET)
+        cmd_action = HostCmd_ACT_GEN_SET;
+    else
+        cmd_action = HostCmd_ACT_GEN_GET;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_11N_CFG,
+                           cmd_action,
+                           0,
+                           (t_void *) pioctl_req,
+                           (t_void *) & cfg->param.tx_cfg);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/get addba parameter 
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_11n_ioctl_addba_param(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_11n_cfg *cfg = MNULL;
+    t_u32 timeout;
+
+    ENTER();
+
+    cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        cfg->param.addba_param.timeout = pmpriv->add_ba_param.timeout;
+        cfg->param.addba_param.txwinsize = pmpriv->add_ba_param.tx_win_size;
+        cfg->param.addba_param.rxwinsize = pmpriv->add_ba_param.rx_win_size;
+    } else {
+        timeout = pmpriv->add_ba_param.timeout;
+        pmpriv->add_ba_param.timeout = cfg->param.addba_param.timeout;
+        pmpriv->add_ba_param.tx_win_size = cfg->param.addba_param.txwinsize;
+        pmpriv->add_ba_param.rx_win_size = cfg->param.addba_param.rxwinsize;
+        if (timeout != pmpriv->add_ba_param.timeout) {
+            wlan_11n_update_addba_request(pmpriv);
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/get addba reject set 
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_11n_ioctl_addba_reject(IN pmlan_adapter pmadapter,
+                            IN pmlan_ioctl_req pioctl_req)
+{
+    int i = 0;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_11n_cfg *cfg = MNULL;
+
+    ENTER();
+
+    cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;
+
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        PRINTM(MERROR, "Addba reject MLAN\n");
+        memcpy(cfg->param.addba_reject, pmpriv->addba_reject, MAX_NUM_TID);
+    } else {
+        if (pmpriv->media_connected == MTRUE) {
+            PRINTM(MERROR, "Can not set aggr priority table in connected"
+                   " state\n");
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+
+        for (i = 0; i < MAX_NUM_TID; i++) {
+            /* For AMPDU */
+            if (cfg->param.addba_reject[i] > ADDBA_RSP_STATUS_REJECT) {
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+
+            pmpriv->addba_reject[i] = cfg->param.addba_reject[i];
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/get aggr_prio_tbl 
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_11n_ioctl_aggr_prio_tbl(IN pmlan_adapter pmadapter,
+                             IN pmlan_ioctl_req pioctl_req)
+{
+    int i = 0;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_11n_cfg *cfg = MNULL;
+
+    ENTER();
+
+    cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;
+
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        for (i = 0; i < MAX_NUM_TID; i++) {
+            cfg->param.aggr_prio_tbl.ampdu[i] =
+                pmpriv->aggr_prio_tbl[i].ampdu_user;
+            cfg->param.aggr_prio_tbl.amsdu[i] = pmpriv->aggr_prio_tbl[i].amsdu;
+        }
+    } else {
+        if (pmpriv->media_connected == MTRUE) {
+            PRINTM(MERROR, "Can not set aggr priority table in connected"
+                   " state\n");
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+
+        for (i = 0; i < MAX_NUM_TID; i++) {
+            /* For AMPDU */
+            if ((cfg->param.aggr_prio_tbl.ampdu[i] > HIGH_PRIO_TID) &&
+                (cfg->param.aggr_prio_tbl.ampdu[i] != BA_STREAM_NOT_ALLOWED)) {
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+
+            pmpriv->aggr_prio_tbl[i].ampdu_ap =
+                pmpriv->aggr_prio_tbl[i].ampdu_user =
+                cfg->param.aggr_prio_tbl.ampdu[i];
+
+            /* For AMSDU */
+            if ((cfg->param.aggr_prio_tbl.amsdu[i] > HIGH_PRIO_TID &&
+                 cfg->param.aggr_prio_tbl.amsdu[i] != BA_STREAM_NOT_ALLOWED)) {
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            } else {
+                pmpriv->aggr_prio_tbl[i].amsdu =
+                    cfg->param.aggr_prio_tbl.amsdu[i];
+            }
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function fills the cap info
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pht_cap      A pointer to MrvlIETypes_HTCap_t structure
+ *
+ *  @return             N/A
+ */
+void
+wlan_fill_cap_info(mlan_adapter * pmadapter, MrvlIETypes_HTCap_t * pht_cap)
+{
+    int rx_mcs_supp;
+
+    ENTER();
+
+    if (ISSUPP_CHANWIDTH40(pmadapter->hw_dot_11n_dev_cap) &&
+        ISSUPP_CHANWIDTH40(pmadapter->usr_dot_11n_dev_cap))
+        SETHT_SUPPCHANWIDTH(pht_cap->ht_cap.ht_cap_info);
+    else
+        RESETHT_SUPPCHANWIDTH(pht_cap->ht_cap.ht_cap_info);
+
+    if (ISSUPP_GREENFIELD(pmadapter->hw_dot_11n_dev_cap) &&
+        ISSUPP_GREENFIELD(pmadapter->usr_dot_11n_dev_cap))
+        SETHT_GREENFIELD(pht_cap->ht_cap.ht_cap_info);
+    else
+        RESETHT_GREENFIELD(pht_cap->ht_cap.ht_cap_info);
+
+    if (ISSUPP_SHORTGI20(pmadapter->hw_dot_11n_dev_cap) &&
+        ISSUPP_SHORTGI20(pmadapter->usr_dot_11n_dev_cap))
+        SETHT_SHORTGI20(pht_cap->ht_cap.ht_cap_info);
+    else
+        RESETHT_SHORTGI20(pht_cap->ht_cap.ht_cap_info);
+
+    if (ISSUPP_SHORTGI40(pmadapter->hw_dot_11n_dev_cap) &&
+        ISSUPP_SHORTGI40(pmadapter->usr_dot_11n_dev_cap))
+        SETHT_SHORTGI40(pht_cap->ht_cap.ht_cap_info);
+    else
+        RESETHT_SHORTGI40(pht_cap->ht_cap.ht_cap_info);
+
+    /* No user config for RX STBC yet */
+    if (ISSUPP_RXSTBC(pmadapter->hw_dot_11n_dev_cap)
+        && ISSUPP_RXSTBC(pmadapter->usr_dot_11n_dev_cap))
+        SETHT_RXSTBC(pht_cap->ht_cap.ht_cap_info, 1);
+    else
+        RESETHT_RXSTBC(pht_cap->ht_cap.ht_cap_info);
+
+    /* No user config for TX STBC yet */
+    if (ISSUPP_TXSTBC(pmadapter->hw_dot_11n_dev_cap))
+        SETHT_TXSTBC(pht_cap->ht_cap.ht_cap_info);
+    else
+        RESETHT_TXSTBC(pht_cap->ht_cap.ht_cap_info);
+
+    /* No user config for Delayed BACK yet */
+    if (GET_DELAYEDBACK(pmadapter->hw_dot_11n_dev_cap))
+        SETHT_DELAYEDBACK(pht_cap->ht_cap.ht_cap_info);
+    else
+        RESETHT_DELAYEDBACK(pht_cap->ht_cap.ht_cap_info);
+
+    if (ISENABLED_40MHZ_INTOLARENT(pmadapter->usr_dot_11n_dev_cap))
+        SETHT_40MHZ_INTOLARANT(pht_cap->ht_cap.ht_cap_info);
+    else
+        RESETHT_40MHZ_INTOLARANT(pht_cap->ht_cap.ht_cap_info);
+
+    SETAMPDU_SIZE(pht_cap->ht_cap.ampdu_param, AMPDU_FACTOR_64K);
+    SETAMPDU_SPACING(pht_cap->ht_cap.ampdu_param, 0);
+
+    /* Need change to support 8k AMSDU receive */
+    RESETHT_MAXAMSDU(pht_cap->ht_cap.ht_cap_info);
+
+    rx_mcs_supp = GET_RXMCSSUPP(pmadapter->hw_dev_mcs_support);
+/** Maximum MCS */
+#define NUM_MCS_FIELD      16
+
+    /* Set MCS for 1x1 */
+    memset((t_u8 *) pht_cap->ht_cap.supported_mcs_set, 0xff, rx_mcs_supp);
+    /* Clear all the other values */
+    memset((t_u8 *) & pht_cap->ht_cap.supported_mcs_set[rx_mcs_supp], 0,
+           NUM_MCS_FIELD - rx_mcs_supp);
+    /* Set MCS32, this is mandatory for any 11n device */
+    SETHT_MCS32(pht_cap->ht_cap.supported_mcs_set);
+
+    LEAVE();
+}
+
+/********************************************************
+    Global Functions
+********************************************************/
+/** 
+ *  @brief This function prints the 802.11n device capability
+ *  
+ *  @param pmadapter     A pointer to mlan_adapter structure
+ *  @param cap           Capability value
+ *
+ *  @return        N/A
+ */
+void
+wlan_show_dot11ndevcap(pmlan_adapter pmadapter, t_u32 cap)
+{
+    ENTER();
+
+    PRINTM(MINFO, "GET_HW_SPEC: Maximum MSDU length = %s octets\n",
+           (ISSUPP_MAXAMSDU(cap) ? "7935" : "3839"));
+    PRINTM(MINFO, "GET_HW_SPEC: Beam forming %s\n",
+           (ISSUPP_BEAMFORMING(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: Greenfield preamble %s\n",
+           (ISSUPP_GREENFIELD(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: AMPDU %s\n",
+           (ISSUPP_AMPDU(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: MIMO Power Save %s\n",
+           (ISSUPP_MIMOPS(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: Rx STBC %s\n",
+           (ISSUPP_RXSTBC(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: Tx STBC %s\n",
+           (ISSUPP_TXSTBC(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: Short GI for 40 Mhz %s\n",
+           (ISSUPP_SHORTGI40(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: Short GI for 20 Mhz %s\n",
+           (ISSUPP_SHORTGI20(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: LDPC coded packet receive %s\n",
+           (ISSUPP_RXLDPC(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: Number of Delayed Block Ack streams = %d\n",
+           GET_DELAYEDBACK(cap));
+    PRINTM(MINFO, "GET_HW_SPEC: Number of Immediate Block Ack streams = %d\n",
+           GET_IMMEDIATEBACK(cap));
+    PRINTM(MINFO, "GET_HW_SPEC: 40 Mhz channel width %s\n",
+           (ISSUPP_CHANWIDTH40(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: 20 Mhz channel width %s\n",
+           (ISSUPP_CHANWIDTH20(cap) ? "supported" : "not supported"));
+    PRINTM(MINFO, "GET_HW_SPEC: 10 Mhz channel width %s\n",
+           (ISSUPP_CHANWIDTH10(cap) ? "supported" : "not supported"));
+
+    if (ISSUPP_RXANTENNAA(cap)) {
+        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Rx antennea A\n");
+    }
+    if (ISSUPP_RXANTENNAB(cap)) {
+        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Rx antennea B\n");
+    }
+    if (ISSUPP_RXANTENNAC(cap)) {
+        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Rx antennea C\n");
+    }
+    if (ISSUPP_RXANTENNAD(cap)) {
+        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Rx antennea D\n");
+    }
+    if (ISSUPP_TXANTENNAA(cap)) {
+        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Tx antennea A\n");
+    }
+    if (ISSUPP_TXANTENNAB(cap)) {
+        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Tx antennea B\n");
+    }
+    if (ISSUPP_TXANTENNAC(cap)) {
+        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Tx antennea C\n");
+    }
+    if (ISSUPP_TXANTENNAD(cap)) {
+        PRINTM(MINFO, "GET_HW_SPEC: Prescence of Tx antennea D\n");
+    }
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function prints the 802.11n device MCS
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param support   Support value
+ *
+ *  @return        N/A
+ */
+void
+wlan_show_devmcssupport(pmlan_adapter pmadapter, t_u8 support)
+{
+    ENTER();
+
+    PRINTM(MINFO, "GET_HW_SPEC: MCSs for %dx%d MIMO\n", GET_RXMCSSUPP(support),
+           GET_TXMCSSUPP(support));
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function handles the command response of
+ *              delete a block ack request
+ *  
+ *  @param priv    A pointer to mlan_private structure
+ *  @param resp    A pointer to HostCmd_DS_COMMAND
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_11n_delba(mlan_private * priv, HostCmd_DS_COMMAND * resp)
+{
+    int tid;
+    TxBAStreamTbl *ptx_ba_tbl;
+    HostCmd_DS_11N_DELBA *pdel_ba =
+        (HostCmd_DS_11N_DELBA *) & resp->params.del_ba;
+
+    ENTER();
+
+    pdel_ba->del_ba_param_set = wlan_le16_to_cpu(pdel_ba->del_ba_param_set);
+    pdel_ba->reason_code = wlan_le16_to_cpu(pdel_ba->reason_code);
+
+    tid = pdel_ba->del_ba_param_set >> DELBA_TID_POS;
+    if (pdel_ba->del_result == BA_RESULT_SUCCESS) {
+        mlan_11n_delete_bastream_tbl(priv, tid, pdel_ba->peer_mac_addr,
+                                     TYPE_DELBA_SENT,
+                                     INITIATOR_BIT(pdel_ba->del_ba_param_set));
+
+        if ((ptx_ba_tbl = wlan_11n_get_txbastream_status(priv,
+                                                         BA_STREAM_SETUP_INPROGRESS)))
+        {
+            wlan_send_addba(priv, ptx_ba_tbl->tid, ptx_ba_tbl->ra);
+        }
+    } else {                    /* 
+                                 * In case of failure, recreate the deleted stream in
+                                 * case we initiated the ADDBA
+                                 */
+        if (INITIATOR_BIT(pdel_ba->del_ba_param_set)) {
+            wlan_11n_create_txbastream_tbl(priv, pdel_ba->peer_mac_addr, tid,
+                                           BA_STREAM_SETUP_INPROGRESS);
+            if ((ptx_ba_tbl = wlan_11n_get_txbastream_status(priv,
+                                                             BA_STREAM_SETUP_INPROGRESS)))
+            {
+                mlan_11n_delete_bastream_tbl(priv, ptx_ba_tbl->tid,
+                                             ptx_ba_tbl->ra, TYPE_DELBA_SENT,
+                                             MTRUE);
+            }
+        }
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of
+ *              add a block ack request
+ *  
+ *  @param priv    A pointer to mlan_private structure
+ *  @param resp    A pointer to HostCmd_DS_COMMAND
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_11n_addba_req(mlan_private * priv, HostCmd_DS_COMMAND * resp)
+{
+    int tid;
+    HostCmd_DS_11N_ADDBA_RSP *padd_ba_rsp =
+        (HostCmd_DS_11N_ADDBA_RSP *) & resp->params.add_ba_rsp;
+    TxBAStreamTbl *ptx_ba_tbl;
+
+    ENTER();
+
+    padd_ba_rsp->block_ack_param_set =
+        wlan_le16_to_cpu(padd_ba_rsp->block_ack_param_set);
+    padd_ba_rsp->block_ack_tmo = wlan_le16_to_cpu(padd_ba_rsp->block_ack_tmo);
+    padd_ba_rsp->ssn = (wlan_le16_to_cpu(padd_ba_rsp->ssn)) & SSN_MASK;
+    padd_ba_rsp->status_code = wlan_le16_to_cpu(padd_ba_rsp->status_code);
+
+    tid = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_TID_MASK)
+        >> BLOCKACKPARAM_TID_POS;
+    if (padd_ba_rsp->status_code == BA_RESULT_SUCCESS) {
+        if ((ptx_ba_tbl = wlan_11n_get_txbastream_tbl(priv, tid,
+                                                      padd_ba_rsp->
+                                                      peer_mac_addr))) {
+            PRINTM(MINFO, "BA stream complete\n");
+            ptx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE;
+        } else {
+            PRINTM(MERROR, "Stream not created!!!\n");
+        }
+    } else {
+        mlan_11n_delete_bastream_tbl(priv, tid, padd_ba_rsp->peer_mac_addr,
+                                     TYPE_DELBA_SENT, MTRUE);
+        if (padd_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) {
+            priv->aggr_prio_tbl[tid].ampdu_ap = BA_STREAM_NOT_ALLOWED;
+        }
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of 11ncfg
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_11n_cfg(IN pmlan_private pmpriv,
+                 IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_11n_cfg *cfg = MNULL;
+    HostCmd_DS_11N_CFG *htcfg = &resp->params.htcfg;
+
+    ENTER();
+    if (pioctl_buf) {
+        cfg = (mlan_ds_11n_cfg *) pioctl_buf->pbuf;
+        cfg->param.tx_cfg.httxcap = wlan_le16_to_cpu(htcfg->ht_tx_cap);
+        cfg->param.tx_cfg.httxinfo = wlan_le16_to_cpu(htcfg->ht_tx_info);
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of reconfigure tx buf
+ *  
+ *  @param priv         A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_cmd_recfg_tx_buf(mlan_private * priv,
+                      HostCmd_DS_COMMAND * cmd, int cmd_action, void *pdata_buf)
+{
+    HostCmd_DS_TXBUF_CFG *ptx_buf = &cmd->params.tx_buf;
+    t_u16 action = (t_u16) cmd_action;
+    t_u16 buf_size = *((t_u16 *) pdata_buf);
+
+    ENTER();
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_TXBUF_CFG)
+                                 + S_DS_GEN);
+    ptx_buf->action = wlan_cpu_to_le16(action);
+    switch (action) {
+    case HostCmd_ACT_GEN_SET:
+        PRINTM(MCMND, "set tx_buf=%d\n", buf_size);
+        ptx_buf->buff_size = wlan_cpu_to_le16(buf_size);
+        break;
+    case HostCmd_ACT_GEN_GET:
+    default:
+        ptx_buf->buff_size = 0;
+        break;
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of amsdu aggr control
+ *  
+ *  @param priv         A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_cmd_amsdu_aggr_ctrl(mlan_private * priv,
+                         HostCmd_DS_COMMAND * cmd,
+                         int cmd_action, void *pdata_buf)
+{
+    HostCmd_DS_AMSDU_AGGR_CTRL *pamsdu_ctrl = &cmd->params.amsdu_aggr_ctrl;
+    t_u16 action = (t_u16) cmd_action;
+    mlan_ds_11n_amsdu_aggr_ctrl *aa_ctrl = (mlan_ds_11n_amsdu_aggr_ctrl *)
+        pdata_buf;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_AMSDU_AGGR_CTRL)
+                                 + S_DS_GEN);
+    pamsdu_ctrl->action = wlan_cpu_to_le16(action);
+    switch (action) {
+    case HostCmd_ACT_GEN_SET:
+        pamsdu_ctrl->enable = wlan_cpu_to_le16(aa_ctrl->enable);
+        pamsdu_ctrl->curr_buf_size = 0;
+        break;
+    case HostCmd_ACT_GEN_GET:
+    default:
+        pamsdu_ctrl->curr_buf_size = 0;
+        break;
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of amsdu aggr ctrl
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_amsdu_aggr_ctrl(IN pmlan_private pmpriv,
+                         IN HostCmd_DS_COMMAND * resp,
+                         IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_11n_cfg *cfg = MNULL;
+    HostCmd_DS_AMSDU_AGGR_CTRL *amsdu_ctrl = &resp->params.amsdu_aggr_ctrl;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        cfg = (mlan_ds_11n_cfg *) pioctl_buf->pbuf;
+        cfg->param.amsdu_aggr_ctrl.enable =
+            wlan_le16_to_cpu(amsdu_ctrl->enable);
+        cfg->param.amsdu_aggr_ctrl.curr_buf_size =
+            wlan_le16_to_cpu(amsdu_ctrl->curr_buf_size);
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares 11n cfg command
+ *  
+ *  @param pmpriv    	A pointer to mlan_private structure
+ *  @param cmd	   	A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action 	the action: GET or SET
+ *  @param pdata_buf 	A pointer to data buffer
+ *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_11n_cfg(IN pmlan_private pmpriv,
+                 IN HostCmd_DS_COMMAND * cmd,
+                 IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    HostCmd_DS_11N_CFG *htcfg = &cmd->params.htcfg;
+    mlan_ds_11n_tx_cfg *txcfg = (mlan_ds_11n_tx_cfg *) pdata_buf;
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_11N_CFG);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_11N_CFG) + S_DS_GEN);
+    htcfg->action = wlan_cpu_to_le16(cmd_action);
+    htcfg->ht_tx_cap = wlan_cpu_to_le16(txcfg->httxcap);
+    htcfg->ht_tx_info = wlan_cpu_to_le16(txcfg->httxinfo);
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function append the 802_11N tlv
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pbss_desc    A pointer to BSSDescriptor_t structure
+ *  @param ppbuffer     A Pointer to command buffer pointer
+ *
+ *  @return bytes added to the buffer       
+ */
+int
+wlan_cmd_append_11n_tlv(IN mlan_private * pmpriv,
+                        IN BSSDescriptor_t * pbss_desc, OUT t_u8 ** ppbuffer)
+{
+    MrvlIETypes_HTCap_t *pht_cap;
+    MrvlIETypes_HTInfo_t *pht_info;
+    MrvlIEtypes_ChanListParamSet_t *pchan_list;
+    MrvlIETypes_2040BSSCo_t *p2040_bss_co;
+    MrvlIETypes_ExtCap_t *pext_cap;
+    int ret_len = 0;
+
+    ENTER();
+
+    /* Null Checks */
+    if (ppbuffer == 0) {
+        LEAVE();
+        return 0;
+    }
+    if (*ppbuffer == 0) {
+        LEAVE();
+        return 0;
+    }
+
+    if (pbss_desc->pht_cap) {
+        pht_cap = (MrvlIETypes_HTCap_t *) * ppbuffer;
+        memset(pht_cap, 0, sizeof(MrvlIETypes_HTCap_t));
+        pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY);
+        pht_cap->header.len = sizeof(HTCap_t);
+        memcpy((t_u8 *) pht_cap + sizeof(MrvlIEtypesHeader_t),
+               (t_u8 *) pbss_desc->pht_cap + sizeof(IEEEtypes_Header_t),
+               pht_cap->header.len);
+
+        pht_cap->ht_cap.ht_cap_info =
+            wlan_le16_to_cpu(pht_cap->ht_cap.ht_cap_info);
+        wlan_fill_cap_info(pmpriv->adapter, pht_cap);
+        pht_cap->ht_cap.ht_cap_info =
+            wlan_cpu_to_le16(pht_cap->ht_cap.ht_cap_info);
+
+        HEXDUMP("HT_CAPABILITIES IE", (t_u8 *) pht_cap,
+                sizeof(MrvlIETypes_HTCap_t));
+        *ppbuffer += sizeof(MrvlIETypes_HTCap_t);
+        ret_len += sizeof(MrvlIETypes_HTCap_t);
+        pht_cap->header.len = wlan_cpu_to_le16(pht_cap->header.len);
+    }
+
+    if (pbss_desc->pht_info) {
+        pht_info = (MrvlIETypes_HTInfo_t *) * ppbuffer;
+        memset(pht_info, 0, sizeof(MrvlIETypes_HTInfo_t));
+        pht_info->header.type = wlan_cpu_to_le16(HT_OPERATION);
+        pht_info->header.len = sizeof(HTInfo_t);
+
+        memcpy((t_u8 *) pht_info + sizeof(MrvlIEtypesHeader_t),
+               (t_u8 *) pbss_desc->pht_info + sizeof(IEEEtypes_Header_t),
+               pht_info->header.len);
+
+        if (!ISSUPP_CHANWIDTH40(pmpriv->adapter->hw_dot_11n_dev_cap) ||
+            !ISSUPP_CHANWIDTH40(pmpriv->adapter->usr_dot_11n_dev_cap)) {
+            RESET_CHANWIDTH40(pht_info->ht_info.field2);
+        }
+
+        *ppbuffer += sizeof(MrvlIETypes_HTInfo_t);
+        ret_len += sizeof(MrvlIETypes_HTInfo_t);
+        pht_info->header.len = wlan_cpu_to_le16(pht_info->header.len);
+
+        pchan_list = (MrvlIEtypes_ChanListParamSet_t *) * ppbuffer;
+        memset(pchan_list, 0, sizeof(MrvlIEtypes_ChanListParamSet_t));
+        pchan_list->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
+        pchan_list->header.len = sizeof(MrvlIEtypes_ChanListParamSet_t) -
+            sizeof(MrvlIEtypesHeader_t);
+        pchan_list->chan_scan_param[0].chan_number = pbss_desc->pht_info->
+            ht_info.pri_chan;
+        pchan_list->chan_scan_param[0].radio_type =
+            wlan_band_to_radio_type((t_u8) pbss_desc->bss_band);
+
+        if ((ISSUPP_CHANWIDTH40(pmpriv->adapter->hw_dot_11n_dev_cap) &&
+             ISSUPP_CHANWIDTH40(pmpriv->adapter->usr_dot_11n_dev_cap)) &&
+            ISALLOWED_CHANWIDTH40(pbss_desc->pht_info->ht_info.field2))
+            SET_SECONDARYCHAN(pchan_list->chan_scan_param[0].radio_type,
+                              GET_SECONDARYCHAN(pbss_desc->pht_info->ht_info.
+                                                field2));
+
+        HEXDUMP("ChanList", (t_u8 *) pchan_list,
+                sizeof(MrvlIEtypes_ChanListParamSet_t));
+        HEXDUMP("pht_info", (t_u8 *) pbss_desc->pht_info,
+                sizeof(MrvlIETypes_HTInfo_t) - 2);
+        *ppbuffer += sizeof(MrvlIEtypes_ChanListParamSet_t);
+        ret_len += sizeof(MrvlIEtypes_ChanListParamSet_t);
+        pchan_list->header.len = wlan_cpu_to_le16(pchan_list->header.len);
+    }
+
+    if (pbss_desc->pbss_co_2040) {
+        p2040_bss_co = (MrvlIETypes_2040BSSCo_t *) * ppbuffer;
+        memset(p2040_bss_co, 0, sizeof(MrvlIETypes_2040BSSCo_t));
+        p2040_bss_co->header.type = wlan_cpu_to_le16(BSSCO_2040);
+        p2040_bss_co->header.len = sizeof(BSSCo2040_t);
+
+        memcpy((t_u8 *) p2040_bss_co + sizeof(MrvlIEtypesHeader_t),
+               (t_u8 *) pbss_desc->pbss_co_2040 + sizeof(IEEEtypes_Header_t),
+               p2040_bss_co->header.len);
+
+        HEXDUMP("20/40 BSS Coexistence IE", (t_u8 *) p2040_bss_co,
+                sizeof(MrvlIETypes_2040BSSCo_t));
+        *ppbuffer += sizeof(MrvlIETypes_2040BSSCo_t);
+        ret_len += sizeof(MrvlIETypes_2040BSSCo_t);
+        p2040_bss_co->header.len = wlan_cpu_to_le16(p2040_bss_co->header.len);
+    }
+
+    if (pbss_desc->pext_cap) {
+        pext_cap = (MrvlIETypes_ExtCap_t *) * ppbuffer;
+        memset(pext_cap, 0, sizeof(MrvlIETypes_ExtCap_t));
+        pext_cap->header.type = wlan_cpu_to_le16(EXT_CAPABILITY);
+        pext_cap->header.len = sizeof(ExtCap_t);
+
+        memcpy((t_u8 *) pext_cap + sizeof(MrvlIEtypesHeader_t),
+               (t_u8 *) pbss_desc->pext_cap + sizeof(IEEEtypes_Header_t),
+               pext_cap->header.len);
+
+        HEXDUMP("Extended Capabilities IE", (t_u8 *) pext_cap,
+                sizeof(MrvlIETypes_ExtCap_t));
+        *ppbuffer += sizeof(MrvlIETypes_ExtCap_t);
+        ret_len += sizeof(MrvlIETypes_ExtCap_t);
+        pext_cap->header.len = wlan_cpu_to_le16(pext_cap->header.len);
+    }
+
+    LEAVE();
+    return ret_len;
+}
+
+/**
+ *  @brief This function reconfigure the tx buf size in firmware.
+ *
+ *  @param pmpriv    A pointer to mlan_private structure
+ *  @param pbss_desc  BSSDescriptor_t from the scan table to assoc
+ *
+ *  @return          N/A
+ */
+void
+wlan_cfg_tx_buf(mlan_private * pmpriv, BSSDescriptor_t * pbss_desc)
+{
+    t_u16 max_amsdu = MLAN_TX_DATA_BUF_SIZE_2K;
+    t_u16 tx_buf = 0;
+
+    ENTER();
+
+    if (pbss_desc->pht_cap) {
+        if (GETHT_MAXAMSDU(pbss_desc->pht_cap->ht_cap.ht_cap_info))
+            max_amsdu = MLAN_TX_DATA_BUF_SIZE_8K;
+        else
+            max_amsdu = MLAN_TX_DATA_BUF_SIZE_4K;
+    }
+
+    tx_buf = MIN(pmpriv->adapter->max_tx_buf_size, max_amsdu);
+
+    PRINTM(MINFO, "max_amsdu=%d, maxTxBuf=%d\n", max_amsdu,
+           pmpriv->adapter->max_tx_buf_size);
+
+    if (pmpriv->adapter->tx_buf_size != tx_buf) {
+        wlan_prepare_cmd(pmpriv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
+                         HostCmd_ACT_GEN_SET, 0, MNULL, &tx_buf);
+    }
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief 11n configuration handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+mlan_status
+wlan_11n_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_11n_cfg *cfg = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_11n_cfg)) {
+        PRINTM(MINFO, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_11n_cfg);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    cfg = (mlan_ds_11n_cfg *) pioctl_req->pbuf;
+    switch (cfg->sub_command) {
+    case MLAN_OID_11N_CFG_TX:
+        status = wlan_11n_ioctl_httxcfg(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_11N_HTCAP_CFG:
+        status = wlan_11n_ioctl_htusrcfg(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_11N_CFG_AGGR_PRIO_TBL:
+        status = wlan_11n_ioctl_aggr_prio_tbl(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_11N_CFG_ADDBA_REJECT:
+        status = wlan_11n_ioctl_addba_reject(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_11N_CFG_ADDBA_PARAM:
+        status = wlan_11n_ioctl_addba_param(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE:
+        status = wlan_11n_ioctl_max_tx_buf_size(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL:
+        status = wlan_11n_ioctl_amsdu_aggr_ctrl(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/**
+ *  @brief This function checks if the given pointer is valid entry of 
+ *         Tx BA Stream table
+ *  
+ *  @param priv         Pointer to mlan_private
+ *  @param ptxtblptr    Pointer to tx ba stream entry
+ *
+ *  @return             MTRUE or MFALSE
+ */
+int
+wlan_is_txbastreamptr_valid(mlan_private * priv, TxBAStreamTbl * ptxtblptr)
+{
+    TxBAStreamTbl *ptx_tbl;
+
+    ENTER();
+
+    if (!
+        (ptx_tbl =
+         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr, MNULL,
+                                          MNULL))) {
+        LEAVE();
+        return MFALSE;
+    }
+
+    while (ptx_tbl != (TxBAStreamTbl *) & priv->tx_ba_stream_tbl_ptr) {
+        if (ptx_tbl == ptxtblptr) {
+            LEAVE();
+            return MTRUE;
+        }
+
+        ptx_tbl = ptx_tbl->pnext;
+    }
+
+    LEAVE();
+    return MFALSE;
+}
+
+/**
+ *  @brief This function will delete the given entry in Tx BA Stream table
+ *  
+ *  @param priv    	Pointer to mlan_private
+ *  @param ptx_tbl	Pointer to tx ba stream entry to delete
+ *
+ *  @return 	        N/A
+ */
+void
+wlan_11n_delete_txbastream_tbl_entry(mlan_private * priv,
+                                     TxBAStreamTbl * ptx_tbl)
+{
+    pmlan_adapter pmadapter = priv->adapter;
+
+    ENTER();
+
+    pmadapter->callbacks.moal_spin_lock(priv->tx_ba_stream_tbl_ptr.plock);
+
+    if (!ptx_tbl && wlan_is_txbastreamptr_valid(priv, ptx_tbl)) {
+        goto exit;
+    }
+
+    PRINTM(MINFO, "tx_ba_stream_tbl_ptr %p\n", ptx_tbl);
+
+    util_unlink_list(&priv->tx_ba_stream_tbl_ptr,
+                     (pmlan_linked_list) ptx_tbl, MNULL, MNULL);
+
+    pmadapter->callbacks.moal_mfree((t_u8 *) ptx_tbl);
+
+  exit:
+    pmadapter->callbacks.moal_spin_unlock(priv->tx_ba_stream_tbl_ptr.plock);
+    LEAVE();
+}
+
+/**
+ *  @brief This function will delete all the entires in Tx BA Stream table
+ *  
+ *  @param priv         A pointer to mlan_private
+ *
+ *  @return             N/A
+ */
+void
+wlan_11n_deleteall_txbastream_tbl(mlan_private * priv)
+{
+    int i;
+    TxBAStreamTbl *del_tbl_ptr;
+
+    ENTER();
+
+    while ((del_tbl_ptr = (TxBAStreamTbl *)
+            util_peek_list(&priv->tx_ba_stream_tbl_ptr,
+                           priv->adapter->callbacks.moal_spin_lock,
+                           priv->adapter->callbacks.moal_spin_unlock))) {
+        wlan_11n_delete_txbastream_tbl_entry(priv, del_tbl_ptr);
+    }
+
+    util_init_list((pmlan_linked_list) & priv->tx_ba_stream_tbl_ptr);
+
+    for (i = 0; i < MAX_NUM_TID; ++i) {
+        priv->aggr_prio_tbl[i].ampdu_ap = priv->aggr_prio_tbl[i].ampdu_user;
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief This function will return the pointer to a entry in BA Stream 
+ *  		table which matches the ba_status requested
+ *  
+ *  @param priv    	    A pointer to mlan_private
+ *  @param ba_status	Current status of the BA stream
+ *
+ *  @return 	        A pointer to first entry matching status in BA stream
+ */
+TxBAStreamTbl *
+wlan_11n_get_txbastream_status(mlan_private * priv, baStatus_e ba_status)
+{
+    TxBAStreamTbl *ptx_tbl;
+
+    ENTER();
+
+    if (!
+        (ptx_tbl =
+         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
+                                          priv->adapter->callbacks.
+                                          moal_spin_lock,
+                                          priv->adapter->callbacks.
+                                          moal_spin_unlock))) {
+        LEAVE();
+        return MNULL;
+    }
+
+    while (ptx_tbl != (TxBAStreamTbl *) & priv->tx_ba_stream_tbl_ptr) {
+        if (ptx_tbl->ba_status == ba_status) {
+            LEAVE();
+            return ptx_tbl;
+        }
+
+        ptx_tbl = ptx_tbl->pnext;
+    }
+
+    LEAVE();
+    return MNULL;
+}
+
+/**
+ *  @brief This function will return the pointer to a entry in BA Stream 
+ *  		table which matches the give RA/TID pair
+ *  
+ *  @param priv    A pointer to mlan_private
+ *  @param tid	   TID to find in reordering table
+ *  @param ra      RA to find in reordering table
+ *
+ *  @return 	   A pointer to first entry matching RA/TID in BA stream
+ */
+TxBAStreamTbl *
+wlan_11n_get_txbastream_tbl(mlan_private * priv, int tid, t_u8 * ra)
+{
+    TxBAStreamTbl *ptx_tbl;
+    pmlan_adapter pmadapter = priv->adapter;
+
+    ENTER();
+
+    if (!
+        (ptx_tbl =
+         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
+                                          pmadapter->callbacks.moal_spin_lock,
+                                          pmadapter->callbacks.
+                                          moal_spin_unlock))) {
+        LEAVE();
+        return MNULL;
+    }
+
+    while (ptx_tbl != (TxBAStreamTbl *) & priv->tx_ba_stream_tbl_ptr) {
+
+        PRINTM(MDAT_D, "get_txbastream_tbl TID %d\n", ptx_tbl->tid);
+        DBG_HEXDUMP(MDAT_D, "RA", ptx_tbl->ra, MLAN_MAC_ADDR_LENGTH);
+
+        if ((!memcmp(ptx_tbl->ra, ra, MLAN_MAC_ADDR_LENGTH))
+            && (ptx_tbl->tid == tid)) {
+            LEAVE();
+            return ptx_tbl;
+        }
+
+        ptx_tbl = ptx_tbl->pnext;
+    }
+
+    LEAVE();
+    return MNULL;
+}
+
+/**
+ *  @brief This function will create a entry in tx ba stream table for the 
+ *  		given RA/TID.
+ *  
+ *  @param priv      A pointer to mlan_private
+ *  @param ra        RA to find in reordering table
+ *  @param tid	     TID to find in reordering table
+ *  @param ba_status BA stream status to create the stream with
+ *
+ *  @return 	    N/A
+ */
+void
+wlan_11n_create_txbastream_tbl(mlan_private * priv,
+                               t_u8 * ra, int tid, baStatus_e ba_status)
+{
+    TxBAStreamTbl *newNode;
+    pmlan_adapter pmadapter = priv->adapter;
+
+    ENTER();
+
+    if (!wlan_11n_get_txbastream_tbl(priv, tid, ra)) {
+        PRINTM(MDAT_D, "get_txbastream_tbl TID %d", tid);
+        DBG_HEXDUMP(MDAT_D, "RA", ra, MLAN_MAC_ADDR_LENGTH);
+
+        pmadapter->callbacks.moal_malloc(sizeof(TxBAStreamTbl),
+                                         (t_u8 **) & newNode);
+        util_init_list((pmlan_linked_list) newNode);
+
+        newNode->tid = tid;
+        newNode->ba_status = ba_status;
+        memcpy(newNode->ra, ra, MLAN_MAC_ADDR_LENGTH);
+
+        util_enqueue_list_tail(&priv->tx_ba_stream_tbl_ptr,
+                               (pmlan_linked_list) newNode,
+                               pmadapter->callbacks.moal_spin_lock,
+                               pmadapter->callbacks.moal_spin_unlock);
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief This function will send a block ack to given tid/ra
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param tid	    TID to send the ADDBA
+ *  @param peer_mac MAC address to send the ADDBA
+ *
+ *  @return 	    MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+wlan_send_addba(mlan_private * priv, int tid, t_u8 * peer_mac)
+{
+    HostCmd_DS_11N_ADDBA_REQ add_ba_req;
+    static t_u8 dialog_tok;
+    mlan_status ret;
+
+    ENTER();
+
+    PRINTM(MCMND, "Send addba: TID %d\n", tid);
+    DBG_HEXDUMP(MCMD_D, "Send addba RA", peer_mac, MLAN_MAC_ADDR_LENGTH);
+
+    add_ba_req.block_ack_param_set = (t_u16) ((tid << BLOCKACKPARAM_TID_POS) |
+                                              (priv->add_ba_param.tx_win_size
+                                               << BLOCKACKPARAM_WINSIZE_POS) |
+                                              IMMEDIATE_BLOCK_ACK);
+    add_ba_req.block_ack_tmo = (t_u16) priv->add_ba_param.timeout;
+
+    ++dialog_tok;
+
+    if (dialog_tok == 0)
+        dialog_tok = 1;
+
+    add_ba_req.dialog_token = dialog_tok;
+    memcpy(&add_ba_req.peer_mac_addr, peer_mac, MLAN_MAC_ADDR_LENGTH);
+
+    /* We don't wait for the response of this command */
+    ret = wlan_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ,
+                           0, 0, MNULL, &add_ba_req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function will delete a block ack to given tid/ra
+ *  
+ *  @param priv    		A pointer to mlan_private
+ *  @param tid	   		TID to send the ADDBA
+ *  @param peer_mac 	MAC address to send the ADDBA
+ *  @param initiator 	MTRUE if we have initiated ADDBA, MFALSE otherwise
+ *
+ *  @return 	        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+wlan_send_delba(mlan_private * priv, int tid, t_u8 * peer_mac, int initiator)
+{
+    HostCmd_DS_11N_DELBA delba;
+    mlan_status ret;
+
+    ENTER();
+
+    memset(&delba, 0, sizeof(delba));
+    delba.del_ba_param_set = (tid << DELBA_TID_POS);
+
+    if (initiator)
+        DELBA_INITIATOR(delba.del_ba_param_set);
+    else
+        DELBA_RECIPIENT(delba.del_ba_param_set);
+
+    memcpy(&delba.peer_mac_addr, peer_mac, MLAN_MAC_ADDR_LENGTH);
+
+    /* We don't wait for the response of this command */
+    ret = wlan_prepare_cmd(priv, HostCmd_CMD_11N_DELBA,
+                           HostCmd_ACT_GEN_SET, 0, MNULL, &delba);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function handles the command response of
+ *  		delete a block ack request
+ *  
+ *  @param priv		A pointer to mlan_private structure
+ *  @param del_ba	A pointer to command response buffer
+ *
+ *  @return        N/A
+ */
+void
+wlan_11n_delete_bastream(mlan_private * priv, t_u8 * del_ba)
+{
+    HostCmd_DS_11N_DELBA *pdel_ba = (HostCmd_DS_11N_DELBA *) del_ba;
+    int tid;
+
+    ENTER();
+
+    DBG_HEXDUMP(MCMD_D, "Delba:", (t_u8 *) pdel_ba, 20);
+    pdel_ba->del_ba_param_set = wlan_le16_to_cpu(pdel_ba->del_ba_param_set);
+    pdel_ba->reason_code = wlan_le16_to_cpu(pdel_ba->reason_code);
+
+    tid = pdel_ba->del_ba_param_set >> DELBA_TID_POS;
+
+    mlan_11n_delete_bastream_tbl(priv, tid, pdel_ba->peer_mac_addr,
+                                 TYPE_DELBA_RECEIVE,
+                                 INITIATOR_BIT(pdel_ba->del_ba_param_set));
+
+    LEAVE();
+}
+
+/**
+ *  @brief This function will resend addba request to all 
+ *          the peer in the TxBAStreamTbl 
+ *  
+ *  @param priv     A pointer to mlan_private
+ *
+ *  @return         N/A	       
+ */
+void
+wlan_11n_update_addba_request(mlan_private * priv)
+{
+
+    TxBAStreamTbl *ptx_tbl;
+
+    ENTER();
+
+    if (!
+        (ptx_tbl =
+         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
+                                          priv->adapter->callbacks.
+                                          moal_spin_lock,
+                                          priv->adapter->callbacks.
+                                          moal_spin_unlock))) {
+        LEAVE();
+        return;
+    }
+
+    while (ptx_tbl != (TxBAStreamTbl *) & priv->tx_ba_stream_tbl_ptr) {
+        wlan_send_addba(priv, ptx_tbl->tid, ptx_tbl->ra);
+        ptx_tbl = ptx_tbl->pnext;
+    }
+
+    mlan_main_process(priv->adapter);
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief Get Rx reordering table
+ *   
+ *  @param priv         A pointer to mlan_private structure
+ *  @param buf          A pointer to rx_reorder_tbl structure
+ *  @return             num of rx reorder table entry
+ */
+int
+wlan_get_rxreorder_tbl(mlan_private * priv, rx_reorder_tbl * buf)
+{
+    int i;
+    rx_reorder_tbl *ptbl = buf;
+    RxReorderTbl *rxReorderTblPtr;
+    int count = 0;
+    ENTER();
+    if (!
+        (rxReorderTblPtr =
+         (RxReorderTbl *) util_peek_list(&priv->rx_reorder_tbl_ptr,
+                                         priv->adapter->callbacks.
+                                         moal_spin_lock,
+                                         priv->adapter->callbacks.
+                                         moal_spin_unlock))) {
+        LEAVE();
+        return count;
+    }
+    while (rxReorderTblPtr != (RxReorderTbl *) & priv->rx_reorder_tbl_ptr) {
+        ptbl->tid = (t_u16) rxReorderTblPtr->tid;
+        memcpy(ptbl->ta, rxReorderTblPtr->ta, MLAN_MAC_ADDR_LENGTH);
+        ptbl->start_win = rxReorderTblPtr->start_win;
+        ptbl->win_size = rxReorderTblPtr->win_size;
+        for (i = 0; i < rxReorderTblPtr->win_size; ++i) {
+            if (rxReorderTblPtr->rx_reorder_ptr[i])
+                ptbl->buffer[i] = MTRUE;
+            else
+                ptbl->buffer[i] = MFALSE;
+        }
+        rxReorderTblPtr = rxReorderTblPtr->pnext;
+        ptbl++;
+        count++;
+    }
+    LEAVE();
+    return count;
+}
+
+/** 
+ *  @brief Get transmit BA stream table
+ *   
+ *  @param priv         A pointer to mlan_private structure
+ *  @param buf          A pointer to tx_ba_stream_tbl structure
+ *  @return             number of ba stream table entry
+ */
+int
+wlan_get_txbastream_tbl(mlan_private * priv, tx_ba_stream_tbl * buf)
+{
+    TxBAStreamTbl *ptxtbl;
+    tx_ba_stream_tbl *ptbl = buf;
+    int count = 0;
+
+    ENTER();
+
+    if (!(ptxtbl = (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
+                                                    priv->adapter->callbacks.
+                                                    moal_spin_lock,
+                                                    priv->adapter->callbacks.
+                                                    moal_spin_unlock))) {
+        LEAVE();
+        return count;
+    }
+
+    while (ptxtbl != (TxBAStreamTbl *) & priv->tx_ba_stream_tbl_ptr) {
+        ptbl->tid = (t_u16) ptxtbl->tid;
+        PRINTM(MMSG, "tid=%d\n", ptbl->tid);
+        memcpy(ptbl->ra, ptxtbl->ra, MLAN_MAC_ADDR_LENGTH);
+        ptxtbl = ptxtbl->pnext;
+        ptbl++;
+        count++;
+    }
+
+    LEAVE();
+    return count;
+}
diff --git a/wlan_src/mlan/mlan_11n.h b/wlan_src/mlan/mlan_11n.h
new file mode 100755
index 0000000..91d7536
--- /dev/null
+++ b/wlan_src/mlan/mlan_11n.h
@@ -0,0 +1,273 @@
+/** @file mlan_11n.h
+ *
+ *  @brief Interface for the 802.11n mlan_11n module implemented in mlan_11n.c
+ *
+ *  Driver interface functions and type declarations for the 11n module
+ *    implemented in mlan_11n.c.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd.
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    12/01/2008: initial version
+********************************************************/
+
+#ifndef _MLAN_11N_H_
+#define _MLAN_11N_H_
+
+#include "mlan_11n_aggr.h"
+#include "mlan_11n_rxreorder.h"
+#include "mlan_wmm.h"
+
+/** Print the 802.11n device capability */
+void wlan_show_dot11ndevcap(pmlan_adapter pmadapter, t_u32 cap);
+/** Print the 802.11n device MCS */
+void wlan_show_devmcssupport(pmlan_adapter pmadapter, t_u8 support);
+/** Handle the command response of a delete block ack request */
+mlan_status wlan_ret_11n_delba(mlan_private * priv, HostCmd_DS_COMMAND * resp);
+/** Handle the command response of an add block ack request */
+mlan_status wlan_ret_11n_addba_req(mlan_private * priv,
+                                   HostCmd_DS_COMMAND * resp);
+/** Handle the command response of 11ncfg command */
+mlan_status wlan_ret_11n_cfg(IN pmlan_private pmpriv,
+                             IN HostCmd_DS_COMMAND * resp,
+                             IN mlan_ioctl_req * pioctl_buf);
+/** Prepare 11ncfg command */
+mlan_status wlan_cmd_11n_cfg(IN pmlan_private pmpriv,
+                             IN HostCmd_DS_COMMAND * cmd, IN t_u16 cmd_action,
+                             IN t_void * pdata_buf);
+/** Append the 802_11N tlv */
+int wlan_cmd_append_11n_tlv(IN mlan_private * pmpriv,
+                            IN BSSDescriptor_t * pbss_desc,
+                            OUT t_u8 ** ppbuffer);
+/** Reconfigure the tx buf size in firmware */
+void wlan_cfg_tx_buf(mlan_private * pmpriv, BSSDescriptor_t * pbss_desc);
+/** wlan fill cap info */
+void wlan_fill_cap_info(mlan_adapter * pmadapter,
+                        MrvlIETypes_HTCap_t * pht_cap);
+/** Miscellaneous configuration handler */
+mlan_status wlan_11n_cfg_ioctl(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req);
+/** Delete Tx BA stream table entry */
+void wlan_11n_delete_txbastream_tbl_entry(mlan_private * priv,
+                                          TxBAStreamTbl * ptx_tbl);
+/** Delete all Tx BA stream table entries */
+void wlan_11n_deleteall_txbastream_tbl(mlan_private * priv);
+/** Get Tx BA stream status */
+TxBAStreamTbl *wlan_11n_get_txbastream_status(mlan_private * priv,
+                                              baStatus_e ba_status);
+/** Get Tx BA stream table */
+TxBAStreamTbl *wlan_11n_get_txbastream_tbl(mlan_private * priv, int tid,
+                                           t_u8 * ra);
+/** Create Tx BA stream table */
+void wlan_11n_create_txbastream_tbl(mlan_private * priv, t_u8 * ra, int tid,
+                                    baStatus_e ba_status);
+/** Send ADD BA request */
+int wlan_send_addba(mlan_private * priv, int tid, t_u8 * peer_mac);
+/** Send DEL BA request */
+int wlan_send_delba(mlan_private * priv, int tid, t_u8 * peer_mac,
+                    int initiator);
+/** This function handles the command response of delete a block ack request*/
+void wlan_11n_delete_bastream(mlan_private * priv, t_u8 * del_ba);
+/** This function will resend addba request to all the peer in the TxBAStreamTbl */
+void wlan_11n_update_addba_request(mlan_private * priv);
+/** get rx reorder table */
+int wlan_get_rxreorder_tbl(mlan_private * priv, rx_reorder_tbl * buf);
+/** get tx ba stream table */
+int wlan_get_txbastream_tbl(mlan_private * priv, tx_ba_stream_tbl * buf);
+/** AMSDU Aggr control cmd resp */
+mlan_status wlan_ret_amsdu_aggr_ctrl(pmlan_private pmpriv,
+                                     HostCmd_DS_COMMAND * resp,
+                                     mlan_ioctl_req * pioctl_buf);
+/** reconfigure tx buf size */
+mlan_status wlan_cmd_recfg_tx_buf(mlan_private * priv,
+                                  HostCmd_DS_COMMAND * cmd,
+                                  int cmd_action, void *pdata_buf);
+/** AMSDU aggr control cmd */
+mlan_status wlan_cmd_amsdu_aggr_ctrl(mlan_private * priv,
+                                     HostCmd_DS_COMMAND * cmd,
+                                     int cmd_action, void *pdata_buf);
+
+/**
+ *  @brief This function checks whether current BA stream is high priority or not
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param tid	    TID
+ *
+ *  @return 	    MTRUE or MFALSE
+ */
+static INLINE t_u8
+wlan_is_cur_bastream_high_prio(mlan_private * priv, int tid)
+{
+    TxBAStreamTbl *ptx_tbl;
+
+    ENTER();
+
+    if (!
+        (ptx_tbl =
+         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
+                                          priv->adapter->callbacks.
+                                          moal_spin_lock,
+                                          priv->adapter->callbacks.
+                                          moal_spin_unlock)))
+        return MNULL;
+
+    while (ptx_tbl != (TxBAStreamTbl *) & priv->tx_ba_stream_tbl_ptr) {
+        if (priv->aggr_prio_tbl[tid].ampdu_user >
+            priv->aggr_prio_tbl[ptx_tbl->tid].ampdu_user) {
+            LEAVE();
+            return MTRUE;
+        }
+
+        ptx_tbl = ptx_tbl->pnext;
+    }
+
+    LEAVE();
+    return MFALSE;
+}
+
+/**
+ *  @brief This function checks whether AMPDU is allowed or not
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param ptr      A pointer to RA list table
+ *
+ *  @return 	    MTRUE or MFALSE
+ */
+static INLINE t_u8
+wlan_is_ampdu_allowed(mlan_private * priv, raListTbl * ptr)
+{
+    return ((priv->aggr_prio_tbl[wlan_get_tid(priv->adapter, ptr)].ampdu_ap
+             != BA_STREAM_NOT_ALLOWED) ? MTRUE : MFALSE);
+}
+
+/**
+ *  @brief This function checks whether AMSDU is allowed or not
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param ptr      A pointer to RA list table
+ *
+ *  @return 	    MTRUE or MFALSE
+ */
+static INLINE t_u8
+wlan_is_amsdu_allowed(mlan_private * priv, raListTbl * ptr)
+{
+    return ((priv->aggr_prio_tbl[wlan_get_tid(priv->adapter, ptr)].amsdu
+             != BA_STREAM_NOT_ALLOWED)
+            ? MTRUE : MFALSE);
+}
+
+/**
+ *  @brief This function checks whether a BA stream is available or not
+ *  
+ *  @param priv     A pointer to mlan_private
+ *
+ *  @return 	    MTRUE or MFALSE
+ */
+static INLINE t_u8
+wlan_is_bastream_avail(mlan_private * priv)
+{
+    mlan_private *pmpriv = MNULL;
+    t_u8 i = 0;
+    t_u32 bastream_num = 0;
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        pmpriv = priv->adapter->priv[i];
+        bastream_num +=
+            wlan_wmm_list_len(priv->adapter,
+                              (pmlan_list_head) & pmpriv->tx_ba_stream_tbl_ptr);
+    }
+    return ((bastream_num < MLAN_MAX_BASTREAM_SUPPORTED) ? MTRUE : MFALSE);
+}
+
+/**
+ *  @brief This function finds the stream to delete
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param ptr      A pointer to RA list table
+ *  @param ptid     A pointer to TID
+ *  @param ra       RA
+ *
+ *  @return 	    MTRUE or MFALSE
+ */
+static INLINE t_u8
+wlan_find_stream_to_delete(mlan_private * priv,
+                           raListTbl * ptr, int *ptid, t_u8 * ra)
+{
+    int tid;
+    t_u8 ret = MFALSE;
+    TxBAStreamTbl *ptx_tbl;
+
+    ENTER();
+    if (!
+        (ptx_tbl =
+         (TxBAStreamTbl *) util_peek_list(&priv->tx_ba_stream_tbl_ptr,
+                                          priv->adapter->callbacks.
+                                          moal_spin_lock,
+                                          priv->adapter->callbacks.
+                                          moal_spin_unlock))) {
+        LEAVE();
+        return ret;
+    }
+
+    tid = priv->aggr_prio_tbl[wlan_get_tid(priv->adapter, ptr)].ampdu_user;
+
+    while (ptx_tbl != (TxBAStreamTbl *) & priv->tx_ba_stream_tbl_ptr) {
+        if (tid > priv->aggr_prio_tbl[ptx_tbl->tid].ampdu_user) {
+            tid = priv->aggr_prio_tbl[ptx_tbl->tid].ampdu_user;
+            *ptid = ptx_tbl->tid;
+            memcpy(ra, ptx_tbl->ra, MLAN_MAC_ADDR_LENGTH);
+            ret = MTRUE;
+        }
+
+        ptx_tbl = ptx_tbl->pnext;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function checks whether BA stream is setup
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param ptr      A pointer to RA list table
+ *
+ *  @return 	    MTRUE or MFALSE
+ */
+static int INLINE
+wlan_is_bastream_setup(mlan_private * priv, raListTbl * ptr)
+{
+    TxBAStreamTbl *ptx_tbl;
+
+    ENTER();
+
+    if ((ptx_tbl = wlan_11n_get_txbastream_tbl(priv,
+                                               wlan_get_tid(priv->adapter, ptr),
+                                               ptr->ra))) {
+        LEAVE();
+        return IS_BASTREAM_SETUP(ptx_tbl) ? MTRUE : MFALSE;
+    }
+
+    LEAVE();
+    return MFALSE;
+}
+
+/**
+ *  @brief This function checks whether 11n is supported
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param ra       Address of the receiver STA
+ *
+ *  @return 	    MTRUE or MFALSE
+ */
+static int INLINE
+wlan_is_11n_enabled(mlan_private * priv, t_u8 * ra)
+{
+    int ret = MFALSE;
+    ENTER();
+    LEAVE();
+    return ret;
+}
+#endif /* !_MLAN_11N_H_ */
diff --git a/wlan_src/mlan/mlan_11n_aggr.c b/wlan_src/mlan/mlan_11n_aggr.c
new file mode 100755
index 0000000..794e622
--- /dev/null
+++ b/wlan_src/mlan/mlan_11n_aggr.c
@@ -0,0 +1,447 @@
+/** @file mlan_11n_aggr.c
+ *
+ *  @brief This file contains functions for 11n Aggregation.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    11/10/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_11n_aggr.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+    Local Variables
+********************************************************/
+
+/********************************************************
+    Global Variables
+********************************************************/
+
+/********************************************************
+    Local Functions
+********************************************************/
+
+/**
+ *  @brief Aggregate individual packets into one AMSDU packet
+ *
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param amsdu_buf A pointer to packet buffer
+ *  @param data      A pointer to aggregated data packet being formed
+ *  @param pkt_len   Length of current packet to aggregate
+ *  @param pad       Pad
+ *
+ *  @return         Final packet size
+ */
+static int
+wlan_11n_form_amsdu_pkt(pmlan_adapter pmadapter, t_u8 * amsdu_buf, t_u8 * data,
+                        int pkt_len, int *pad)
+{
+    int dt_offset, amsdu_buf_offset;
+    Rfc1042Hdr_t snap = {
+        0xaa,                   /* LLC DSAP */
+        0xaa,                   /* LLC SSAP */
+        0x03,                   /* LLC CTRL */
+        {0x00, 0x00, 0x00},     /* SNAP OUI */
+        0x0000                  /* SNAP type */
+            /* 
+             * This field will be overwritten
+             * later with ethertype
+             */
+    };
+
+    ENTER();
+
+    memcpy(amsdu_buf, data, (MLAN_MAC_ADDR_LENGTH) * 2);
+    dt_offset = amsdu_buf_offset = (MLAN_MAC_ADDR_LENGTH) * 2;
+
+    snap.snap_type = *(t_u16 *) (data + dt_offset);
+    dt_offset += sizeof(t_u16);
+    *(t_u16 *) (amsdu_buf + amsdu_buf_offset) = mlan_htons(pkt_len +
+                                                           LLC_SNAP_LEN -
+                                                           ((2 *
+                                                             MLAN_MAC_ADDR_LENGTH)
+                                                            + sizeof(t_u16)));
+    amsdu_buf_offset += sizeof(t_u16);
+    memcpy(amsdu_buf + amsdu_buf_offset, &snap, LLC_SNAP_LEN);
+    amsdu_buf_offset += LLC_SNAP_LEN;
+
+    memcpy(amsdu_buf + amsdu_buf_offset, data + dt_offset, pkt_len - dt_offset);
+    *pad = (((pkt_len + LLC_SNAP_LEN) & 3)) ?
+        (4 - (((pkt_len + LLC_SNAP_LEN)) & 3)) : 0;
+
+    LEAVE();
+    return (pkt_len + LLC_SNAP_LEN + *pad);
+}
+
+/**
+ *  @brief Add TxPD to AMSDU header
+ *
+ *  @param priv     A pointer to mlan_private structure
+ *  @param mbuf		Pointer to buffer where the TxPD will be formed 
+ *
+ *  @return		N/A
+ */
+static void
+wlan_11n_form_amsdu_txpd(mlan_private * priv, mlan_buffer * mbuf)
+{
+    TxPD *ptx_pd;
+    mlan_adapter *pmadapter = priv->adapter;
+    ENTER();
+
+    ptx_pd = (TxPD *) mbuf->pbuf;
+    memset(ptx_pd, 0, sizeof(TxPD));
+
+    /* 
+     * Original priority has been overwritten 
+     */
+    ptx_pd->priority = (t_u8) mbuf->priority;
+    ptx_pd->pkt_delay_2ms = wlan_wmm_compute_driver_packet_delay(priv, mbuf);
+    ptx_pd->bss_num = (t_u8) mbuf->bss_num;
+    if (pmadapter->ps_state != PS_STATE_AWAKE) {
+        if (MTRUE == wlan_check_last_packet_indication(priv)) {
+            pmadapter->tx_lock_flag = MTRUE;
+            ptx_pd->flags = MRVDRV_TxPD_POWER_MGMT_LAST_PACKET;
+        }
+    }
+    /* Always zero as the data is followed by TxPD */
+    ptx_pd->tx_pkt_offset = sizeof(TxPD);
+    ptx_pd->tx_pkt_type = PKT_TYPE_AMSDU;
+
+    if (ptx_pd->tx_control == 0)
+        /* TxCtrl set by user or default */
+        ptx_pd->tx_control = priv->pkt_tx_ctrl;
+
+    endian_convert_TxPD(ptx_pd);
+
+    LEAVE();
+}
+
+/**
+ *  @brief Update the TxPktLength field in TxPD after the complete AMSDU
+ *  packet is formed
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param mbuf     	TxPD buffer
+ *
+ *  @return		N/A
+ */
+static INLINE void
+wlan_11n_update_pktlen_amsdu_txpd(pmlan_adapter pmadapter, pmlan_buffer mbuf)
+{
+    TxPD *ptx_pd;
+
+    ENTER();
+
+    ptx_pd = (TxPD *) mbuf->pbuf;
+    ptx_pd->tx_pkt_length =
+        (t_u16) wlan_cpu_to_le16(mbuf->data_len - sizeof(TxPD));
+
+    LEAVE();
+}
+
+/**
+ *  @brief Get number of aggregated packets
+ *
+ *  @param data			A pointer to packet data
+ *  @param total_pkt_len	Total packet length
+ *
+ *  @return			Number of packets
+ */
+static int
+wlan_11n_get_num_aggrpkts(t_u8 * data, int total_pkt_len)
+{
+    int pkt_count = 0, pkt_len, pad;
+
+    while (total_pkt_len > 0) {
+        /* Length will be in network format, change it to host */
+        pkt_len = mlan_ntohs((*(t_u16 *) (data + (2 * MLAN_MAC_ADDR_LENGTH))));
+        pad = (((pkt_len + sizeof(Eth803Hdr_t)) & 3)) ?
+            (4 - ((pkt_len + sizeof(Eth803Hdr_t)) & 3)) : 0;
+        data += pkt_len + pad + sizeof(Eth803Hdr_t);
+        total_pkt_len -= pkt_len + pad + sizeof(Eth803Hdr_t);
+        ++pkt_count;
+    }
+
+    return pkt_count;
+}
+
+/********************************************************
+    Global Functions
+********************************************************/
+
+/**
+ *  @brief Deaggregate the received AMSDU packet 
+ *
+ *  @param priv		A pointer to mlan_private structure
+ *  @param pmbuf	A pointer to aggregated data packet
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+mlan_status
+wlan_11n_deaggregate_pkt(mlan_private * priv, pmlan_buffer pmbuf)
+{
+    t_u16 pkt_len;
+    int total_pkt_len;
+    t_u8 *data;
+    int pad;
+    mlan_status ret = MLAN_STATUS_FAILURE;
+    RxPacketHdr_t *prx_pkt;
+    mlan_buffer *daggr_mbuf;
+    mlan_adapter *pmadapter = priv->adapter;
+    t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] = { 0xaa, 0xaa, 0x03,
+        0x00, 0x00, 0x00
+    };
+
+    ENTER();
+
+    data = (t_u8 *) (pmbuf->pbuf + pmbuf->data_offset);
+    total_pkt_len = pmbuf->data_len;
+
+    /* Sanity test */
+    if (total_pkt_len > MLAN_RX_DATA_BUF_SIZE) {
+        PRINTM(MERROR, "Total packet length greater than tx buffer"
+               " size %d\n", total_pkt_len);
+        goto done;
+    }
+
+    pmbuf->use_count = wlan_11n_get_num_aggrpkts(data, total_pkt_len);
+
+    while (total_pkt_len > 0) {
+        prx_pkt = (RxPacketHdr_t *) data;
+        /* Length will be in network format, change it to host */
+        pkt_len = mlan_ntohs((*(t_u16 *) (data + (2 * MLAN_MAC_ADDR_LENGTH))));
+        if (pkt_len > total_pkt_len) {
+            PRINTM(MERROR, "Error in pkt_len %d %d\n", total_pkt_len, pkt_len);
+            break;
+        }
+
+        pad = (((pkt_len + sizeof(Eth803Hdr_t)) & 3)) ?
+            (4 - ((pkt_len + sizeof(Eth803Hdr_t)) & 3)) : 0;
+
+        total_pkt_len -= pkt_len + pad + sizeof(Eth803Hdr_t);
+
+        if (memcmp(&prx_pkt->rfc1042_hdr,
+                   rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) {
+            memmove(data + LLC_SNAP_LEN, data, (2 * MLAN_MAC_ADDR_LENGTH));
+            data += LLC_SNAP_LEN;
+            pkt_len += sizeof(Eth803Hdr_t) - LLC_SNAP_LEN;
+        } else {
+            *(t_u16 *) (data + (2 * MLAN_MAC_ADDR_LENGTH))
+                = (t_u16) 0;
+            pkt_len += sizeof(Eth803Hdr_t);
+        }
+
+        if ((pmadapter->callbacks.moal_malloc(sizeof(mlan_buffer),
+                                              (t_u8 **) & daggr_mbuf))) {
+            PRINTM(MERROR, "Error allocating daggr mlan_buffer\n");
+            return MLAN_STATUS_FAILURE;
+        }
+
+        memcpy(daggr_mbuf, pmbuf, sizeof(mlan_buffer));
+
+        daggr_mbuf->data_offset = 0;
+        daggr_mbuf->data_len = pkt_len;
+        daggr_mbuf->pbuf = data;
+        daggr_mbuf->pdesc = MNULL;
+        daggr_mbuf->pparent = pmbuf;
+        daggr_mbuf->priority = pmbuf->priority;
+        ret =
+            pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle,
+                                                  daggr_mbuf);
+
+        switch (ret) {
+        case MLAN_STATUS_PENDING:
+            break;
+        case MLAN_STATUS_FAILURE:
+            PRINTM(MERROR, "Deaggr, send to moal failed\n");
+        case MLAN_STATUS_SUCCESS:
+            wlan_recv_packet_complete(pmadapter, daggr_mbuf, ret);
+            break;
+        default:
+            break;
+        }
+
+        data += pkt_len + pad;
+    }
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Aggregate multiple packets into one single AMSDU packet
+ *
+ *  @param priv 	A pointer to mlan_private structure
+ *  @param pra_list	Pointer to the RA List table containing the pointers
+ *  			    to packets.
+ *  @param headroom	Any interface specific headroom that may be need. TxPD 
+ *  				will be formed leaving this headroom.
+ *  @param ptrindex	Pointer index
+ *
+ *  @return		Final packet size
+ */
+int
+wlan_11n_aggregate_pkt(mlan_private * priv, raListTbl * pra_list,
+                       int headroom, int ptrindex)
+{
+    int pkt_size = 0;
+    pmlan_adapter pmadapter = priv->adapter;
+    mlan_buffer *pmbuf_aggr, *pmbuf_src;
+    t_u8 *data;
+    int pad = 0;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u32 sec, usec;
+    mlan_tx_param tx_param;
+    ENTER();
+
+    PRINTM(MDAT_D, "Handling Aggr packet\n");
+
+    if ((pmbuf_src = (pmlan_buffer) util_peek_list(&pra_list->buf_head,
+                                                   pmadapter->callbacks.
+                                                   moal_spin_lock,
+                                                   pmadapter->callbacks.
+                                                   moal_spin_unlock))) {
+
+        if (!
+            (pmbuf_aggr =
+             wlan_alloc_mlan_buffer(&pmadapter->callbacks,
+                                    pmadapter->tx_buf_size))) {
+            PRINTM(MERROR, "Error allocating mlan_buffer\n");
+            return MLAN_STATUS_FAILURE;
+        }
+
+        data = pmbuf_aggr->pbuf + headroom;
+        memcpy(pmbuf_aggr, pmbuf_src, sizeof(mlan_buffer));
+
+        pmbuf_aggr->pbuf = data;
+        pmbuf_aggr->pdesc = MNULL;
+        pmbuf_aggr->data_offset = 0;
+
+        /* Form AMSDU */
+        wlan_11n_form_amsdu_txpd(priv, pmbuf_aggr);
+        pkt_size = sizeof(TxPD);
+    } else {
+        goto exit;
+    }
+
+    while (pmbuf_src && ((pkt_size + (pmbuf_src->data_len + LLC_SNAP_LEN)
+                          + headroom)
+                         <= pmadapter->tx_buf_size)) {
+
+        pmbuf_src = (pmlan_buffer)
+            util_dequeue_list(&pra_list->buf_head,
+                              pmadapter->callbacks.moal_spin_lock,
+                              pmadapter->callbacks.moal_spin_unlock);
+
+        pra_list->total_pkts_size -= pmbuf_src->data_len;
+
+        pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+        pkt_size += wlan_11n_form_amsdu_pkt(pmadapter,
+                                            (data + pkt_size),
+                                            pmbuf_src->pbuf +
+                                            pmbuf_src->data_offset,
+                                            pmbuf_src->data_len, &pad);
+
+        DBG_HEXDUMP(MDAT_D, "pmbuf_src", pmbuf_src, sizeof(mlan_buffer));
+        pmadapter->callbacks.moal_send_packet_complete(pmadapter->pmoal_handle,
+                                                       pmbuf_src,
+                                                       MLAN_STATUS_SUCCESS);
+
+        pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+
+        if (!wlan_is_ralist_valid(priv, pra_list, ptrindex)) {
+            pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+
+        pmbuf_src = (pmlan_buffer) util_peek_list(&pra_list->buf_head,
+                                                  pmadapter->callbacks.
+                                                  moal_spin_lock,
+                                                  pmadapter->callbacks.
+                                                  moal_spin_unlock);
+    }
+
+    pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+
+    /* Last AMSDU packet does not need padding */
+    pkt_size -= pad;
+    pmbuf_aggr->data_len = pkt_size;
+    wlan_11n_update_pktlen_amsdu_txpd(pmadapter, pmbuf_aggr);
+    pmbuf_aggr->data_len += headroom;
+    pmbuf_aggr->pbuf = data - headroom;
+    tx_param.next_pkt_len = ((pra_list->total_pkts_size) ?
+                             (((pra_list->total_pkts_size) >
+                               pmadapter->tx_buf_size) ? pmadapter->
+                              tx_buf_size : pra_list->total_pkts_size +
+                              LLC_SNAP_LEN + sizeof(TxPD)) : 0);
+    ret =
+        wlan_sdio_host_to_card(pmadapter, MLAN_TYPE_DATA, pmbuf_aggr,
+                               &tx_param);
+    switch (ret) {
+    case MLAN_STATUS_RESOURCE:
+        pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+
+        if (!wlan_is_ralist_valid(priv, pra_list, ptrindex)) {
+            pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+            wlan_write_data_complete(pmadapter, pmbuf_aggr,
+                                     MLAN_STATUS_FAILURE);
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+        util_enqueue_list_head(&pra_list->buf_head,
+                               (pmlan_linked_list) pmbuf_aggr,
+                               pmadapter->callbacks.moal_spin_lock,
+                               pmadapter->callbacks.moal_spin_unlock);
+
+        pra_list->total_pkts_size += pmbuf_aggr->data_len;
+
+        pmbuf_aggr->flags = MLAN_BUF_FLAG_REQUEUED_PKT;
+        pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+        PRINTM(MDATA, "MLAN_STATUS_RESOURCE is returned\n");
+        break;
+    case MLAN_STATUS_FAILURE:
+        pmadapter->data_sent = MFALSE;
+        PRINTM(MERROR, "Error: moal_write_data_async failed: 0x%X\n", ret);
+        pmadapter->dbg.num_tx_host_to_card_failure++;
+        wlan_write_data_complete(pmadapter, pmbuf_aggr, ret);
+        goto exit;
+    case MLAN_STATUS_PENDING:
+        pmadapter->data_sent = MFALSE;
+        break;
+    case MLAN_STATUS_SUCCESS:
+        wlan_write_data_complete(pmadapter, pmbuf_aggr, ret);
+        break;
+    default:
+        break;
+    }
+    if (ret != MLAN_STATUS_RESOURCE) {
+        pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+        if (wlan_is_ralist_valid(priv, pra_list, ptrindex)) {
+            priv->wmm.packets_out[ptrindex]++;
+            priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list;
+        }
+        pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur =
+            pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur->pnext;
+        pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+    }
+    pmadapter->callbacks.moal_get_system_time(&sec, &usec);
+    PRINTM(MDATA, "%lu.%lu : Data => FW\n", sec, usec);
+
+  exit:
+    LEAVE();
+    return (pkt_size + headroom);
+}
diff --git a/wlan_src/mlan/mlan_11n_aggr.h b/wlan_src/mlan/mlan_11n_aggr.h
new file mode 100755
index 0000000..197ce08
--- /dev/null
+++ b/wlan_src/mlan/mlan_11n_aggr.h
@@ -0,0 +1,27 @@
+/** @file mlan_11n_aggr.h
+ *
+ *  @brief This file contains related macros, enum, and struct
+ *  of 11n aggregation functionalities
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd.
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    11/10/2008: initial version
+********************************************************/
+
+#ifndef _MLAN_11N_AGGR_H_
+#define _MLAN_11N_AGGR_H_
+
+/** AMSDU packet type */
+#define PKT_TYPE_AMSDU	0xE6
+
+/** Aggregate 11N packets */
+mlan_status wlan_11n_deaggregate_pkt(pmlan_private priv, pmlan_buffer pmbuf);
+/** Deaggregate 11N packets */
+int wlan_11n_aggregate_pkt(mlan_private * priv, raListTbl * ptr,
+                           int headroom, int ptrindex);
+
+#endif /* !_MLAN_11N_AGGR_H_ */
diff --git a/wlan_src/mlan/mlan_11n_rxreorder.c b/wlan_src/mlan/mlan_11n_rxreorder.c
new file mode 100755
index 0000000..72c15b5
--- /dev/null
+++ b/wlan_src/mlan/mlan_11n_rxreorder.c
@@ -0,0 +1,788 @@
+/** @file mlan_11n_rxreorder.c
+ *
+ *  @brief This file contains the handling of RxReordering in wlan
+ *  driver.
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    11/10/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_11n_rxreorder.h"
+
+/********************************************************
+    Local Variables
+********************************************************/
+
+/********************************************************
+    Global Variables
+********************************************************/
+
+/********************************************************
+    Local Functions
+********************************************************/
+
+/**
+ *  @brief This function will process the rx packet and 
+ *  		forward it to kernel/upper layer
+ *  
+ *  @param priv    	A pointer to mlan_private
+ *  @param payload  A pointer to rx packet payload
+ *
+ *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_11n_dispatch_pkt(t_void * priv, t_void * payload)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_adapter pmadapter = ((pmlan_private) priv)->adapter;
+    ret = wlan_process_rx_packet(pmadapter, (pmlan_buffer) payload);
+    return ret;
+}
+
+/**
+ *  @brief This function dispatchs all the packets in the buffer.
+ *  		There could be holes in the buffer.
+ *    
+ *  @param priv    	        A pointer to mlan_private
+ *  @param rx_reor_tbl_ptr  A pointer to structure RxReorderTbl
+ *  @param start_win        Start window
+ *
+ *  @return 	   	        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_11n_dispatch_pkt_until_start_win(t_void * priv,
+                                      RxReorderTbl * rx_reor_tbl_ptr,
+                                      int start_win)
+{
+    int no_pkt_to_send, i, xchg;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    void *rx_tmp_ptr = MNULL;
+    mlan_private *pmpriv = (mlan_private *) priv;
+
+    ENTER();
+
+    no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ?
+        MIN((start_win - rx_reor_tbl_ptr->start_win),
+            rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size;
+
+    for (i = 0; i < no_pkt_to_send; ++i) {
+        pmpriv->adapter->callbacks.moal_spin_lock(pmpriv->rx_pkt_lock);
+        rx_tmp_ptr = MNULL;
+        if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
+            rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
+            rx_reor_tbl_ptr->rx_reorder_ptr[i] = MNULL;
+        }
+        pmpriv->adapter->callbacks.moal_spin_unlock(pmpriv->rx_pkt_lock);
+        if (rx_tmp_ptr)
+            wlan_11n_dispatch_pkt(priv, rx_tmp_ptr);
+    }
+
+    pmpriv->adapter->callbacks.moal_spin_lock(pmpriv->rx_pkt_lock);
+    /* 
+     * We don't have a circular buffer, hence use rotation to simulate
+     * circular buffer
+     */
+    xchg = rx_reor_tbl_ptr->win_size - no_pkt_to_send;
+    for (i = 0; i < xchg; ++i) {
+        rx_reor_tbl_ptr->rx_reorder_ptr[i] =
+            rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i];
+        rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = MNULL;
+    }
+
+    rx_reor_tbl_ptr->start_win = start_win;
+    pmpriv->adapter->callbacks.moal_spin_unlock(pmpriv->rx_pkt_lock);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function will display the rxReorder table
+ *      
+ *  @param pmadapter          A pointer to mlan_adapter structure
+ *  @param rx_reor_tbl_ptr    A pointer to structure RxReorderTbl
+ *
+ *  @return 	   	N/A
+ */
+static t_void
+wlan_11n_display_tbl_ptr(pmlan_adapter pmadapter,
+                         RxReorderTbl * rx_reor_tbl_ptr)
+{
+    ENTER();
+
+    DBG_HEXDUMP(MDAT_D, "Reorder ptr", rx_reor_tbl_ptr->rx_reorder_ptr,
+                rx_reor_tbl_ptr->win_size);
+
+    LEAVE();
+}
+
+/**
+ *  @brief This function will dispatch all packets sequentially 
+ *  		from start_win until a hole is found and adjust the 
+ *  		start_win appropriately
+ *
+ *  @param priv    	        A pointer to mlan_private
+ *  @param rx_reor_tbl_ptr  A pointer to structure RxReorderTbl
+ *
+ *  @return 	   	        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_11n_scan_and_dispatch(t_void * priv, RxReorderTbl * rx_reor_tbl_ptr)
+{
+    int i, j, xchg;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    void *rx_tmp_ptr = MNULL;
+    mlan_private *pmpriv = (mlan_private *) priv;
+
+    ENTER();
+
+    for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) {
+        pmpriv->adapter->callbacks.moal_spin_lock(pmpriv->rx_pkt_lock);
+        if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
+            pmpriv->adapter->callbacks.moal_spin_unlock(pmpriv->rx_pkt_lock);
+            break;
+        }
+        rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
+        rx_reor_tbl_ptr->rx_reorder_ptr[i] = MNULL;
+        pmpriv->adapter->callbacks.moal_spin_unlock(pmpriv->rx_pkt_lock);
+        wlan_11n_dispatch_pkt(priv, rx_tmp_ptr);
+    }
+
+    pmpriv->adapter->callbacks.moal_spin_lock(pmpriv->rx_pkt_lock);
+    /* 
+     * We don't have a circular buffer, hence use rotation to simulate
+     * circular buffer
+     */
+    if (i > 0) {
+        xchg = rx_reor_tbl_ptr->win_size - i;
+        for (j = 0; j < xchg; ++j) {
+            rx_reor_tbl_ptr->rx_reorder_ptr[j] =
+                rx_reor_tbl_ptr->rx_reorder_ptr[i + j];
+            rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = MNULL;
+        }
+    }
+    rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i)
+        & (MAX_TID_VALUE - 1);
+    pmpriv->adapter->callbacks.moal_spin_unlock(pmpriv->rx_pkt_lock);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function delete rxreorder table's entry 
+ *         	and free the memory
+ *
+ *  @param priv    	        A pointer to mlan_private
+ *  @param rx_reor_tbl_ptr  A pointer to structure RxReorderTbl
+ *
+ *  @return 	   	        N/A
+ */
+static t_void
+wlan_11n_delete_rxreorder_tbl_entry(mlan_private * priv,
+                                    RxReorderTbl * rx_reor_tbl_ptr)
+{
+    pmlan_adapter pmadapter = priv->adapter;
+
+    ENTER();
+
+    if (!rx_reor_tbl_ptr) {
+        LEAVE();
+        return;
+    }
+
+    wlan_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
+                                          (rx_reor_tbl_ptr->start_win +
+                                           rx_reor_tbl_ptr->win_size)
+                                          & (MAX_TID_VALUE - 1));
+
+    if (rx_reor_tbl_ptr->timer_context.timer) {
+        if (rx_reor_tbl_ptr->timer_context.timer_is_set)
+            priv->adapter->callbacks.moal_stop_timer(rx_reor_tbl_ptr->
+                                                     timer_context.timer);
+        priv->adapter->callbacks.moal_free_timer(rx_reor_tbl_ptr->
+                                                 timer_context.timer);
+    }
+
+    PRINTM(MDAT_D, "Delete rx_reor_tbl_ptr: %p\n", rx_reor_tbl_ptr);
+    util_unlink_list(&priv->rx_reorder_tbl_ptr,
+                     (pmlan_linked_list) rx_reor_tbl_ptr,
+                     pmadapter->callbacks.moal_spin_lock,
+                     pmadapter->callbacks.moal_spin_unlock);
+
+    pmadapter->callbacks.moal_mfree((t_u8 *) rx_reor_tbl_ptr->rx_reorder_ptr);
+    pmadapter->callbacks.moal_mfree((t_u8 *) rx_reor_tbl_ptr);
+
+    LEAVE();
+}
+
+/**
+ *  @brief This function will return the pointer to a entry in rx reordering 
+ *  		table which matches the give TA/TID pair
+ *  
+ *  @param priv    A pointer to mlan_private
+ *  @param ta      ta to find in reordering table
+ *  @param tid	   tid to find in reordering table
+ *
+ *  @return	   A pointer to structure RxReorderTbl
+ */
+RxReorderTbl *
+wlan_11n_get_rxreorder_tbl(mlan_private * priv, int tid, t_u8 * ta)
+{
+    RxReorderTbl *rx_reor_tbl_ptr;
+
+    ENTER();
+
+    if (!
+        (rx_reor_tbl_ptr =
+         (RxReorderTbl *) util_peek_list(&priv->rx_reorder_tbl_ptr,
+                                         priv->adapter->callbacks.
+                                         moal_spin_lock,
+                                         priv->adapter->callbacks.
+                                         moal_spin_unlock))) {
+        LEAVE();
+        return MNULL;
+    }
+
+    while (rx_reor_tbl_ptr != (RxReorderTbl *) & priv->rx_reorder_tbl_ptr) {
+        if ((!memcmp(rx_reor_tbl_ptr->ta, ta, MLAN_MAC_ADDR_LENGTH)) &&
+            (rx_reor_tbl_ptr->tid == tid)) {
+            LEAVE();
+            return rx_reor_tbl_ptr;
+        }
+
+        rx_reor_tbl_ptr = rx_reor_tbl_ptr->pnext;
+    }
+
+    LEAVE();
+    return MNULL;
+}
+
+static int
+wlan_11n_find_last_seqnum(RxReorderTbl * rxReorderTblPtr)
+{
+    int i;
+
+    for (i = (rxReorderTblPtr->win_size - 1); i >= 0; --i) {
+        if (rxReorderTblPtr->rx_reorder_ptr[i]) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+static t_void
+wlan_flush_data(t_void * context)
+{
+    reorder_tmr_cnxt_t *reorder_cnxt = (reorder_tmr_cnxt_t *) context;
+    int startWin;
+
+    reorder_cnxt->timer_is_set = MFALSE;
+    wlan_11n_display_tbl_ptr(reorder_cnxt->priv->adapter, reorder_cnxt->ptr);
+
+    if ((startWin = wlan_11n_find_last_seqnum(reorder_cnxt->ptr)) >= 0) {
+        PRINTM(MINFO, "Flush data %d\n", startWin);
+        wlan_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv,
+                                              reorder_cnxt->ptr,
+                                              ((reorder_cnxt->ptr->start_win +
+                                                startWin + 1) & (MAX_TID_VALUE -
+                                                                 1)));
+    }
+
+    wlan_11n_display_tbl_ptr(reorder_cnxt->priv->adapter, reorder_cnxt->ptr);
+}
+
+/**
+ *  @brief This function will create a entry in rx reordering table for the 
+ *  		given ta/tid and will initialize it with seq_num, win_size
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param ta       ta to find in reordering table
+ *  @param tid	    tid to find in reordering table
+ *  @param win_size win_size for the give ta/tid pair.
+ *  @param seq_num  Starting sequence number for current entry.
+ *
+ *  @return 	    N/A
+ */
+t_void
+wlan_11n_create_rxreorder_tbl(mlan_private * priv, t_u8 * ta, int tid,
+                              int win_size, int seq_num)
+{
+    int i;
+    pmlan_adapter pmadapter = priv->adapter;
+    RxReorderTbl *rx_reor_tbl_ptr, *new_node;
+
+    ENTER();
+
+    /* 
+     * If we get a TID, ta pair which is already present dispatch all the
+     * the packets and move the window size until the ssn
+     */
+    if ((rx_reor_tbl_ptr = wlan_11n_get_rxreorder_tbl(priv, tid, ta))) {
+        wlan_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, seq_num);
+    } else {
+        PRINTM(MDAT_D, "%s: seq_num %d, tid %d, ta %02x:%02x:%02x:%02x:"
+               "%02x:%02x, win_size %d\n", __FUNCTION__,
+               seq_num, tid, ta[0], ta[1], ta[2], ta[3],
+               ta[4], ta[5], win_size);
+        if (pmadapter->callbacks.moal_malloc(sizeof(RxReorderTbl),
+                                             (t_u8 **) & new_node)) {
+            PRINTM(MERROR, "Rx reorder memory allocation failed\n");
+            return;
+        }
+
+        util_init_list((pmlan_linked_list) new_node);
+        new_node->tid = tid;
+        memcpy(new_node->ta, ta, MLAN_MAC_ADDR_LENGTH);
+        new_node->start_win = seq_num;
+        new_node->win_size = win_size;
+
+        if (pmadapter->callbacks.moal_malloc(sizeof(t_void *) * win_size,
+                                             (t_u8 **) & new_node->
+                                             rx_reorder_ptr)) {
+            PRINTM(MERROR, "Rx reorder table memory allocation" "failed\n");
+            pmadapter->callbacks.moal_mfree((t_u8 *) new_node);
+            return;
+        }
+
+        PRINTM(MDAT_D, "Create ReorderPtr: %p\n", new_node);
+        new_node->timer_context.ptr = new_node;
+        new_node->timer_context.priv = priv;
+        new_node->timer_context.timer_is_set = MFALSE;
+
+        pmadapter->callbacks.moal_init_timer(&new_node->timer_context.
+                                             timer, wlan_flush_data,
+                                             &new_node->timer_context);
+
+        for (i = 0; i < win_size; ++i)
+            new_node->rx_reorder_ptr[i] = MNULL;
+
+        util_enqueue_list_tail(&priv->rx_reorder_tbl_ptr,
+                               (pmlan_linked_list) new_node,
+                               pmadapter->callbacks.moal_spin_lock,
+                               pmadapter->callbacks.moal_spin_unlock);
+    }
+
+    LEAVE();
+}
+
+/********************************************************
+    Global Functions
+********************************************************/
+
+/** 
+  *  @brief This function prepares command for adding a block ack
+  *  		request.
+  *  
+  *  @param priv        A pointer to mlan_private structure
+  *  @param cmd         A pointer to HostCmd_DS_COMMAND structure
+  *  @param pdata_buf   A pointer to data buffer
+  *
+  *  @return            MLAN_STATUS_SUCCESS
+  */
+mlan_status
+wlan_cmd_11n_addba_req(mlan_private * priv,
+                       HostCmd_DS_COMMAND * cmd, t_void * pdata_buf)
+{
+    HostCmd_DS_11N_ADDBA_REQ *padd_ba_req = (HostCmd_DS_11N_ADDBA_REQ *)
+        & cmd->params.add_ba_req;
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_11N_ADDBA_REQ);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_11N_ADDBA_REQ) + S_DS_GEN);
+
+    memcpy(padd_ba_req, pdata_buf, sizeof(HostCmd_DS_11N_ADDBA_REQ));
+    padd_ba_req->block_ack_param_set =
+        wlan_cpu_to_le16(padd_ba_req->block_ack_param_set);
+    padd_ba_req->block_ack_tmo = wlan_cpu_to_le16(padd_ba_req->block_ack_tmo);
+    padd_ba_req->ssn = wlan_cpu_to_le16(padd_ba_req->ssn);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+  *  @brief This function prepares command for adding a block ack
+  *  		response.
+  *  
+  *  @param priv        A pointer to mlan_private structure
+  *  @param cmd         A pointer to HostCmd_DS_COMMAND structure
+  *  @param pdata_buf   A pointer to data buffer
+  *
+  *  @return            MLAN_STATUS_SUCCESS
+  */
+mlan_status
+wlan_cmd_11n_addba_rspgen(mlan_private * priv,
+                          HostCmd_DS_COMMAND * cmd, void *pdata_buf)
+{
+    HostCmd_DS_11N_ADDBA_RSP *padd_ba_rsp = (HostCmd_DS_11N_ADDBA_RSP *)
+        & cmd->params.add_ba_rsp;
+    HostCmd_DS_11N_ADDBA_REQ *pevt_addba_req =
+        (HostCmd_DS_11N_ADDBA_REQ *) pdata_buf;
+    t_u8 tid;
+
+    ENTER();
+
+    pevt_addba_req->block_ack_param_set =
+        wlan_le16_to_cpu(pevt_addba_req->block_ack_param_set);
+    pevt_addba_req->block_ack_tmo =
+        wlan_le16_to_cpu(pevt_addba_req->block_ack_tmo);
+    pevt_addba_req->ssn = wlan_le16_to_cpu(pevt_addba_req->ssn);
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_11N_ADDBA_RSP) + S_DS_GEN);
+
+    memcpy(padd_ba_rsp->peer_mac_addr, pevt_addba_req->peer_mac_addr,
+           MLAN_MAC_ADDR_LENGTH);
+    padd_ba_rsp->dialog_token = pevt_addba_req->dialog_token;
+    padd_ba_rsp->block_ack_tmo =
+        wlan_cpu_to_le16(pevt_addba_req->block_ack_tmo);
+    padd_ba_rsp->ssn = wlan_cpu_to_le16(pevt_addba_req->ssn);
+
+    padd_ba_rsp->block_ack_param_set = pevt_addba_req->block_ack_param_set;
+    tid = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_TID_MASK)
+        >> BLOCKACKPARAM_TID_POS;
+    padd_ba_rsp->status_code = wlan_cpu_to_le16(priv->addba_reject[tid]);
+    padd_ba_rsp->block_ack_param_set &= ~BLOCKACKPARAM_WINSIZE_MASK;
+    /* We donot support AMSDU inside AMPDU, hence reset the bit */
+    padd_ba_rsp->block_ack_param_set &= ~BLOCKACKPARAM_AMSDU_SUPP_MASK;
+    padd_ba_rsp->block_ack_param_set |= (priv->add_ba_param.rx_win_size <<
+                                         BLOCKACKPARAM_WINSIZE_POS);
+    padd_ba_rsp->block_ack_param_set =
+        wlan_cpu_to_le16(padd_ba_rsp->block_ack_param_set);
+    padd_ba_rsp->block_ack_tmo =
+        (t_u16) wlan_cpu_to_le16(priv->add_ba_param.timeout);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+  *  @brief This function prepares command for deleting a block ack
+  *  		request.
+  *  
+  *  @param priv       A pointer to mlan_private structure
+  *  @param cmd        A pointer to HostCmd_DS_COMMAND structure
+  *  @param pdata_buf  A pointer to data buffer
+  *
+  *  @return           MLAN_STATUS_SUCCESS
+  */
+mlan_status
+wlan_cmd_11n_delba(mlan_private * priv,
+                   HostCmd_DS_COMMAND * cmd, void *pdata_buf)
+{
+    HostCmd_DS_11N_DELBA *pdel_ba = (HostCmd_DS_11N_DELBA *)
+        & cmd->params.del_ba;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_11N_DELBA);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_11N_DELBA) + S_DS_GEN);
+
+    memcpy(pdel_ba, pdata_buf, sizeof(HostCmd_DS_11N_DELBA));
+    pdel_ba->del_ba_param_set = wlan_cpu_to_le16(pdel_ba->del_ba_param_set);
+    pdel_ba->reason_code = wlan_cpu_to_le16(pdel_ba->reason_code);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function will identify if RxReodering is needed for the packet
+ *  		and will do the reordering if required before sending it to kernel
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param seq_num  Seqence number of the current packet
+ *  @param tid	    Tid of the current packet
+ *  @param ta	    Transmiter address of the current packet
+ *  @param pkt_type Packetype for the current packet (to identify if its a BAR)
+ *  @param payload  Pointer to the payload
+ *
+ *  @return 	    MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+mlan_11n_rxreorder_pkt(void *priv, t_u16 seq_num, t_u16 tid,
+                       t_u8 * ta, t_u8 pkt_type, void *payload)
+{
+    RxReorderTbl *rx_reor_tbl_ptr;
+    int start_win, end_win, win_size;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_adapter pmadapter = ((mlan_private *) priv)->adapter;
+
+    ENTER();
+
+    if (!
+        (rx_reor_tbl_ptr =
+         wlan_11n_get_rxreorder_tbl((mlan_private *) priv, tid, ta))) {
+        LEAVE();
+        if (pkt_type == PKT_TYPE_BAR)
+            return ret;
+        else {
+            wlan_11n_dispatch_pkt(priv, payload);
+            return ret;
+        }
+    } else {
+        if (pkt_type == PKT_TYPE_BAR)
+            PRINTM(MDAT_D, "BAR ");
+
+        start_win = rx_reor_tbl_ptr->start_win;
+        win_size = rx_reor_tbl_ptr->win_size;
+        end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
+        if (rx_reor_tbl_ptr->timer_context.timer_is_set)
+            pmadapter->callbacks.moal_stop_timer(rx_reor_tbl_ptr->timer_context.
+                                                 timer);
+        pmadapter->callbacks.moal_start_timer(rx_reor_tbl_ptr->timer_context.
+                                              timer, MFALSE,
+                                              MIN_FLUSH_TIMER_MS * win_size);
+        rx_reor_tbl_ptr->timer_context.timer_is_set = MTRUE;
+
+        PRINTM(MDAT_D, "TID %d, TA %02x:%02x:%02x:%02x:%02x:%02x\n",
+               tid, ta[0], ta[1], ta[2], ta[3], ta[4], ta[5]);
+        PRINTM(MDAT_D, "1:seq_num %d start_win %d win_size %d end_win %d\n",
+               seq_num, start_win, win_size, end_win);
+        /* 
+         * If seq_num is less then starting win then ignore and drop the
+         * packet
+         */
+        if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {     /* Wrap */
+            if (seq_num >= ((start_win + (TWOPOW11)) &
+                            (MAX_TID_VALUE - 1)) && (seq_num < start_win)) {
+                LEAVE();
+                return MLAN_STATUS_FAILURE;
+            }
+        } else if ((seq_num < start_win) ||
+                   (seq_num > (start_win + (TWOPOW11)))) {
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+
+        /* 
+         * If this packet is a BAR we adjust seq_num as
+         * WinStart = seq_num
+         */
+        if (pkt_type == PKT_TYPE_BAR)
+            seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
+
+        PRINTM(MDAT_D, "2:seq_num %d start_win %d win_size %d end_win %d\n",
+               seq_num, start_win, win_size, end_win);
+
+        if (((end_win < start_win) && (seq_num < (TWOPOW11 -
+                                                  (MAX_TID_VALUE - start_win)))
+             && (seq_num > end_win))
+            || ((end_win > start_win) &&
+                ((seq_num > end_win) || (seq_num < start_win)))) {
+            end_win = seq_num;
+            if (((seq_num - win_size) + 1) >= 0)
+                start_win = (end_win - win_size) + 1;
+            else
+                start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1;
+            if ((ret = wlan_11n_dispatch_pkt_until_start_win(priv,
+                                                             rx_reor_tbl_ptr,
+                                                             start_win))) {
+                LEAVE();
+                return ret;
+            }
+        }
+
+        PRINTM(MDAT_D, "3:seq_num %d start_win %d win_size %d"
+               " end_win %d\n", seq_num, start_win, win_size, end_win);
+        if (pkt_type != PKT_TYPE_BAR) {
+            if (seq_num >= start_win)
+                rx_reor_tbl_ptr->rx_reorder_ptr[seq_num - start_win] = payload;
+            else                /* Wrap condition */
+                rx_reor_tbl_ptr->rx_reorder_ptr[(seq_num
+                                                 + (MAX_TID_VALUE)) -
+                                                start_win] = payload;
+        }
+
+        wlan_11n_display_tbl_ptr(pmadapter, rx_reor_tbl_ptr);
+
+        /* 
+         * Dispatch all packets sequentially from start_win until a
+         * hole is found and adjust the start_win appropriately
+         */
+        ret = wlan_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr);
+
+        wlan_11n_display_tbl_ptr(pmadapter, rx_reor_tbl_ptr);
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function will delete an entry for a given tid/ta pair. tid/ta
+ *  		are taken from delba_event body
+ *  
+ *  @param priv    	    A pointer to mlan_private
+ *  @param tid		    tid to send delba
+ *  @param peer_mac	    MAC address to send delba
+ *  @param type 	    TYPE_DELBA_SENT	or TYPE_DELBA_RECEIVE	
+ *  @param initiator    MTRUE if we are initiator of ADDBA, MFALSE otherwise
+ *
+ *  @return 	   	    N/A
+ */
+void
+mlan_11n_delete_bastream_tbl(mlan_private * priv, int tid,
+                             t_u8 * peer_mac, t_u8 type, int initiator)
+{
+    RxReorderTbl *rx_reor_tbl_ptr;
+    TxBAStreamTbl *ptxtbl;
+    t_u8 cleanup_rx_reorder_tbl;
+
+    ENTER();
+
+    if (type == TYPE_DELBA_RECEIVE)
+        cleanup_rx_reorder_tbl = (initiator) ? MTRUE : MFALSE;
+    else
+        cleanup_rx_reorder_tbl = (initiator) ? MFALSE : MTRUE;
+
+    PRINTM(MEVENT, "DELBA: %02x:%02x:%02x:%02x:%02x:%02x tid=%d,"
+           "initiator=%d\n", peer_mac[0],
+           peer_mac[1], peer_mac[2],
+           peer_mac[3], peer_mac[4], peer_mac[5], tid, initiator);
+
+    if (cleanup_rx_reorder_tbl) {
+        if (!(rx_reor_tbl_ptr = wlan_11n_get_rxreorder_tbl(priv, tid,
+                                                           peer_mac))) {
+            PRINTM(MWARN, "TID, TA not found in table!\n");
+            LEAVE();
+            return;
+        }
+        wlan_11n_delete_rxreorder_tbl_entry(priv, rx_reor_tbl_ptr);
+    } else {
+        if (!(ptxtbl = wlan_11n_get_txbastream_tbl(priv, tid, peer_mac))) {
+            PRINTM(MWARN, "TID, RA not found in table!\n");
+            LEAVE();
+            return;
+        }
+
+        wlan_11n_delete_txbastream_tbl_entry(priv, ptxtbl);
+    }
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function handles the command response of
+ *  		a block ack response
+ *  
+ *  @param priv    A pointer to mlan_private structure
+ *  @param resp    A pointer to HostCmd_DS_COMMAND
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_11n_addba_resp(mlan_private * priv, HostCmd_DS_COMMAND * resp)
+{
+    HostCmd_DS_11N_ADDBA_RSP *padd_ba_rsp = (HostCmd_DS_11N_ADDBA_RSP *)
+        & resp->params.add_ba_rsp;
+    int tid, win_size;
+
+    ENTER();
+
+    padd_ba_rsp->status_code = wlan_le16_to_cpu(padd_ba_rsp->status_code);
+
+    tid = (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_TID_MASK)
+        >> BLOCKACKPARAM_TID_POS;
+    /* Check if we had rejected the ADDBA, if yes then do not create the stream */
+    if (padd_ba_rsp->status_code == BA_RESULT_SUCCESS) {
+        padd_ba_rsp->block_ack_param_set =
+            wlan_le16_to_cpu(padd_ba_rsp->block_ack_param_set);
+        padd_ba_rsp->block_ack_tmo =
+            wlan_le16_to_cpu(padd_ba_rsp->block_ack_tmo);
+        padd_ba_rsp->ssn = wlan_le16_to_cpu(padd_ba_rsp->ssn);
+
+        win_size =
+            (padd_ba_rsp->block_ack_param_set & BLOCKACKPARAM_WINSIZE_MASK)
+            >> BLOCKACKPARAM_WINSIZE_POS;
+
+        wlan_11n_create_rxreorder_tbl(priv, padd_ba_rsp->peer_mac_addr, tid,
+                                      win_size, padd_ba_rsp->ssn);
+
+        PRINTM(MCMND, "ADDBA RSP: %02x:%02x:%02x:%02x:%02x:%02x tid=%d\n",
+               padd_ba_rsp->peer_mac_addr[0], padd_ba_rsp->peer_mac_addr[1],
+               padd_ba_rsp->peer_mac_addr[2], padd_ba_rsp->peer_mac_addr[3],
+               padd_ba_rsp->peer_mac_addr[4], padd_ba_rsp->peer_mac_addr[5],
+               tid);
+    } else {
+        PRINTM(MERROR,
+               "ADDBA RSP: Failed(%02x:%02x:%02x:%02x:%02x:%02x tid=%d)\n",
+               padd_ba_rsp->peer_mac_addr[0], padd_ba_rsp->peer_mac_addr[1],
+               padd_ba_rsp->peer_mac_addr[2], padd_ba_rsp->peer_mac_addr[3],
+               padd_ba_rsp->peer_mac_addr[4], padd_ba_rsp->peer_mac_addr[5],
+               tid);
+
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles ba_stream_timeout event
+ *  
+ *  @param priv    	A pointer to mlan_private
+ *  @param event    A pointer to structure HostCmd_DS_11N_BATIMEOUT
+ *
+ *  @return 	   	N/A
+ */
+void
+wlan_11n_ba_stream_timeout(mlan_private * priv,
+                           HostCmd_DS_11N_BATIMEOUT * event)
+{
+    HostCmd_DS_11N_DELBA delba;
+
+    ENTER();
+
+    DBG_HEXDUMP(MCMD_D, "Event:", (t_u8 *) event, 20);
+
+    memset(&delba, 0, sizeof(HostCmd_DS_11N_DELBA));
+    memcpy(delba.peer_mac_addr, event->peer_mac_addr, MLAN_MAC_ADDR_LENGTH);
+
+    delba.del_ba_param_set |= (t_u16) event->tid << DELBA_TID_POS;
+    delba.del_ba_param_set |= (t_u16) event->origninator << DELBA_INITIATOR_POS;
+    delba.reason_code = REASON_CODE_STA_TIMEOUT;
+    wlan_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, MNULL, &delba);
+
+    LEAVE();
+    return;
+}
+
+/**
+ *  @brief This function cleans up reorder tbl
+ *  
+ *  @param priv    	A pointer to mlan_private
+ *
+ *  @return 	   	N/A
+ */
+void
+wlan_11n_cleanup_reorder_tbl(mlan_private * priv)
+{
+    RxReorderTbl *del_tbl_ptr;
+
+    ENTER();
+
+    while ((del_tbl_ptr = (RxReorderTbl *)
+            util_peek_list(&priv->rx_reorder_tbl_ptr,
+                           priv->adapter->callbacks.moal_spin_lock,
+                           priv->adapter->callbacks.moal_spin_unlock))) {
+        wlan_11n_delete_rxreorder_tbl_entry(priv, del_tbl_ptr);
+    }
+
+    util_init_list((pmlan_linked_list) & priv->rx_reorder_tbl_ptr);
+
+    LEAVE();
+}
diff --git a/wlan_src/mlan/mlan_11n_rxreorder.h b/wlan_src/mlan/mlan_11n_rxreorder.h
new file mode 100755
index 0000000..47ea16a
--- /dev/null
+++ b/wlan_src/mlan/mlan_11n_rxreorder.h
@@ -0,0 +1,78 @@
+/** @file mlan_11n_rxreorder.h
+ *
+ *  @brief This file contains related macros, enum, and struct
+ *  of 11n RxReordering functionalities
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    11/10/2008: initial version
+********************************************************/
+
+#ifndef _MLAN_11N_RXREORDER_H_
+#define _MLAN_11N_RXREORDER_H_
+
+/** Rx packet type for BAR */
+#define PKT_TYPE_BAR 0xE7
+/** Max value a TID can take = 2^12 = 4096 */
+#define MAX_TID_VALUE			(2 << 11)
+/** 2^11 = 2048 */
+#define TWOPOW11			(2 << 10)
+
+/** Tid Mask used for extracting TID from BlockAckParamSet */
+#define BLOCKACKPARAM_TID_MASK		0x3C
+/** Tid position in BlockAckParamSet */
+#define BLOCKACKPARAM_TID_POS		2
+/** WinSize Mask used for extracting WinSize from BlockAckParamSet */
+#define BLOCKACKPARAM_WINSIZE_MASK	0xffc0
+/** WinSize Mask used for extracting WinSize from BlockAckParamSet */
+#define BLOCKACKPARAM_AMSDU_SUPP_MASK	0x1
+/** WinSize position in BlockAckParamSet */
+#define BLOCKACKPARAM_WINSIZE_POS	6
+/** Position of TID in DelBA Param set */
+#define DELBA_TID_POS			12
+/** Position of INITIATOR in DelBA Param set */
+#define DELBA_INITIATOR_POS		11
+/** Reason code: Requested from peer STA as it does not want to use the mechanism */
+#define REASON_CODE_STA_DONT_WANT	37
+/** Reason code: Requested from peer STA due to timeout*/
+#define REASON_CODE_STA_TIMEOUT		39
+/** Type: send delba command */
+#define TYPE_DELBA_SENT			1
+/** Type: recieve delba command */
+#define TYPE_DELBA_RECEIVE		2
+/** Set Initiator Bit */
+#define DELBA_INITIATOR(paramset)	(paramset = (paramset | (1 << 11)))
+/** Reset Initiator Bit for recipient */
+#define DELBA_RECIPIENT(paramset)	(paramset = (paramset & ~(1 << 11)))
+/** Immediate block ack */
+#define IMMEDIATE_BLOCK_ACK		0x2
+
+/** ADDBA response status : Reject */
+#define ADDBA_RSP_STATUS_REJECT 1
+/** ADDBA response status : Accept */
+#define ADDBA_RSP_STATUS_ACCEPT 0
+
+mlan_status mlan_11n_rxreorder_pkt(void *priv, t_u16 seqNum, t_u16 tid,
+                                   t_u8 * ta, t_u8 pkttype, void *payload);
+void mlan_11n_delete_bastream_tbl(mlan_private * priv, int Tid,
+                                  t_u8 * PeerMACAddr, t_u8 type, int initiator);
+void wlan_11n_ba_stream_timeout(mlan_private * priv,
+                                HostCmd_DS_11N_BATIMEOUT * event);
+mlan_status wlan_ret_11n_addba_resp(mlan_private * priv,
+                                    HostCmd_DS_COMMAND * resp);
+mlan_status wlan_cmd_11n_delba(mlan_private * priv, HostCmd_DS_COMMAND * cmd,
+                               void *pdata_buf);
+mlan_status wlan_cmd_11n_addba_rspgen(mlan_private * priv,
+                                      HostCmd_DS_COMMAND * cmd,
+                                      void *pdata_buf);
+mlan_status wlan_cmd_11n_addba_req(mlan_private * priv,
+                                   HostCmd_DS_COMMAND * cmd, void *pdata_buf);
+void wlan_11n_cleanup_reorder_tbl(mlan_private * priv);
+RxReorderTbl *wlan_11n_get_rxreorder_tbl(mlan_private * priv, int tid,
+                                         t_u8 * ta);
+
+#endif /* _MLAN_11N_RXREORDER_H_ */
diff --git a/wlan_src/mlan/mlan_cfp.c b/wlan_src/mlan/mlan_cfp.c
new file mode 100755
index 0000000..a41d932
--- /dev/null
+++ b/wlan_src/mlan/mlan_cfp.c
@@ -0,0 +1,960 @@
+/**
+ * @file mlan_cfp.c
+ *
+ *  @brief This file contains WLAN client mode channel, frequence and power
+ *  related code
+ *
+ *  Copyright (C) 2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ *   
+ */
+
+/*************************************************************
+Change Log:
+    04/16/2009: initial version
+************************************************************/
+
+#include "mlan.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_join.h"
+#include "mlan_main.h"
+
+/********************************************************
+    Local Variables
+********************************************************/
+
+/** 100mW */
+#define WLAN_TX_PWR_DEFAULT     20
+/** 100mW */
+#define WLAN_TX_PWR_US_DEFAULT      20
+/** 50mW */
+#define WLAN_TX_PWR_JP_DEFAULT      16
+/** 100mW */
+#define WLAN_TX_PWR_FR_100MW        20
+/** 10mW */
+#define WLAN_TX_PWR_FR_10MW         10
+/** 100mW */
+#define WLAN_TX_PWR_EMEA_DEFAULT    20
+
+/* Format { Channel, Frequency (MHz), MaxTxPower } */
+/** Band: 'B/G', Region: USA FCC/Canada IC */
+static chan_freq_power_t channel_freq_power_US_BG[] = {
+    {1, 2412, WLAN_TX_PWR_US_DEFAULT},
+    {2, 2417, WLAN_TX_PWR_US_DEFAULT},
+    {3, 2422, WLAN_TX_PWR_US_DEFAULT},
+    {4, 2427, WLAN_TX_PWR_US_DEFAULT},
+    {5, 2432, WLAN_TX_PWR_US_DEFAULT},
+    {6, 2437, WLAN_TX_PWR_US_DEFAULT},
+    {7, 2442, WLAN_TX_PWR_US_DEFAULT},
+    {8, 2447, WLAN_TX_PWR_US_DEFAULT},
+    {9, 2452, WLAN_TX_PWR_US_DEFAULT},
+    {10, 2457, WLAN_TX_PWR_US_DEFAULT},
+    {11, 2462, WLAN_TX_PWR_US_DEFAULT}
+};
+
+/** Band: 'B/G', Region: Europe ETSI */
+static chan_freq_power_t channel_freq_power_EU_BG[] = {
+    {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT},
+    {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT},
+    {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT},
+    {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT},
+    {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT},
+    {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT},
+    {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT},
+    {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT},
+    {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT},
+    {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT},
+    {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT},
+    {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT},
+    {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT}
+};
+
+/** Band: 'B/G', Region: France */
+static chan_freq_power_t channel_freq_power_FR_BG[] = {
+    {1, 2412, WLAN_TX_PWR_FR_100MW},
+    {2, 2417, WLAN_TX_PWR_FR_100MW},
+    {3, 2422, WLAN_TX_PWR_FR_100MW},
+    {4, 2427, WLAN_TX_PWR_FR_100MW},
+    {5, 2432, WLAN_TX_PWR_FR_100MW},
+    {6, 2437, WLAN_TX_PWR_FR_100MW},
+    {7, 2442, WLAN_TX_PWR_FR_100MW},
+    {8, 2447, WLAN_TX_PWR_FR_100MW},
+    {9, 2452, WLAN_TX_PWR_FR_100MW},
+    {10, 2457, WLAN_TX_PWR_FR_10MW},
+    {11, 2462, WLAN_TX_PWR_FR_10MW},
+    {12, 2467, WLAN_TX_PWR_FR_10MW},
+    {13, 2472, WLAN_TX_PWR_FR_10MW}
+};
+
+/** Band: 'B/G', Region: Japan */
+static chan_freq_power_t channel_freq_power_JPN41_BG[] = {
+    {1, 2412, WLAN_TX_PWR_JP_DEFAULT},
+    {2, 2417, WLAN_TX_PWR_JP_DEFAULT},
+    {3, 2422, WLAN_TX_PWR_JP_DEFAULT},
+    {4, 2427, WLAN_TX_PWR_JP_DEFAULT},
+    {5, 2432, WLAN_TX_PWR_JP_DEFAULT},
+    {6, 2437, WLAN_TX_PWR_JP_DEFAULT},
+    {7, 2442, WLAN_TX_PWR_JP_DEFAULT},
+    {8, 2447, WLAN_TX_PWR_JP_DEFAULT},
+    {9, 2452, WLAN_TX_PWR_JP_DEFAULT},
+    {10, 2457, WLAN_TX_PWR_JP_DEFAULT},
+    {11, 2462, WLAN_TX_PWR_JP_DEFAULT},
+    {12, 2467, WLAN_TX_PWR_JP_DEFAULT},
+    {13, 2472, WLAN_TX_PWR_JP_DEFAULT}
+};
+
+/** Band: 'B/G', Region: Japan */
+static chan_freq_power_t channel_freq_power_JPN40_BG[] = {
+    {14, 2484, WLAN_TX_PWR_JP_DEFAULT}
+};
+
+/** Band : 'B/G', Region: Special */
+static chan_freq_power_t channel_freq_power_SPECIAL_BG[] = {
+    {1, 2412, WLAN_TX_PWR_JP_DEFAULT},
+    {2, 2417, WLAN_TX_PWR_JP_DEFAULT},
+    {3, 2422, WLAN_TX_PWR_JP_DEFAULT},
+    {4, 2427, WLAN_TX_PWR_JP_DEFAULT},
+    {5, 2432, WLAN_TX_PWR_JP_DEFAULT},
+    {6, 2437, WLAN_TX_PWR_JP_DEFAULT},
+    {7, 2442, WLAN_TX_PWR_JP_DEFAULT},
+    {8, 2447, WLAN_TX_PWR_JP_DEFAULT},
+    {9, 2452, WLAN_TX_PWR_JP_DEFAULT},
+    {10, 2457, WLAN_TX_PWR_JP_DEFAULT},
+    {11, 2462, WLAN_TX_PWR_JP_DEFAULT},
+    {12, 2467, WLAN_TX_PWR_JP_DEFAULT},
+    {13, 2472, WLAN_TX_PWR_JP_DEFAULT},
+    {14, 2484, WLAN_TX_PWR_JP_DEFAULT}
+};
+
+/** Band: 'A', Region: USA FCC, Canada IC, Spain, France */
+static chan_freq_power_t channel_freq_power_A[] = {
+    {36, 5180, WLAN_TX_PWR_US_DEFAULT},
+    {40, 5200, WLAN_TX_PWR_US_DEFAULT},
+    {44, 5220, WLAN_TX_PWR_US_DEFAULT},
+    {48, 5240, WLAN_TX_PWR_US_DEFAULT},
+    {52, 5260, WLAN_TX_PWR_US_DEFAULT},
+    {56, 5280, WLAN_TX_PWR_US_DEFAULT},
+    {60, 5300, WLAN_TX_PWR_US_DEFAULT},
+    {64, 5320, WLAN_TX_PWR_US_DEFAULT},
+    {100, 5500, WLAN_TX_PWR_US_DEFAULT},
+    {104, 5520, WLAN_TX_PWR_US_DEFAULT},
+    {108, 5540, WLAN_TX_PWR_US_DEFAULT},
+    {112, 5560, WLAN_TX_PWR_US_DEFAULT},
+    {116, 5580, WLAN_TX_PWR_US_DEFAULT},
+    {120, 5600, WLAN_TX_PWR_US_DEFAULT},
+    {124, 5620, WLAN_TX_PWR_US_DEFAULT},
+    {128, 5640, WLAN_TX_PWR_US_DEFAULT},
+    {132, 5660, WLAN_TX_PWR_US_DEFAULT},
+    {136, 5680, WLAN_TX_PWR_US_DEFAULT},
+    {140, 5700, WLAN_TX_PWR_US_DEFAULT},
+    {149, 5745, WLAN_TX_PWR_US_DEFAULT},
+    {153, 5765, WLAN_TX_PWR_US_DEFAULT},
+    {157, 5785, WLAN_TX_PWR_US_DEFAULT},
+    {161, 5805, WLAN_TX_PWR_US_DEFAULT},
+    {165, 5825, WLAN_TX_PWR_US_DEFAULT}
+};
+
+/** Band: 'A', Region: Europe ETSI */
+static chan_freq_power_t channel_freq_power_EU_A[] = {
+    {36, 5180, WLAN_TX_PWR_EMEA_DEFAULT},
+    {40, 5200, WLAN_TX_PWR_EMEA_DEFAULT},
+    {44, 5220, WLAN_TX_PWR_EMEA_DEFAULT},
+    {48, 5240, WLAN_TX_PWR_EMEA_DEFAULT},
+    {52, 5260, WLAN_TX_PWR_EMEA_DEFAULT},
+    {56, 5280, WLAN_TX_PWR_EMEA_DEFAULT},
+    {60, 5300, WLAN_TX_PWR_EMEA_DEFAULT},
+    {64, 5320, WLAN_TX_PWR_EMEA_DEFAULT},
+    {100, 5500, WLAN_TX_PWR_EMEA_DEFAULT},
+    {104, 5520, WLAN_TX_PWR_EMEA_DEFAULT},
+    {108, 5540, WLAN_TX_PWR_EMEA_DEFAULT},
+    {112, 5560, WLAN_TX_PWR_EMEA_DEFAULT},
+    {116, 5580, WLAN_TX_PWR_EMEA_DEFAULT},
+    {120, 5600, WLAN_TX_PWR_EMEA_DEFAULT},
+    {124, 5620, WLAN_TX_PWR_EMEA_DEFAULT},
+    {128, 5640, WLAN_TX_PWR_EMEA_DEFAULT},
+    {132, 5660, WLAN_TX_PWR_EMEA_DEFAULT},
+    {136, 5680, WLAN_TX_PWR_EMEA_DEFAULT},
+    {140, 5700, WLAN_TX_PWR_EMEA_DEFAULT}
+};
+
+/** Band: 'A', Region: Japan */
+static chan_freq_power_t channel_freq_power_JPN_A[] = {
+    {8, 5040, WLAN_TX_PWR_JP_DEFAULT},
+    {12, 5060, WLAN_TX_PWR_JP_DEFAULT},
+    {16, 5080, WLAN_TX_PWR_JP_DEFAULT},
+    {34, 5170, WLAN_TX_PWR_JP_DEFAULT},
+    {38, 5190, WLAN_TX_PWR_JP_DEFAULT},
+    {42, 5210, WLAN_TX_PWR_JP_DEFAULT},
+    {46, 5230, WLAN_TX_PWR_JP_DEFAULT},
+};
+
+/**
+ * The structure for channel, frequency and power
+ */
+typedef struct _region_cfp_table
+{
+    /** Region */
+    t_u8 region;
+    /** Frequency/Power */
+    chan_freq_power_t *cfp_BG;
+    /** No BG flag */
+    int cfp_no_BG;
+    /** Frequency/Power for band A */
+    chan_freq_power_t *cfp_A;
+    /** No A flag */
+    int cfp_no_A;
+} region_cfp_table_t;
+
+/**
+ * The structure for the mapping between region and CFP
+ */
+static region_cfp_table_t region_cfp_table[] = {
+    {0x10,                      /* US FCC */
+     channel_freq_power_US_BG,
+     sizeof(channel_freq_power_US_BG) / sizeof(chan_freq_power_t),
+     channel_freq_power_A,
+     sizeof(channel_freq_power_A) / sizeof(chan_freq_power_t),
+     }
+    ,
+    {0x20,                      /* CANADA IC */
+     channel_freq_power_US_BG,
+     sizeof(channel_freq_power_US_BG) / sizeof(chan_freq_power_t),
+     channel_freq_power_A,
+     sizeof(channel_freq_power_A) / sizeof(chan_freq_power_t),
+     }
+    ,
+    {0x30,                      /* EU */
+     channel_freq_power_EU_BG,
+     sizeof(channel_freq_power_EU_BG) / sizeof(chan_freq_power_t),
+     channel_freq_power_EU_A,
+     sizeof(channel_freq_power_EU_A) / sizeof(chan_freq_power_t),
+     }
+    ,
+    {0x32,                      /* FRANCE */
+     channel_freq_power_FR_BG,
+     sizeof(channel_freq_power_FR_BG) / sizeof(chan_freq_power_t),
+     channel_freq_power_A,
+     sizeof(channel_freq_power_A) / sizeof(chan_freq_power_t),
+     }
+    ,
+    {0x40,                      /* JAPAN */
+     channel_freq_power_JPN40_BG,
+     sizeof(channel_freq_power_JPN40_BG) / sizeof(chan_freq_power_t),
+     channel_freq_power_JPN_A,
+     sizeof(channel_freq_power_JPN_A) / sizeof(chan_freq_power_t),
+     }
+    ,
+    {0x41,                      /* JAPAN */
+     channel_freq_power_JPN41_BG,
+     sizeof(channel_freq_power_JPN41_BG) / sizeof(chan_freq_power_t),
+     channel_freq_power_JPN_A,
+     sizeof(channel_freq_power_JPN_A) / sizeof(chan_freq_power_t),
+     }
+    ,
+    {0xff,                      /* Special */
+     channel_freq_power_SPECIAL_BG,
+     sizeof(channel_freq_power_SPECIAL_BG) / sizeof(chan_freq_power_t),
+     channel_freq_power_JPN_A,
+     sizeof(channel_freq_power_JPN_A) / sizeof(chan_freq_power_t),
+     }
+    ,
+/* Add new region here */
+};
+
+/********************************************************
+    Global Variables
+********************************************************/
+/**
+ * The rates supported for ad-hoc B mode
+ */
+t_u8 AdhocRates_B[B_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96, 0 };
+
+/**
+ * The rates supported for ad-hoc G mode
+ */
+t_u8 AdhocRates_G[G_SUPPORTED_RATES] =
+    { 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0 };
+
+/**
+ * The rates supported for ad-hoc BG mode
+ */
+t_u8 AdhocRates_BG[BG_SUPPORTED_RATES] =
+    { 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
+    0x60, 0x6c, 0
+};
+
+/**
+ * The rates supported in A mode for ad-hoc
+ */
+t_u8 AdhocRates_A[A_SUPPORTED_RATES] =
+    { 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0 };
+/**
+ * The rates supported in A mode (used for BAND_A)
+ */
+t_u8 SupportedRates_A[A_SUPPORTED_RATES] =
+    { 0x0c, 0x12, 0x18, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0 };
+/**
+ * The rates supported by the card
+ */
+t_u16 WlanDataRates[WLAN_SUPPORTED_RATES_EXT] =
+    { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
+    0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90,
+    0x0D, 0x1A, 0x27, 0x34, 0x4E, 0x68, 0x75,
+    0x82, 0x0C, 0x1B, 0x36, 0x51, 0x6C, 0xA2,
+    0xD8, 0xF3, 0x10E, 0x00
+};
+
+/**
+ * The rates supported in B mode
+ */
+t_u8 SupportedRates_B[B_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x16, 0 };
+
+/**
+ * The rates supported in G mode (BAND_G, BAND_G|BAND_GN)
+ */
+t_u8 SupportedRates_G[G_SUPPORTED_RATES] =
+    { 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0 };
+
+/**
+ * The rates supported in BG mode (BAND_B|BAND_G, BAND_B|BAND_G|BAND_GN)
+ */
+t_u8 SupportedRates_BG[BG_SUPPORTED_RATES] =
+    { 0x02, 0x04, 0x0b, 0x0c, 0x12, 0x16, 0x18, 0x24, 0x30, 0x48,
+    0x60, 0x6c, 0
+};
+
+/**
+ * The table to keep region code
+ */
+t_u16 region_code_index[MRVDRV_MAX_REGION_CODE] =
+    { 0x10, 0x20, 0x30, 0x32, 0x40, 0x41, 0xff };
+
+/**
+ * The rates supported in N mode
+ */
+t_u8 SupportedRates_N[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
+
+/********************************************************
+    Local Functions
+********************************************************/
+/** 
+ *  @brief Find a character in a string.
+ *   
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param s            A pointer to string
+ *  @param c            Character to be located 
+ *  @param n            The length of string
+ *
+ *  @return        A pointer to the first occurrence of c in string, or MNULL if c is not found.
+ */
+static void *
+wlan_memchr(pmlan_adapter pmadapter, void *s, int c, int n)
+{
+    const t_u8 *p = (t_u8 *) s;
+
+    ENTER();
+
+    while (n--) {
+        if ((t_u8) c == *p++) {
+            LEAVE();
+            return (void *) (p - 1);
+        }
+    }
+
+    LEAVE();
+    return MNULL;
+}
+
+/** 
+ *  @brief Use index to get the data rate
+ *   
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param index        The index of data rate
+ *  @param ht_info      ht info
+ *
+ *  @return                     Data rate or 0 
+ */
+t_u32
+wlan_index_to_data_rate(pmlan_adapter pmadapter, t_u8 index, t_u8 ht_info)
+{
+    t_u16 mcs_rate[4][8] = { {0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e}
+    ,                           /* LG 40M */
+    {0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c}
+    ,                           /* SG 40M */
+    {0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82}
+    ,                           /* LG 20M */
+    {0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90}
+    };                          /* SG 20M */
+
+    t_u32 rate;
+    ENTER();
+
+    if (ht_info & MBIT(0)) {
+        if (index == MLAN_RATE_BITMAP_MCS0) {
+            if (ht_info & MBIT(2))
+                rate = 0x0D;    /* MCS 32 SGI rate */
+            else
+                rate = 0x0C;    /* MCS 32 LGI rate */
+        } else if (index < 8) {
+            if (ht_info & MBIT(1)) {
+                if (ht_info & MBIT(2))
+                    rate = mcs_rate[1][index];  /* SGI, 40M */
+                else
+                    rate = mcs_rate[0][index];  /* LGI, 40M */
+            } else {
+                if (ht_info & MBIT(2))
+                    rate = mcs_rate[3][index];  /* SGI, 20M */
+                else
+                    rate = mcs_rate[2][index];  /* LGI, 20M */
+            }
+        } else
+            rate = WlanDataRates[0];
+    } else {
+        if (index >= WLAN_SUPPORTED_RATES_EXT)
+            index = 0;
+        rate = WlanDataRates[index];
+    }
+    LEAVE();
+    return rate;
+}
+
+/** 
+ *  @brief Use rate to get the index
+ *   
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param rate         Data rate
+ *
+ *  @return                     Index or 0 
+ */
+t_u8
+wlan_data_rate_to_index(pmlan_adapter pmadapter, t_u32 rate)
+{
+    t_u16 *ptr;
+
+    ENTER();
+    if (rate)
+        if ((ptr = wlan_memchr(pmadapter, WlanDataRates, (t_u8) rate,
+                               sizeof(WlanDataRates)))) {
+            LEAVE();
+            return (t_u8) (ptr - WlanDataRates);
+        }
+    LEAVE();
+    return 0;
+}
+
+/** 
+ *  @brief Get active data rates
+ *   
+ *  @param pmpriv           A pointer to mlan_private structure
+ *  @param rates            The buf to return the active rates
+ *
+ *  @return                 The number of Rates
+ */
+t_u32
+wlan_get_active_data_rates(mlan_private * pmpriv, WLAN_802_11_RATES rates)
+{
+    t_u32 k;
+
+    ENTER();
+
+    if (pmpriv->media_connected != MTRUE) {
+        k = wlan_get_supported_rates(pmpriv, rates);
+    } else {
+        k = wlan_copy_rates(rates, 0, pmpriv->curr_bss_params.data_rates,
+                            pmpriv->curr_bss_params.num_of_rates);
+    }
+
+    LEAVE();
+    return k;
+}
+
+/********************************************************
+    Global Functions
+********************************************************/
+/** 
+ *  @brief This function finds the CFP in 
+ *  		region_cfp_table based on region and band parameter.
+ *  
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *  @param region     The region code
+ *  @param band       The band
+ *  @param cfp_no     A pointer to CFP number
+ *
+ *  @return           A pointer to CFP
+ */
+chan_freq_power_t *
+wlan_get_region_cfp_table(pmlan_adapter pmadapter, t_u8 region, t_u8 band,
+                          int *cfp_no)
+{
+    t_u32 i;
+
+    ENTER();
+
+    for (i = 0; i < sizeof(region_cfp_table) / sizeof(region_cfp_table_t); i++) {
+        PRINTM(MINFO, "region_cfp_table[i].region=%d\n",
+               region_cfp_table[i].region);
+        /* Check if region matches */
+        if (region_cfp_table[i].region == region) {
+            /* Select by band */
+            if (band & (BAND_B | BAND_G | BAND_GN)) {
+                *cfp_no = region_cfp_table[i].cfp_no_BG;
+                LEAVE();
+                return region_cfp_table[i].cfp_BG;
+            } else if (band & (BAND_A | BAND_AN)) {
+                *cfp_no = region_cfp_table[i].cfp_no_A;
+                LEAVE();
+                return region_cfp_table[i].cfp_A;
+            } else {
+                PRINTM(MERROR, "Error Band[0x%x]\n", band);
+                LEAVE();
+                return MNULL;
+
+            }
+        }
+    }
+
+    LEAVE();
+    return MNULL;
+}
+
+/** 
+ *  @brief This function search through all the regions cfp table to find the channel, 
+ *            if the channel is found then gets the MIN txpower of the channel 
+ *            present in all the regions.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param channel      Channel number.
+ *
+ *  @return             The Tx power
+ */
+t_u8
+wlan_get_txpwr_of_chan_from_cfp(mlan_private * pmpriv, t_u8 channel)
+{
+    t_u8 i = 0;
+    t_u8 j = 0;
+    t_u8 tx_power = 0;
+    t_u32 cfp_no;
+    chan_freq_power_t *cfp = MNULL;
+    chan_freq_power_t *cfp_a = MNULL;
+    t_u32 cfp_no_a;
+
+    ENTER();
+
+    for (i = 0; i < NELEMENTS(region_cfp_table); i++) {
+        /* Get CFP */
+        cfp = region_cfp_table[i].cfp_BG;
+        cfp_no = region_cfp_table[i].cfp_no_BG;
+
+        cfp_a = region_cfp_table[i].cfp_A;
+        cfp_no_a = region_cfp_table[i].cfp_no_A;
+        /* Find matching channel and get Tx power */
+        for (j = 0; j < cfp_no; j++) {
+            if ((cfp + j)->channel == channel) {
+                if (tx_power != 0)
+                    tx_power = MIN(tx_power, (cfp + j)->max_tx_power);
+                else
+                    tx_power = (t_u8) (cfp + j)->max_tx_power;
+                break;
+            }
+        }
+
+        for (j = 0; j < cfp_no_a; j++) {
+            if ((cfp_a + j)->channel == channel) {
+                if (tx_power != 0)
+                    tx_power = MIN(tx_power, (cfp_a + j)->max_tx_power);
+                else
+                    tx_power = (cfp_a + j)->max_tx_power;
+                break;
+            }
+        }
+    }
+
+    LEAVE();
+    return tx_power;
+}
+
+/** 
+ *  @brief Get the channel frequency power info for a specific channel
+ *   
+ *  @param pmadapter            A pointer to mlan_adapter structure
+ *  @param band                 It can be BAND_A, BAND_G or BAND_B
+ *  @param channel              The channel to search for
+ *  @param region_channel       A pointer to region_chan_t structure
+ *
+ *  @return                     A pointer to chan_freq_power_t structure or MNULL if not found.
+ */
+
+chan_freq_power_t *
+wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter,
+                                 t_u8 band,
+                                 t_u16 channel, region_chan_t * region_channel)
+{
+    region_chan_t *rc;
+    chan_freq_power_t *cfp = MNULL;
+    int i, j;
+
+    ENTER();
+
+    for (j = 0; !cfp && (j < MAX_REGION_CHANNEL_NUM); j++) {
+        rc = &region_channel[j];
+
+        if (!rc->valid || !rc->pcfp)
+            continue;
+        switch (rc->band) {
+        case BAND_A:
+            switch (band) {
+            case BAND_AN:
+            case BAND_A | BAND_AN:
+            case BAND_A:       /* Matching BAND_A */
+                break;
+
+            default:
+                continue;
+            }
+            break;
+        case BAND_B:
+        case BAND_G:
+            switch (band) {
+            case BAND_GN:
+            case BAND_B | BAND_G | BAND_GN:
+            case BAND_G | BAND_GN:
+            case BAND_B | BAND_G:
+            case BAND_B:       /* Matching BAND_B/G */
+            case BAND_G:
+            case 0:
+                break;
+            default:
+                continue;
+            }
+            break;
+        default:
+            continue;
+        }
+        if (channel == FIRST_VALID_CHANNEL)
+            cfp = &rc->pcfp[0];
+        else {
+            for (i = 0; i < rc->num_cfp; i++) {
+                if (rc->pcfp[i].channel == channel) {
+                    cfp = &rc->pcfp[i];
+                    break;
+                }
+            }
+        }
+    }
+
+    if (!cfp && channel)
+        PRINTM(MERROR, "wlan_get_cfp_by_band_and_channel(): cannot find "
+               "cfp by band %d & channel %d\n", band, channel);
+
+    LEAVE();
+    return cfp;
+}
+
+/** 
+ *  @brief Find the channel frequency power info for a specific channel
+ *   
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param band         It can be BAND_A, BAND_G or BAND_B
+ *  @param channel      The channel to search for
+ *
+ *  @return             A pointer to chan_freq_power_t structure or MNULL if not found.
+ */
+chan_freq_power_t *
+wlan_find_cfp_by_band_and_channel(mlan_adapter * pmadapter,
+                                  t_u8 band, t_u16 channel)
+{
+    chan_freq_power_t *cfp = MNULL;
+
+    ENTER();
+
+    if (pmadapter->state_11d.enable_11d == ENABLE_11D)
+        cfp =
+            wlan_get_cfp_by_band_and_channel(pmadapter, band, channel,
+                                             pmadapter->universal_channel);
+    else
+        cfp =
+            wlan_get_cfp_by_band_and_channel(pmadapter, band, channel,
+                                             pmadapter->region_channel);
+
+    LEAVE();
+    return cfp;
+}
+
+/** 
+ *  @brief Find the channel frequency power info for a specific frequency
+ *   
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param band         It can be BAND_A, BAND_G or BAND_B
+ *  @param freq         The frequency to search for
+ *
+ *  @return         Pointer to chan_freq_power_t structure; MNULL if not found
+ */
+chan_freq_power_t *
+wlan_find_cfp_by_band_and_freq(mlan_adapter * pmadapter, t_u8 band, t_u32 freq)
+{
+    chan_freq_power_t *cfp = MNULL;
+    region_chan_t *rc;
+    int count = sizeof(pmadapter->region_channel) /
+        sizeof(pmadapter->region_channel[0]);
+    int i, j;
+
+    ENTER();
+
+    for (j = 0; !cfp && (j < count); j++) {
+        rc = &pmadapter->region_channel[j];
+
+        if (pmadapter->state_11d.enable_11d == ENABLE_11D)
+            rc = &pmadapter->universal_channel[j];
+
+        if (!rc->valid || !rc->pcfp)
+            continue;
+        switch (rc->band) {
+        case BAND_A:
+            switch (band) {
+            case BAND_AN:
+            case BAND_A | BAND_AN:
+            case BAND_A:       /* Matching BAND_A */
+                break;
+            default:
+                continue;
+            }
+            break;
+        case BAND_B:
+        case BAND_G:
+            switch (band) {
+            case BAND_GN:
+            case BAND_B | BAND_G | BAND_GN:
+            case BAND_G | BAND_GN:
+            case BAND_B | BAND_G:
+            case BAND_B:
+            case BAND_G:
+            case 0:
+                break;
+            default:
+                continue;
+            }
+            break;
+        default:
+            continue;
+        }
+        for (i = 0; i < rc->num_cfp; i++) {
+            if (rc->pcfp[i].freq == freq) {
+                cfp = &rc->pcfp[i];
+                break;
+            }
+        }
+    }
+
+    if (!cfp && freq)
+        PRINTM(MERROR, "find_cfp_by_band_and_freql(): cannot find cfp by "
+               "band %d & freq %d\n", band, freq);
+
+    LEAVE();
+    return cfp;
+}
+
+/** 
+ *  @brief Check if Rate Auto
+ *   
+ *  @param pmpriv               A pointer to mlan_private structure
+ *
+ *  @return                     MTRUE or MFALSE
+ */
+t_u8
+wlan_is_rate_auto(mlan_private * pmpriv)
+{
+    t_u32 i;
+    int rate_num = 0;
+
+    ENTER();
+
+    for (i = 0; i < NELEMENTS(pmpriv->bitmap_rates); i++)
+        if (pmpriv->bitmap_rates[i])
+            rate_num++;
+
+    LEAVE();
+    if (rate_num > 1)
+        return MTRUE;
+    else
+        return MFALSE;
+}
+
+/** 
+ *  @brief Covert Rate Bitmap to Rate index
+ *   
+ *  @param pmadapter    Pointer to mlan_adapter structure
+ *  @param rate_bitmap  Pointer to rate bitmap
+ *  @param size         Size of the bitmap array
+ *
+ *  @return             Rate index
+ */
+int
+wlan_get_rate_index(pmlan_adapter pmadapter, t_u16 * rate_bitmap, int size)
+{
+    int i;
+
+    ENTER();
+
+    for (i = 0; i < size * 8; i++) {
+        if (rate_bitmap[i / 16] & (1 << (i % 16))) {
+            LEAVE();
+            return i;
+        }
+    }
+
+    LEAVE();
+    return 0;
+}
+
+/** 
+ *  @brief Get supported data rates
+ *   
+ *  @param pmpriv           A pointer to mlan_private structure
+ *  @param rates            The buf to return the supported rates
+ *
+ *  @return                 The number of Rates
+ */
+t_u32
+wlan_get_supported_rates(mlan_private * pmpriv, WLAN_802_11_RATES rates)
+{
+    t_u32 k = 0;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+
+    ENTER();
+
+    if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) {
+        /* Infra. mode */
+        switch (pmadapter->config_bands) {
+        case BAND_B:
+            PRINTM(MINFO, "Infra Band=%d SupportedRates_B\n",
+                   pmadapter->config_bands);
+            k = wlan_copy_rates(rates, k, SupportedRates_B,
+                                sizeof(SupportedRates_B));
+            break;
+        case BAND_G:
+        case BAND_G | BAND_GN:
+            PRINTM(MINFO, "Infra band=%d SupportedRates_G\n",
+                   pmadapter->config_bands);
+            k = wlan_copy_rates(rates, k, SupportedRates_G,
+                                sizeof(SupportedRates_G));
+            break;
+        case BAND_B | BAND_G:
+        case BAND_A | BAND_B | BAND_G:
+        case BAND_A | BAND_B:
+        case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN:
+        case BAND_B | BAND_G | BAND_GN:
+            PRINTM(MINFO, "Infra band=%d SupportedRates_BG\n",
+                   pmadapter->config_bands);
+            k = wlan_copy_rates(rates, k, SupportedRates_BG,
+                                sizeof(SupportedRates_BG));
+            break;
+        case BAND_A:
+        case BAND_A | BAND_G:
+            PRINTM(MINFO, "Infra band=%d SupportedRates_A\n",
+                   pmadapter->config_bands);
+            k = wlan_copy_rates(rates, k, SupportedRates_A,
+                                sizeof(SupportedRates_A));
+            break;
+        case BAND_A | BAND_AN:
+        case BAND_A | BAND_G | BAND_AN | BAND_GN:
+            PRINTM(MINFO, "Infra band=%d SupportedRates_A\n",
+                   pmadapter->config_bands);
+            k = wlan_copy_rates(rates, k, SupportedRates_A,
+                                sizeof(SupportedRates_A));
+            break;
+        case BAND_GN:
+            PRINTM(MINFO, "Infra band=%d SupportedRates_N\n",
+                   pmadapter->config_bands);
+            k = wlan_copy_rates(rates, k, SupportedRates_N,
+                                sizeof(SupportedRates_N));
+            break;
+        }
+    } else {
+        /* Ad-hoc mode */
+        switch (pmadapter->adhoc_start_band) {
+        case BAND_B:
+            PRINTM(MINFO, "Adhoc B\n");
+            k = wlan_copy_rates(rates, k, AdhocRates_B, sizeof(AdhocRates_B));
+            break;
+        case BAND_G:
+        case BAND_G | BAND_GN:
+            PRINTM(MINFO, "Adhoc G only\n");
+            k = wlan_copy_rates(rates, k, AdhocRates_G, sizeof(AdhocRates_G));
+            break;
+        case BAND_B | BAND_G:
+        case BAND_B | BAND_G | BAND_GN:
+            PRINTM(MINFO, "Adhoc BG\n");
+            k = wlan_copy_rates(rates, k, AdhocRates_BG, sizeof(AdhocRates_BG));
+            break;
+        case BAND_A:
+        case BAND_A | BAND_AN:
+            PRINTM(MINFO, "Adhoc A\n");
+            k = wlan_copy_rates(rates, k, AdhocRates_A, sizeof(AdhocRates_A));
+            break;
+        }
+    }
+
+    LEAVE();
+    return k;
+}
+
+/** 
+ *  @brief This function sets region table. 
+ *  
+ *  @param pmpriv  A pointer to mlan_private structure
+ *  @param region  The region code
+ *  @param band    The band
+ *
+ *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_set_regiontable(mlan_private * pmpriv, t_u8 region, t_u8 band)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    int i = 0;
+    chan_freq_power_t *cfp;
+    int cfp_no;
+
+    ENTER();
+
+    memset(pmadapter->region_channel, 0, sizeof(pmadapter->region_channel));
+
+    if (band & (BAND_B | BAND_G | BAND_GN)) {
+        cfp =
+            wlan_get_region_cfp_table(pmadapter, region,
+                                      BAND_G | BAND_B | BAND_GN, &cfp_no);
+        if (cfp) {
+            pmadapter->region_channel[i].num_cfp = (t_u8) cfp_no;
+            pmadapter->region_channel[i].pcfp = cfp;
+        } else {
+            PRINTM(MERROR, "wrong region code %#x in Band B-G\n", region);
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+        pmadapter->region_channel[i].valid = MTRUE;
+        pmadapter->region_channel[i].region = region;
+        if (band & BAND_GN)
+            pmadapter->region_channel[i].band = BAND_G;
+        else
+            pmadapter->region_channel[i].band =
+                (band & BAND_G) ? BAND_G : BAND_B;
+        i++;
+    }
+    if (band & (BAND_A | BAND_AN)) {
+        cfp = wlan_get_region_cfp_table(pmadapter, region, BAND_A, &cfp_no);
+        if (cfp) {
+            pmadapter->region_channel[i].num_cfp = cfp_no;
+            pmadapter->region_channel[i].pcfp = cfp;
+        } else {
+            PRINTM(MERROR, "wrong region code %#x in Band A\n", region);
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+        pmadapter->region_channel[i].valid = MTRUE;
+        pmadapter->region_channel[i].region = region;
+        pmadapter->region_channel[i].band = BAND_A;
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
diff --git a/wlan_src/mlan/mlan_cmdevt.c b/wlan_src/mlan/mlan_cmdevt.c
new file mode 100755
index 0000000..b3584b6
--- /dev/null
+++ b/wlan_src/mlan/mlan_cmdevt.c
@@ -0,0 +1,1475 @@
+/**
+ * @file mlan_cmdevt.c
+ *
+ *  @brief This file contains the handling of CMD/EVENT in MLAN
+ *
+ *
+ *  Copyright (C) 2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ *   
+ */
+
+/*************************************************************
+Change Log:
+    05/12/2009: initial version
+************************************************************/
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_11h.h"
+#include "mlan_sdio.h"
+/********************************************************
+                Local Variables
+********************************************************/
+
+/*******************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+/** 
+ *  @brief This function initializes the command node.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pcmd_node    A pointer to cmd_ctrl_node structure
+ *  @param cmd_oid      Cmd oid: treated as sub command
+ *  @param pioctl_buf   A pointer to MLAN IOCTl Request buffer
+ *  @param pdata_buf    A pointer to information buffer
+ *
+ *  @return             N/A
+ */
+void
+wlan_init_cmd_node(IN pmlan_private pmpriv,
+                   IN cmd_ctrl_node * pcmd_node,
+                   IN t_u32 cmd_oid,
+                   IN t_void * pioctl_buf, IN t_void * pdata_buf)
+{
+    t_u8 *head_ptr = MNULL;
+    ENTER();
+
+    if (pcmd_node == MNULL) {
+        LEAVE();
+        return;
+    }
+    pcmd_node->priv = pmpriv;
+    pcmd_node->cmd_oid = cmd_oid;
+    pcmd_node->pioctl_buf = pioctl_buf;
+    pcmd_node->pdata_buf = pdata_buf;
+
+    pcmd_node->cmdbuf = pcmd_node->pmbuf;
+
+    /* Make sure head_ptr for cmd buf is Align */
+    head_ptr = (t_u8 *) ALIGN_ADDR(pcmd_node->cmdbuf->pbuf, HEADER_ALIGNMENT);
+    pcmd_node->cmdbuf->data_offset =
+        (t_u32) (head_ptr - pcmd_node->cmdbuf->pbuf);
+    memset(head_ptr, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
+
+    /* Prepare mlan_buffer for command sending */
+    pcmd_node->cmdbuf->buf_type = MLAN_BUF_TYPE_CMD;
+    pcmd_node->cmdbuf->data_offset += INTF_HEADER_LEN;
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function gets a free command node if available in
+ *              command free queue.
+ *  
+ *  @param pmadapter        A pointer to mlan_adapter structure
+ *
+ *  @return cmd_ctrl_node   A pointer to cmd_ctrl_node structure or MNULL
+ */
+cmd_ctrl_node *
+wlan_get_cmd_node(mlan_adapter * pmadapter)
+{
+    cmd_ctrl_node *pcmd_node;
+
+    ENTER();
+
+    if (pmadapter == MNULL) {
+        LEAVE();
+        return MNULL;
+    }
+
+    if (util_peek_list(&pmadapter->cmd_free_q,
+                       pmadapter->callbacks.moal_spin_lock,
+                       pmadapter->callbacks.moal_spin_unlock)) {
+        pcmd_node = (cmd_ctrl_node *) util_dequeue_list(&pmadapter->cmd_free_q,
+                                                        pmadapter->callbacks.
+                                                        moal_spin_lock,
+                                                        pmadapter->callbacks.
+                                                        moal_spin_unlock);
+    } else {
+        PRINTM(MERROR, "GET_CMD_NODE: cmd_ctrl_node is not available\n");
+        pcmd_node = MNULL;
+    }
+
+    LEAVE();
+    return pcmd_node;
+}
+
+/** 
+ *  @brief This function cleans command node.
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pcmd_node    A pointer to cmd_ctrl_node structure
+ *
+ *  @return             N/A
+ */
+t_void
+wlan_clean_cmd_node(pmlan_adapter pmadapter, cmd_ctrl_node * pcmd_node)
+{
+    ENTER();
+
+    if (pcmd_node == MNULL) {
+        LEAVE();
+        return;
+    }
+    pcmd_node->cmd_oid = 0;
+    pcmd_node->cmd_flag = 0;
+    pcmd_node->pioctl_buf = MNULL;
+    pcmd_node->pdata_buf = MNULL;
+
+    if (pcmd_node->respbuf) {
+        pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle,
+                                                pcmd_node->respbuf, 0,
+                                                MLAN_STATUS_SUCCESS);
+        pcmd_node->respbuf = MNULL;
+    }
+
+    LEAVE();
+    return;
+}
+
+/**
+ *  @brief This function will return the pointer to the first entry in 
+ *  		pending cmd which matches the given pioctl_req
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter
+ *  @param pioctl_req   A pointer to mlan_ioctl_req buf
+ *
+ *  @return 	   A pointer to first entry match pioctl_req
+ */
+cmd_ctrl_node *
+wlan_get_pending_ioctl_cmd(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
+{
+    cmd_ctrl_node *pcmd_node = MNULL;
+
+    ENTER();
+
+    if (!
+        (pcmd_node =
+         (cmd_ctrl_node *) util_peek_list(&pmadapter->cmd_pending_q,
+                                          pmadapter->callbacks.moal_spin_lock,
+                                          pmadapter->callbacks.
+                                          moal_spin_unlock))) {
+        LEAVE();
+        return MNULL;
+    }
+    while (pcmd_node != (cmd_ctrl_node *) & pmadapter->cmd_pending_q) {
+        if (pcmd_node->pioctl_buf == pioctl_req) {
+            LEAVE();
+            return pcmd_node;
+        }
+        pcmd_node = pcmd_node->pnext;
+    }
+    LEAVE();
+    return MNULL;
+}
+
+/** 
+ *  @brief This function handles the command response of host_cmd
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_host_cmd(IN pmlan_private pmpriv,
+                  IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_misc_cfg *misc;
+    t_u16 size = wlan_le16_to_cpu(resp->size);
+
+    ENTER();
+
+    PRINTM(MINFO, "host command response size = %d\n", size);
+    size = MIN(size, MRVDRV_SIZE_OF_CMD_BUFFER);
+    if (pioctl_buf) {
+        misc = (mlan_ds_misc_cfg *) pioctl_buf->pbuf;
+        misc->param.hostcmd.len = size;
+        memcpy(misc->param.hostcmd.cmd, (void *) resp, size);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function sends host command to firmware.
+ *  
+ *  @param pmpriv     	A pointer to mlan_private structure
+ *  @param cmd      	A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf	A pointer to data buffer
+ *  @return         	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_host_cmd(IN pmlan_private pmpriv,
+                  IN HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_ds_misc_cmd *pcmd_ptr = (mlan_ds_misc_cmd *) pdata_buf;
+
+    ENTER();
+
+    /* Copy the HOST command to command buffer */
+    memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len);
+    PRINTM(MCMND, "Host command size = %d\n", pcmd_ptr->len);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function downloads a command to firmware.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pcmd_node    A pointer to cmd_ctrl_node structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_dnld_cmd_to_fw(IN mlan_private * pmpriv, IN cmd_ctrl_node * pcmd_node)
+{
+
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    HostCmd_DS_COMMAND *pcmd;
+    mlan_ioctl_req *pioctl_buf = MNULL;
+    t_u16 cmd_code;
+    t_u16 cmd_size;
+    t_u32 sec, usec;
+
+    ENTER();
+
+    if (!pmadapter || !pcmd_node) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    pcmd =
+        (HostCmd_DS_COMMAND *) (pcmd_node->cmdbuf->pbuf +
+                                pcmd_node->cmdbuf->data_offset);
+    if (pcmd_node->pioctl_buf != MNULL)
+        pioctl_buf = (mlan_ioctl_req *) pcmd_node->pioctl_buf;
+
+    /* Sanity test */
+    if (pcmd == MNULL || pcmd->size == 0) {
+        PRINTM(MERROR, "DNLD_CMD: pcmd is null or command size is zero, "
+               "Not sending\n");
+        if (pioctl_buf != MNULL)
+            pioctl_buf->status_code = MLAN_ERROR_CMD_DNLD_FAIL,
+                wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Set command sequence number */
+    pmadapter->seq_num++;
+    pcmd->seq_num = wlan_cpu_to_le16(pmadapter->seq_num);
+
+    wlan_request_cmd_lock(pmadapter);
+    pmadapter->curr_cmd = pcmd_node;
+    wlan_release_cmd_lock(pmadapter);
+
+    cmd_code = wlan_le16_to_cpu(pcmd->command);
+    cmd_size = wlan_le16_to_cpu(pcmd->size);
+
+    /* Set BSS_NO_BITS to HostCmd */
+    cmd_code = HostCmd_SET_BSS_NO(cmd_code, pcmd_node->priv->bss_num);
+    pcmd->command = wlan_cpu_to_le16(cmd_code);
+
+    pcmd_node->cmdbuf->data_len = cmd_size;
+
+    pmadapter->callbacks.moal_get_system_time(&sec, &usec);
+    PRINTM(MCMND, "DNLD_CMD (%lu.%lu): 0x%x, act 0x%x, len %d, seqno %d\n",
+           sec, usec, cmd_code,
+           wlan_le16_to_cpu(*(t_u16 *) ((t_u8 *) pcmd + S_DS_GEN)), cmd_size,
+           wlan_le16_to_cpu(pcmd->seq_num));
+    DBG_HEXDUMP(MCMD_D, "DNLD_CMD", (t_u8 *) pcmd, cmd_size);
+
+    /* Send the command to lower layer */
+
+    pcmd_node->cmdbuf->data_offset -= INTF_HEADER_LEN;
+    pcmd_node->cmdbuf->data_len += INTF_HEADER_LEN;
+    /* Extra header for SDIO is added here */
+    ret =
+        wlan_sdio_host_to_card(pmadapter, MLAN_TYPE_CMD, pcmd_node->cmdbuf,
+                               MNULL);
+
+    if (ret == MLAN_STATUS_FAILURE) {
+        PRINTM(MERROR, "DNLD_CMD: Host to Card Failed\n");
+        if (pioctl_buf != MNULL)
+            pioctl_buf->status_code = MLAN_ERROR_CMD_DNLD_FAIL,
+                wlan_insert_cmd_to_free_q(pmadapter, pmadapter->curr_cmd);
+
+        wlan_request_cmd_lock(pmadapter);
+        pmadapter->curr_cmd = MNULL;
+        wlan_release_cmd_lock(pmadapter);
+
+        pmadapter->dbg.num_cmd_host_to_card_failure++;
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Save the last command id and action to debug log */
+    pmadapter->dbg.last_cmd_index =
+        (pmadapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
+    pmadapter->dbg.last_cmd_id[pmadapter->dbg.last_cmd_index] = cmd_code;
+    pmadapter->dbg.last_cmd_act[pmadapter->dbg.last_cmd_index] =
+        wlan_le16_to_cpu(*(t_u16 *) ((t_u8 *) pcmd + S_DS_GEN));
+
+    /* Clear BSS_NO_BITS from HostCmd */
+    cmd_code &= HostCmd_CMD_ID_MASK;
+
+    /* Setup the timer after transmit command */
+    pcb->moal_start_timer(pmadapter->pmlan_cmd_timer, MFALSE, MRVDRV_TIMER_10S);
+
+    pmadapter->cmd_timer_is_set = MTRUE;
+
+    ret = MLAN_STATUS_SUCCESS;
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function sends sleep confirm command to firmware.
+ * 
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_dnld_sleep_confirm_cmd(mlan_adapter * pmadapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    static t_u32 i = 0;
+    t_u16 cmd_len = 0;
+    HostCmd_DS_802_11_PS_MODE_ENH *pps_mode = MNULL;
+    opt_sleep_confirm_buffer *sleep_cfm_buf =
+        (opt_sleep_confirm_buffer *) (pmadapter->psleep_cfm->pbuf +
+                                      pmadapter->psleep_cfm->data_offset);
+
+    ENTER();
+
+    cmd_len = sizeof(HostCmd_DS_COMMAND);
+    pps_mode = &sleep_cfm_buf->ps_cfm_sleep.params.psmode_enh;
+    sleep_cfm_buf->ps_cfm_sleep.seq_num =
+        wlan_cpu_to_le16(++pmadapter->seq_num);
+    pps_mode->params.sleep_cfm.resp_ctrl = wlan_cpu_to_le16(RESP_NEEDED);
+    DBG_HEXDUMP(MCMD_D, "SLEEP_CFM", &sleep_cfm_buf->ps_cfm_sleep, cmd_len);
+
+    /* Send sleep confirm command to firmware */
+
+    pmadapter->psleep_cfm->data_len = cmd_len + INTF_HEADER_LEN;
+    ret = wlan_sdio_host_to_card(pmadapter, MLAN_TYPE_CMD,
+                                 pmadapter->psleep_cfm, MNULL);
+
+    if (ret == MLAN_STATUS_FAILURE) {
+        PRINTM(MERROR, "SLEEP_CFM: failed\n");
+        pmadapter->dbg.num_cmd_sleep_cfm_host_to_card_failure++;
+        goto done;
+    } else {
+        if ((wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY))->bss_type ==
+            MLAN_BSS_TYPE_STA) {
+            if (!pps_mode->params.sleep_cfm.resp_ctrl) {
+                /* Response is not needed for sleep confirm command */
+                pmadapter->ps_state = PS_STATE_SLEEP;
+            } else {
+                pmadapter->ps_state = PS_STATE_SLEEP_CFM;
+            }
+
+            if (pps_mode->params.sleep_cfm.resp_ctrl != RESP_NEEDED
+                && (pmadapter->is_hs_configured &&
+                    !pmadapter->sleep_period.period)) {
+                pmadapter->pm_wakeup_card_req = MTRUE;
+                wlan_host_sleep_activated_event(wlan_get_priv
+                                                (pmadapter, MLAN_BSS_TYPE_STA),
+                                                MTRUE);
+            }
+        }
+#define NUM_SC_PER_LINE         16
+        if (++i % NUM_SC_PER_LINE == 0)
+            PRINTM(MEVENT, "+\n");
+        else
+            PRINTM(MEVENT, "+");
+    }
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/********************************************************
+                Global Functions
+********************************************************/
+
+/** 
+ *  @brief Event handler
+ *  
+ *  @param priv		A pointer to mlan_private structure
+ *  @param event_id	Event ID
+ *  @param pmevent	Event buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_recv_event(pmlan_private priv, mlan_event_id event_id, t_void * pmevent)
+{
+    pmlan_callbacks pcb = &priv->adapter->callbacks;
+
+    ENTER();
+
+    if (pmevent)
+        /* The caller has provided the event. */
+        pcb->moal_recv_event(priv->adapter->pmoal_handle,
+                             (pmlan_event) pmevent);
+    else {
+        mlan_event mevent;
+
+        memset(&mevent, 0, sizeof(mlan_event));
+        mevent.bss_num = priv->bss_num;
+        mevent.event_id = event_id;
+        mevent.event_len = 0;
+
+        pcb->moal_recv_event(priv->adapter->pmoal_handle, &mevent);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function allocates the command buffer and links
+ *              it to command free queue.
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_alloc_cmd_buffer(IN mlan_adapter * pmadapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
+    cmd_ctrl_node *pcmd_array;
+    t_u32 buf_size;
+    t_u32 i;
+
+    ENTER();
+
+    /* Allocate and initialize cmd_ctrl_node */
+    buf_size = sizeof(cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER;
+    ret = pcb->moal_malloc(buf_size, (t_u8 **) & pcmd_array);
+    if (ret != MLAN_STATUS_SUCCESS || !pcmd_array) {
+        PRINTM(MERROR, "ALLOC_CMD_BUF: Failed to allocate pcmd_array\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    pmadapter->cmd_pool = pcmd_array;
+    memset(pmadapter->cmd_pool, 0, buf_size);
+
+    /* Allocate and initialize command buffers */
+    for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
+        if (!
+            (pcmd_array[i].pmbuf =
+             wlan_alloc_mlan_buffer(pcb,
+                                    (MRVDRV_SIZE_OF_CMD_BUFFER +
+                                     HEADER_ALIGNMENT)))) {
+            PRINTM(MERROR, "ALLOC_CMD_BUF: pcmd_buf: out of memory\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+    }
+
+    for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
+        wlan_insert_cmd_to_free_q(pmadapter, &pcmd_array[i]);
+    }
+    ret = MLAN_STATUS_SUCCESS;
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function frees the command buffer.
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_free_cmd_buffer(IN mlan_adapter * pmadapter)
+{
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
+    cmd_ctrl_node *pcmd_array;
+    t_u32 i;
+
+    ENTER();
+
+    /* Need to check if cmd pool is allocated or not */
+    if (pmadapter->cmd_pool == MNULL) {
+        PRINTM(MINFO, "FREE_CMD_BUF: cmd_pool is Null\n");
+        goto done;
+    }
+
+    pcmd_array = pmadapter->cmd_pool;
+
+    /* Release shared memory buffers */
+    for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
+        if (pcmd_array[i].pmbuf) {
+            PRINTM(MCMND, "Free all the command buffer.\n");
+            wlan_free_mlan_buffer(pcb, pcmd_array[i].pmbuf);
+            pcmd_array[i].pmbuf = MNULL;
+        }
+        if (pcmd_array[i].respbuf) {
+            pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle,
+                                                    pcmd_array[i].respbuf, 0,
+                                                    MLAN_STATUS_SUCCESS);
+            pcmd_array[i].respbuf = MNULL;
+        }
+    }
+    /* Release cmd_ctrl_node */
+    if (pmadapter->cmd_pool) {
+        PRINTM(MCMND, "Free command pool.\n");
+        pcb->moal_mfree((t_u8 *) pmadapter->cmd_pool);
+        pmadapter->cmd_pool = MNULL;
+    }
+
+  done:
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles events generated by firmware
+ *  
+ *  @param pmadapter		A pointer to mlan_adapter structure
+ *
+ *  @return		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_process_event(pmlan_adapter pmadapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private priv = wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY);
+    pmlan_buffer pmbuf = pmadapter->pmlan_buffer_event;
+    t_u32 eventcause = pmadapter->event_cause;
+    t_u32 bss_num = 0;
+    t_u32 in_ts_sec;
+    t_u32 in_ts_usec;
+    ENTER();
+
+    /* Save the last event to debug log */
+    pmadapter->dbg.last_event_index =
+        (pmadapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
+    pmadapter->dbg.last_event[pmadapter->dbg.last_event_index] =
+        (t_u16) eventcause;
+
+    /* Get BSS number and corresponding priv */
+    bss_num = EVENT_GET_BSS_NUM((t_u16) eventcause);
+    priv = pmadapter->priv[bss_num];
+    if (!priv) {
+        bss_num = 0;
+        priv = wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY);
+    }
+    /* Clear BSS_NO_BITS from event */
+    eventcause &= EVENT_ID_MASK;
+    if (pmbuf)
+        pmbuf->bss_num = bss_num;
+
+    if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
+        pmadapter->callbacks.moal_get_system_time(&in_ts_sec, &in_ts_usec);
+        PRINTM(MEVENT, "%lu.%lu : Event: 0x%x\n", in_ts_sec, in_ts_usec,
+               eventcause);
+    }
+
+    ret = priv->ops.process_event(priv);
+
+    pmadapter->event_cause = 0;
+    pmadapter->pmlan_buffer_event = MNULL;
+
+    if (pmbuf) {
+        pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle, pmbuf,
+                                                0, MLAN_STATUS_SUCCESS);
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function requests a lock on command queue.
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *
+ *  @return             N/A
+ */
+t_void
+wlan_request_cmd_lock(IN mlan_adapter * pmadapter)
+{
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
+
+    ENTER();
+
+    /* Call MOAL spin lock callback function */
+    pcb->moal_spin_lock(pmadapter->pmlan_cmd_lock);
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function releases a lock on command queue.
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *
+ *  @return             N/A
+ */
+t_void
+wlan_release_cmd_lock(IN mlan_adapter * pmadapter)
+{
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
+
+    ENTER();
+
+    /* Call MOAL spin unlock callback function */
+    pcb->moal_spin_unlock(pmadapter->pmlan_cmd_lock);
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function prepare the command before sending to firmware.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd_no       Command number
+ *  @param cmd_action   Command action: GET or SET
+ *  @param cmd_oid      Cmd oid: treated as sub command
+ *  @param pioctl_buf   A pointer to MLAN IOCTl Request buffer
+ *  @param pdata_buf    A pointer to information buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_prepare_cmd(IN mlan_private * pmpriv,
+                 IN t_u16 cmd_no,
+                 IN t_u16 cmd_action,
+                 IN t_u32 cmd_oid,
+                 IN t_void * pioctl_buf, IN t_void * pdata_buf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    cmd_ctrl_node *pcmd_node = MNULL;
+    HostCmd_DS_COMMAND *cmd_ptr = MNULL;
+
+    ENTER();
+
+    /* Sanity test */
+    if (pmadapter == MNULL) {
+        PRINTM(MERROR, "PREP_CMD: pmadapter is MNULL\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    if (pmadapter->surprise_removed) {
+        PRINTM(MERROR, "PREP_CMD: Card is Removed\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    if (pmadapter->hw_status == WlanHardwareStatusReset) {
+        if (cmd_no != HostCmd_CMD_FUNC_INIT) {
+            PRINTM(MERROR, "PREP_CMD: FW is in reset state\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+    }
+
+    /* Get a new command node */
+    pcmd_node = wlan_get_cmd_node(pmadapter);
+
+    if (pcmd_node == MNULL) {
+        PRINTM(MERROR, "PREP_CMD: No free cmd node\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Initialize the command node */
+    wlan_init_cmd_node(pmpriv, pcmd_node, cmd_oid, pioctl_buf, pdata_buf);
+
+    if (pcmd_node->cmdbuf == MNULL) {
+        PRINTM(MERROR, "PREP_CMD: No free cmd buf\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    cmd_ptr =
+        (HostCmd_DS_COMMAND *) (pcmd_node->cmdbuf->pbuf +
+                                pcmd_node->cmdbuf->data_offset);
+    cmd_ptr->command = cmd_no;
+    cmd_ptr->result = 0;
+
+    /* Prepare command */
+    if (cmd_no)
+        ret =
+            pmpriv->ops.prepare_cmd(pmpriv, cmd_no, cmd_action, cmd_oid,
+                                    pioctl_buf, pdata_buf, cmd_ptr);
+    else {
+        ret = wlan_cmd_host_cmd(pmpriv, cmd_ptr, pdata_buf);
+        pcmd_node->cmd_flag |= CMD_F_HOSTCMD;
+    }
+
+    /* Return error, since the command preparation failed */
+    if (ret != MLAN_STATUS_SUCCESS) {
+        PRINTM(MERROR, "PREP_CMD: Command 0x%x preparation failed\n", cmd_no);
+        wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Send command */
+    if (cmd_no == HostCmd_CMD_802_11_SCAN)
+        wlan_queue_scan_cmd(pmpriv, pcmd_node);
+    else
+        wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node, MTRUE);
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function inserts command node to cmd_free_q
+ *              after cleaning it.
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pcmd_node    A pointer to cmd_ctrl_node structure
+ *
+ *  @return             N/A
+ */
+t_void
+wlan_insert_cmd_to_free_q(IN mlan_adapter * pmadapter,
+                          IN cmd_ctrl_node * pcmd_node)
+{
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
+    mlan_ioctl_req *pioctl_req = MNULL;
+    ENTER();
+
+    if (pcmd_node == MNULL)
+        goto done;
+    if (pcmd_node->pioctl_buf) {
+        pioctl_req = (mlan_ioctl_req *) pcmd_node->pioctl_buf;
+        if (pioctl_req->status_code != MLAN_ERROR_NO_ERROR)
+            pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
+                                     pioctl_req, MLAN_STATUS_FAILURE);
+        else
+            pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
+                                     pioctl_req, MLAN_STATUS_SUCCESS);
+    }
+    /* Clean the node */
+    wlan_clean_cmd_node(pmadapter, pcmd_node);
+
+    /* Insert node into cmd_free_q */
+    util_enqueue_list_tail(&pmadapter->cmd_free_q,
+                           (pmlan_linked_list) pcmd_node,
+                           pmadapter->callbacks.moal_spin_lock,
+                           pmadapter->callbacks.moal_spin_unlock);
+  done:
+    LEAVE();
+}
+
+/** 
+ *  @brief This function queues the command to cmd list.
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pcmd_node    A pointer to cmd_ctrl_node structure
+ *  @param add_tail      Specify if the cmd needs to be queued in the header or tail
+ *
+ *  @return             N/A
+ */
+t_void
+wlan_insert_cmd_to_pending_q(IN mlan_adapter * pmadapter,
+                             IN cmd_ctrl_node * pcmd_node, IN t_u32 add_tail)
+{
+    HostCmd_DS_COMMAND *pcmd = MNULL;
+    t_u16 command;
+
+    ENTER();
+
+    if (pcmd_node == MNULL) {
+        PRINTM(MERROR, "QUEUE_CMD: pcmd_node is MNULL\n");
+        goto done;
+    }
+
+    pcmd =
+        (HostCmd_DS_COMMAND *) (pcmd_node->cmdbuf->pbuf +
+                                pcmd_node->cmdbuf->data_offset);
+    if (pcmd == MNULL) {
+        PRINTM(MERROR, "QUEUE_CMD: pcmd is MNULL\n");
+        goto done;
+    }
+
+    command = wlan_le16_to_cpu(pcmd->command);
+
+/* Exit_PS command needs to be queued in the header always. */
+    if (command == HostCmd_CMD_802_11_PS_MODE_ENH) {
+        HostCmd_DS_802_11_PS_MODE_ENH *pm = &pcmd->params.psmode_enh;
+        if (wlan_le16_to_cpu(pm->action) == DIS_PS) {
+            if (pmadapter->ps_state != PS_STATE_AWAKE)
+                add_tail = MFALSE;
+        }
+    }
+
+    if (add_tail) {
+        util_enqueue_list_tail(&pmadapter->cmd_pending_q,
+                               (pmlan_linked_list) pcmd_node,
+                               pmadapter->callbacks.moal_spin_lock,
+                               pmadapter->callbacks.moal_spin_unlock);
+    } else {
+        util_enqueue_list_head(&pmadapter->cmd_pending_q,
+                               (pmlan_linked_list) pcmd_node,
+                               pmadapter->callbacks.moal_spin_lock,
+                               pmadapter->callbacks.moal_spin_unlock);
+    }
+
+    PRINTM(MCMND, "QUEUE_CMD: cmd=0x%x is queued\n", command);
+
+  done:
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function executes next command in command
+ *      pending queue. It will put firmware back to PS mode
+ *      if applicable.
+ * 
+ *  @param pmadapter     A pointer to mlan_adapter structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE 
+ */
+mlan_status
+wlan_exec_next_cmd(mlan_adapter * pmadapter)
+{
+    mlan_private *priv = MNULL;
+    cmd_ctrl_node *pcmd_node = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    HostCmd_DS_COMMAND *pcmd;
+
+    ENTER();
+
+    /* Sanity test */
+    if (pmadapter == MNULL) {
+        PRINTM(MERROR, "EXEC_NEXT_CMD: pmadapter is MNULL\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    /* Check if already in processing */
+    if (pmadapter->curr_cmd) {
+        PRINTM(MERROR, "EXEC_NEXT_CMD: there is command in processing!\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    wlan_request_cmd_lock(pmadapter);
+    /* Check if any command is pending */
+    pcmd_node = (cmd_ctrl_node *) util_peek_list(&pmadapter->cmd_pending_q,
+                                                 pmadapter->callbacks.
+                                                 moal_spin_lock,
+                                                 pmadapter->callbacks.
+                                                 moal_spin_unlock);
+
+    if (pcmd_node) {
+        pcmd =
+            (HostCmd_DS_COMMAND *) (pcmd_node->cmdbuf->pbuf +
+                                    pcmd_node->cmdbuf->data_offset);
+        priv = pcmd_node->priv;
+
+        if (pmadapter->ps_state != PS_STATE_AWAKE) {
+            PRINTM(MERROR,
+                   "Cannot send command in sleep state, this should not happen\n");
+            wlan_release_cmd_lock(pmadapter);
+            goto done;
+        }
+
+        util_unlink_list(&pmadapter->cmd_pending_q,
+                         (pmlan_linked_list) pcmd_node,
+                         pmadapter->callbacks.moal_spin_lock,
+                         pmadapter->callbacks.moal_spin_unlock);
+        wlan_release_cmd_lock(pmadapter);
+        ret = wlan_dnld_cmd_to_fw(priv, pcmd_node);
+        priv = wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY);
+        /* Any command sent to the firmware when host is in sleep mode, should
+           de-configure host sleep */
+        /* We should skip the host sleep configuration command itself though */
+        if (priv &&
+            (pcmd->command !=
+             wlan_cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
+            if (pmadapter->hs_activated == MTRUE) {
+                pmadapter->is_hs_configured = MFALSE;
+                wlan_host_sleep_activated_event(priv, MFALSE);
+            }
+        }
+        goto done;
+    } else {
+        wlan_release_cmd_lock(pmadapter);
+    }
+    ret = MLAN_STATUS_SUCCESS;
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function handles the command response
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_process_cmdresp(mlan_adapter * pmadapter)
+{
+    HostCmd_DS_COMMAND *resp = MNULL;
+    mlan_private *pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY);
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 orig_cmdresp_no;
+    t_u16 cmdresp_no;
+    t_u16 cmdresp_result;
+    mlan_ioctl_req *pioctl_buf = MNULL;
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
+    t_u32 sec, usec;
+
+    ENTER();
+
+    /* Now we got response from FW, cancel the command timer */
+    if (pmadapter->cmd_timer_is_set) {
+        /* Cancel command timeout timer */
+        pcb->moal_stop_timer(pmadapter->pmlan_cmd_timer);
+        /* Cancel command timeout timer */
+        pmadapter->cmd_timer_is_set = MFALSE;
+    }
+
+    if (!pmadapter->curr_cmd || !pmadapter->curr_cmd->respbuf) {
+        resp = (HostCmd_DS_COMMAND *) pmadapter->upld_buf;
+        resp->command = wlan_le16_to_cpu(resp->command);
+        PRINTM(MERROR, "CMD_RESP: MNULL curr_cmd, 0x%x\n", resp->command);
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    if (pmadapter->curr_cmd->pioctl_buf != MNULL) {
+        pioctl_buf = (mlan_ioctl_req *) pmadapter->curr_cmd->pioctl_buf;
+    }
+
+    pmadapter->num_cmd_timeout = 0;
+
+    DBG_HEXDUMP(MCMD_D, "CMD_RESP",
+                pmadapter->curr_cmd->respbuf->pbuf +
+                pmadapter->curr_cmd->respbuf->data_offset, pmadapter->upld_len);
+
+    resp =
+        (HostCmd_DS_COMMAND *) (pmadapter->curr_cmd->respbuf->pbuf +
+                                pmadapter->curr_cmd->respbuf->data_offset);
+    if (pmadapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
+        /* Copy original response back to response buffer */
+        wlan_ret_host_cmd(pmpriv, resp, pioctl_buf);
+    }
+    resp->command = wlan_le16_to_cpu(resp->command);
+    resp->size = wlan_le16_to_cpu(resp->size);
+    resp->seq_num = wlan_le16_to_cpu(resp->seq_num);
+    resp->result = wlan_le16_to_cpu(resp->result);
+
+    orig_cmdresp_no = resp->command;
+    cmdresp_result = resp->result;
+
+    /* Save the last command response to debug log */
+    pmadapter->dbg.last_cmd_resp_index =
+        (pmadapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
+    pmadapter->dbg.last_cmd_resp_id[pmadapter->dbg.last_cmd_resp_index] =
+        orig_cmdresp_no;
+
+    pmadapter->callbacks.moal_get_system_time(&sec, &usec);
+    PRINTM(MCMND, "CMD_RESP (%lu.%lu): 0x%x, result %d, len %d, seqno %d\n",
+           sec, usec, orig_cmdresp_no, cmdresp_result, resp->size,
+           resp->seq_num);
+
+    if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
+        PRINTM(MERROR, "CMD_RESP: Invalid response to command!");
+        if (pioctl_buf) {
+            pioctl_buf->status_code = MLAN_ERROR_FW_CMDRESP;
+        }
+        wlan_insert_cmd_to_free_q(pmadapter, pmadapter->curr_cmd);
+        wlan_request_cmd_lock(pmadapter);
+        pmadapter->curr_cmd = MNULL;
+        wlan_release_cmd_lock(pmadapter);
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Get BSS number and corresponding priv */
+    pmpriv = pmadapter->priv[HostCmd_GET_BSS_NO(resp->command)];
+    if (!pmpriv)
+        pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY);
+    /* Clear RET_BIT & BSS_NO_BITS from HostCmd */
+    resp->command &= HostCmd_CMD_ID_MASK;
+    cmdresp_no = resp->command;
+
+    if (pmadapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
+        pmadapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD;
+        if ((cmdresp_result == HostCmd_RESULT_OK)
+            && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
+            ret = wlan_ret_802_11_hs_cfg(pmpriv, resp, pioctl_buf);
+    } else {
+        /* handle response */
+        ret = pmpriv->ops.process_cmdresp(pmpriv, cmdresp_no, resp, pioctl_buf);
+    }
+
+    if ((pmadapter->hw_status == WlanHardwareStatusInitializing) &&
+        (pmadapter->last_init_cmd == cmdresp_no)) {
+        if (cmdresp_result == HostCmd_RESULT_OK)
+            pmadapter->hw_status = WlanHardwareStatusInitdone;
+        else
+            wlan_init_fw_complete(pmadapter);
+    }
+
+    if (pmadapter->curr_cmd) {
+        pioctl_buf = (mlan_ioctl_req *) pmadapter->curr_cmd->pioctl_buf;
+        if (pioctl_buf && (ret == MLAN_STATUS_SUCCESS))
+            pioctl_buf->status_code = MLAN_ERROR_NO_ERROR;
+
+        /* Clean up and put current command back to cmd_free_q */
+        wlan_insert_cmd_to_free_q(pmadapter, pmadapter->curr_cmd);
+
+        wlan_request_cmd_lock(pmadapter);
+        pmadapter->curr_cmd = MNULL;
+        wlan_release_cmd_lock(pmadapter);
+    }
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function handles the timeout of command sending.
+ *  It will re-send the same command again.
+ *  
+ *  @param function_context   A pointer to function_context
+ *  @return 	   n/a
+ */
+t_void
+wlan_cmd_timeout_func(t_void * function_context)
+{
+    mlan_adapter *pmadapter = (mlan_adapter *) function_context;
+    cmd_ctrl_node *pcmd_node = MNULL;
+    mlan_ioctl_req *pioctl_buf = MNULL;
+    t_u32 sec, usec;
+    t_u8 i;
+    ENTER();
+
+    pmadapter->cmd_timer_is_set = MFALSE;
+    pmadapter->num_cmd_timeout++;
+    pmadapter->dbg.num_cmd_timeout++;
+    if (!pmadapter->curr_cmd) {
+        PRINTM(MWARN, "CurCmd Empty\n");
+        goto exit;
+    }
+    pcmd_node = pmadapter->curr_cmd;
+    if (pcmd_node->pioctl_buf != MNULL) {
+        pioctl_buf = (mlan_ioctl_req *) pcmd_node->pioctl_buf;
+        pioctl_buf->status_code = MLAN_ERROR_CMD_TIMEOUT;
+    }
+
+    if (pcmd_node) {
+        pmadapter->dbg.timeout_cmd_id =
+            pmadapter->dbg.last_cmd_id[pmadapter->dbg.last_cmd_index];
+        pmadapter->dbg.timeout_cmd_act =
+            pmadapter->dbg.last_cmd_act[pmadapter->dbg.last_cmd_index];
+        pmadapter->callbacks.moal_get_system_time(&sec, &usec);
+        PRINTM(MERROR, "Timeout cmd id (%lu.%lu) = 0x%x, act = 0x%x \n", sec,
+               usec, pmadapter->dbg.timeout_cmd_id,
+               pmadapter->dbg.timeout_cmd_act);
+
+        PRINTM(MERROR, "num_data_h2c_failure = %d\n",
+               pmadapter->dbg.num_tx_host_to_card_failure);
+        PRINTM(MERROR, "num_cmd_h2c_failure = %d\n",
+               pmadapter->dbg.num_cmd_host_to_card_failure);
+
+        PRINTM(MERROR, "num_cmd_timeout = %d\n",
+               pmadapter->dbg.num_cmd_timeout);
+        PRINTM(MERROR, "num_tx_timeout = %d\n", pmadapter->dbg.num_tx_timeout);
+
+        PRINTM(MERROR, "last_cmd_index = %d\n", pmadapter->dbg.last_cmd_index);
+        PRINTM(MERROR, "last_cmd_id = ");
+        for (i = 0; i < DBG_CMD_NUM; i++) {
+            PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_id[i]);
+        }
+        PRINTM(MMSG, "\n");
+        PRINTM(MERROR, "last_cmd_act = ");
+        for (i = 0; i < DBG_CMD_NUM; i++) {
+            PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_act[i]);
+        }
+        PRINTM(MMSG, "\n");
+        PRINTM(MERROR, "last_cmd_resp_index = %d\n",
+               pmadapter->dbg.last_cmd_resp_index);
+        PRINTM(MERROR, "last_cmd_resp_id = ");
+        for (i = 0; i < DBG_CMD_NUM; i++) {
+            PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_cmd_resp_id[i]);
+        }
+        PRINTM(MMSG, "\n");
+
+        PRINTM(MERROR, "last_event_index = %d\n",
+               pmadapter->dbg.last_event_index);
+        PRINTM(MERROR, "last_event = ");
+        for (i = 0; i < DBG_CMD_NUM; i++) {
+            PRINTM(MERROR, "0x%x ", pmadapter->dbg.last_event[i]);
+        }
+        PRINTM(MMSG, "\n");
+
+        PRINTM(MERROR, "data_sent=%d cmd_sent=%d\n", pmadapter->data_sent,
+               pmadapter->cmd_sent);
+
+        PRINTM(MERROR, "ps_mode=%d ps_state=%d\n", pmadapter->ps_mode,
+               pmadapter->ps_state);
+    }
+    if (pmadapter->hw_status == WlanHardwareStatusInitializing)
+        wlan_init_fw_complete(pmadapter);
+  exit:
+    LEAVE();
+    return;
+}
+
+/**
+ *  @brief Cancel all pending cmd.
+ *  
+ *  @param pmadapter	A pointer to mlan_adapter
+ *
+ *  @return		N/A
+ */
+void
+wlan_cancel_all_pending_cmd(pmlan_adapter pmadapter)
+{
+    cmd_ctrl_node *pcmd_node = MNULL;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    mlan_ioctl_req *pioctl_buf = MNULL;
+
+    /* Cancel current cmd */
+    if ((pmadapter->curr_cmd) && (pmadapter->curr_cmd->pioctl_buf)) {
+        pioctl_buf = (mlan_ioctl_req *) pmadapter->curr_cmd->pioctl_buf;
+        wlan_request_cmd_lock(pmadapter);
+        pmadapter->curr_cmd->pioctl_buf = MNULL;
+        wlan_release_cmd_lock(pmadapter);
+        pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
+        pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
+                                 MLAN_STATUS_FAILURE);
+    }
+    /* Cancel all pending command */
+    while ((pcmd_node =
+            (cmd_ctrl_node *) util_peek_list(&pmadapter->cmd_pending_q,
+                                             pcb->moal_spin_lock,
+                                             pcb->moal_spin_unlock))) {
+        util_unlink_list(&pmadapter->cmd_pending_q,
+                         (pmlan_linked_list) pcmd_node, pcb->moal_spin_lock,
+                         pcb->moal_spin_unlock);
+        if (pcmd_node->pioctl_buf) {
+            pioctl_buf = (mlan_ioctl_req *) pcmd_node->pioctl_buf;
+            pioctl_buf->status_code = MLAN_ERROR_CMD_CANCEL;
+            pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_buf,
+                                     MLAN_STATUS_FAILURE);
+            pcmd_node->pioctl_buf = MNULL;
+        }
+        wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
+    }
+    /* Cancel all pending scan command */
+    while ((pcmd_node =
+            (cmd_ctrl_node *) util_peek_list(&pmadapter->scan_pending_q,
+                                             pcb->moal_spin_lock,
+                                             pcb->moal_spin_unlock))) {
+        util_unlink_list(&pmadapter->scan_pending_q,
+                         (pmlan_linked_list) pcmd_node, pcb->moal_spin_lock,
+                         pcb->moal_spin_unlock);
+        pcmd_node->pioctl_buf = MNULL;
+        wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
+    }
+    wlan_request_cmd_lock(pmadapter);
+    pmadapter->scan_processing = MFALSE;
+    wlan_release_cmd_lock(pmadapter);
+}
+
+/**
+ *  @brief Cancel pending ioctl cmd.
+ *  
+ *  @param pmadapter	A pointer to mlan_adapter
+ *  @param pioctl_req	A pointer to mlan_ioctl_req buf
+ *
+ *  @return		N/A
+ */
+void
+wlan_cancel_pending_ioctl(pmlan_adapter pmadapter, pmlan_ioctl_req pioctl_req)
+{
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    cmd_ctrl_node *pcmd_node = MNULL;
+
+    ENTER();
+
+    PRINTM(MCMND, "MOAL Cancel IOCTL: 0x%x sub_id=0x%x action=%d\n",
+           pioctl_req->req_id, *((t_u32 *) pioctl_req->pbuf),
+           (int) pioctl_req->action);
+
+    if ((pmadapter->curr_cmd) &&
+        (pmadapter->curr_cmd->pioctl_buf == pioctl_req)) {
+        wlan_request_cmd_lock(pmadapter);
+        pcmd_node = pmadapter->curr_cmd;
+        pcmd_node->pioctl_buf = MNULL;
+        wlan_release_cmd_lock(pmadapter);
+    }
+
+    wlan_request_cmd_lock(pmadapter);
+    while ((pcmd_node =
+            wlan_get_pending_ioctl_cmd(pmadapter, pioctl_req)) != MNULL) {
+        util_unlink_list(&pmadapter->cmd_pending_q,
+                         (pmlan_linked_list) pcmd_node,
+                         pmadapter->callbacks.moal_spin_lock,
+                         pmadapter->callbacks.moal_spin_unlock);
+        pcmd_node->pioctl_buf = MNULL;
+        wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
+    }
+    wlan_release_cmd_lock(pmadapter);
+    if (pioctl_req->req_id == MLAN_IOCTL_SCAN) {
+        /* Cancel all pending scan command */
+        while ((pcmd_node =
+                (cmd_ctrl_node *) util_peek_list(&pmadapter->scan_pending_q,
+                                                 pcb->moal_spin_lock,
+                                                 pcb->moal_spin_unlock))) {
+            util_unlink_list(&pmadapter->scan_pending_q,
+                             (pmlan_linked_list) pcmd_node, pcb->moal_spin_lock,
+                             pcb->moal_spin_unlock);
+            pcmd_node->pioctl_buf = MNULL;
+            wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
+        }
+        wlan_request_cmd_lock(pmadapter);
+        pmadapter->scan_processing = MFALSE;
+        wlan_release_cmd_lock(pmadapter);
+    }
+    pioctl_req->status_code = MLAN_ERROR_CMD_CANCEL;
+    pcb->moal_ioctl_complete(pmadapter->pmoal_handle, pioctl_req,
+                             MLAN_STATUS_FAILURE);
+
+    LEAVE();
+    return;
+}
+
+/**
+ *  @brief This function checks conditions and prepares to
+ *              send sleep confirm command to firmware if OK.
+ * 
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *
+ *  @return             N/A
+ */
+t_void
+wlan_check_ps_cond(mlan_adapter * pmadapter)
+{
+    ENTER();
+
+    if (!pmadapter->cmd_sent &&
+        !pmadapter->curr_cmd && !IS_CARD_RX_RCVD(pmadapter)) {
+        wlan_dnld_sleep_confirm_cmd(pmadapter);
+    } else {
+        PRINTM(MCMND, "Delay Sleep Confirm (%s%s%s)\n",
+               (pmadapter->cmd_sent) ? "D" : "",
+               (pmadapter->curr_cmd) ? "C" : "",
+               (IS_CARD_RX_RCVD(pmadapter)) ? "R" : "");
+    }
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function sends the HS_ACTIVATED event to the application
+ *   
+ *  @param priv         A pointer to mlan_private structure
+ *  @param activated    MTRUE if activated, MFALSE if de-activated
+ *
+ *  @return             None
+ */
+t_void
+wlan_host_sleep_activated_event(pmlan_private priv, t_u8 activated)
+{
+    ENTER();
+
+    if (activated) {
+        if (priv->adapter->is_hs_configured) {
+            priv->adapter->hs_activated = MTRUE;
+            PRINTM(MEVENT, "hs_actived\n");
+            wlan_recv_event(priv, MLAN_EVENT_ID_DRV_HS_ACTIVATED, MNULL);
+        } else
+            PRINTM(MWARN, "hs_activated: HS not configured !!!\n");
+    } else {
+        PRINTM(MEVENT, "hs_deactived\n");
+        priv->adapter->hs_activated = MFALSE;
+        wlan_recv_event(priv, MLAN_EVENT_ID_DRV_HS_DEACTIVATED, MNULL);
+    }
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function sends the HS_WAKEUP event to the application
+ *   
+ *  @param priv         A pointer to mlan_private structure
+ *
+ *  @return             None
+ */
+t_void
+wlan_host_sleep_wakeup_event(pmlan_private priv)
+{
+    ENTER();
+
+    if (priv->adapter->is_hs_configured) {
+        wlan_recv_event(priv, MLAN_EVENT_ID_FW_HS_WAKEUP, MNULL);
+    } else {
+        PRINTM(MWARN, "hs_wakeup: Host Sleep not configured !!!\n");
+    }
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function handles the command response of hs_cfg
+ * 
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_802_11_hs_cfg(IN pmlan_private pmpriv,
+                       IN HostCmd_DS_COMMAND * resp,
+                       IN mlan_ioctl_req * pioctl_buf)
+{
+    pmlan_adapter pmadapter = pmpriv->adapter;
+    HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg = &resp->params.opt_hs_cfg;
+    ENTER();
+
+    if (phs_cfg->action == HS_ACTIVATE) {
+        wlan_host_sleep_activated_event(pmpriv, MTRUE);
+        goto done;
+    } else {
+        phs_cfg->params.hs_config.conditions =
+            wlan_le32_to_cpu(phs_cfg->params.hs_config.conditions);
+        PRINTM(MCMND,
+               "CMD_RESP: HS_CFG cmd reply result=%#x,"
+               " conditions=0x%x gpio=0x%x gap=0x%x\n", resp->result,
+               phs_cfg->params.hs_config.conditions,
+               phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap);
+    }
+    if (phs_cfg->params.hs_config.conditions != HOST_SLEEP_CFG_CANCEL) {
+        pmadapter->is_hs_configured = MTRUE;
+    } else {
+        pmadapter->is_hs_configured = MFALSE;
+        if (pmadapter->hs_activated)
+            wlan_host_sleep_activated_event(pmpriv, MFALSE);
+    }
+  done:
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Perform hs related activities on receving the power up interrupt
+ *  
+ *  @param pmadapter  A pointer to the adapter structure
+ *  @return           N/A
+ */
+t_void
+wlan_process_hs_config(pmlan_adapter pmadapter)
+{
+    PRINTM(MINFO,
+           "Auto Cancelling host sleep since there is some interrupt from the firmware\n");
+    wlan_pm_wakeup_card(pmadapter);
+    pmadapter->hs_activated = MFALSE;
+    pmadapter->is_hs_configured = MFALSE;
+    wlan_host_sleep_activated_event(wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY),
+                                    MFALSE);
+    return;
+}
+
+/** 
+ *  @brief Check sleep confirm command response and set the state to ASLEEP
+ *  
+ *  @param pmadapter  A pointer to the adapter structure
+ *  @param pbuf       A pointer to the command response buffer
+ *  @param upld_len   Command response buffer length
+ *  @return           N/A
+ */
+void
+wlan_process_sleep_confirm_resp(pmlan_adapter pmadapter, t_u8 * pbuf,
+                                t_u32 upld_len)
+{
+    HostCmd_DS_COMMAND *cmd;
+    pmlan_private pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY);
+
+    ENTER();
+
+    if (!upld_len) {
+        PRINTM(MERROR, "Command size is 0\n");
+        LEAVE();
+        return;
+    }
+    cmd = (HostCmd_DS_COMMAND *) pbuf;
+    cmd->result = wlan_le16_to_cpu(cmd->result);
+    cmd->command = wlan_le16_to_cpu(cmd->command);
+
+    /* Get BSS number and corresponding priv */
+    pmpriv = pmadapter->priv[HostCmd_GET_BSS_NO(cmd->command)];
+    if (!pmpriv)
+        pmpriv = wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY);
+    /* Clear RET_BIT & BSS_NO_BITS from HostCmd */
+    cmd->command &= HostCmd_CMD_ID_MASK;
+
+    if (cmd->command != HostCmd_CMD_802_11_PS_MODE_ENH) {
+        PRINTM(MERROR,
+               "Received unexpected response for command %x, result = %x\n",
+               cmd->command, cmd->result);
+        return;
+    }
+    PRINTM(MEVENT, "#\n");
+    if ((pmpriv->media_connected != MTRUE) || !pmadapter->sleep_period.period)
+        pmadapter->pm_wakeup_card_req = MTRUE;
+
+    if (cmd->result != MLAN_STATUS_SUCCESS) {
+        PRINTM(MERROR, "Sleep confirm command failed\n");
+        LEAVE();
+        return;
+    }
+    if (pmadapter->is_hs_configured && !pmadapter->sleep_period.period) {
+        wlan_host_sleep_activated_event(wlan_get_priv
+                                        (pmadapter, MLAN_BSS_TYPE_ANY), MTRUE);
+    }
+    pmadapter->ps_state = PS_STATE_SLEEP;
+    LEAVE();
+}
diff --git a/wlan_src/mlan/mlan_decl.h b/wlan_src/mlan/mlan_decl.h
new file mode 100755
index 0000000..0ce78a7
--- /dev/null
+++ b/wlan_src/mlan/mlan_decl.h
@@ -0,0 +1,600 @@
+/** @file mlan_decl.h
+ *
+ *  @brief This file declares the generic data structures and APIs.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    11/07/2008: initial version
+******************************************************/
+
+#ifndef _MLAN_DECL_H_
+#define _MLAN_DECL_H_
+
+/** MLAN release version */
+#define MLAN_RELEASE_VERSION		"074"
+
+/** Re-define generic data types for MLAN/MOAL */
+/** Signed char (1-byte) */
+typedef char t_s8;
+/** Unsigned char (1-byte) */
+typedef unsigned char t_u8;
+/** Signed short (2-bytes) */
+typedef short t_s16;
+/** Unsigned short (2-bytes) */
+typedef unsigned short t_u16;
+/** Signed long (4-bytes) */
+typedef long t_s32;
+/** Unsigned long (4-bytes) */
+typedef unsigned long t_u32;
+/** Signed long long 8-bytes) */
+typedef long long t_s64;
+/** Unsigned long long 8-bytes) */
+typedef unsigned long long t_u64;
+/** Void pointer (4-bytes) */
+typedef void t_void;
+
+/** Constants below */
+
+#ifdef __GNUC__
+/** Structure packing begins */
+#define MLAN_PACK_START
+/** Structure packeing end */
+#define MLAN_PACK_END  __attribute__ ((packed))
+#else /* !__GNUC__ */
+#ifdef PRAGMA_PACK
+/** Structure packing begins */
+#define MLAN_PACK_START
+/** Structure packeing end */
+#define MLAN_PACK_END
+#else /* !PRAGMA_PACK */
+/** Structure packing begins */
+#define MLAN_PACK_START   __packed
+/** Structure packeing end */
+#define MLAN_PACK_END
+#endif /* PRAGMA_PACK */
+#endif /* __GNUC__ */
+
+#ifdef __GNUC__
+#define	INLINE	inline
+#else
+#define	INLINE	__inline
+#endif
+
+/** MLAN TRUE */
+#define MTRUE                    (1)
+/** MLAN FALSE */
+#define MFALSE                   (0)
+
+/** Macros for Data Alignment : size */
+#define ALIGN_SZ(p, a)	\
+	(((p) + ((a) - 1)) & ~((a) - 1))
+
+/** Macros for Data Alignment : address */
+#define ALIGN_ADDR(p, a)	\
+	((((t_u32)(p)) + (((t_u32)(a)) - 1)) & ~(((t_u32)(a)) - 1))
+
+/** Maximum BSS numbers */
+#define MLAN_MAX_BSS_NUM         (1)
+
+/* NET IP alignment */
+#define MLAN_NET_IP_ALIGN        0
+
+/** Minimum data header length */
+#define MLAN_MIN_DATA_HEADER_LEN 32     // (sizeof(mlan_txpd))
+
+/** This is current limit on Maximum AMPDU allowed */
+#define MLAN_MAX_BASTREAM_SUPPORTED     2
+
+/** Default Win size attached during ADDBA request */
+#define MLAN_AMPDU_DEF_TXWINSIZE        32
+/** Default Win size attached during ADDBA response */
+#define MLAN_AMPDU_DEF_RXWINSIZE        16
+/** Block ack timeout value */
+#define MLAN_DEFAULT_BLOCK_ACK_TIMEOUT  0xffff
+
+/** Rate index for HR/DSSS 0 */
+#define MLAN_RATE_INDEX_HRDSSS0 0
+/** Rate index for HR/DSSS 3 */
+#define MLAN_RATE_INDEX_HRDSSS3 3
+/** Rate index for OFDM 0 */
+#define MLAN_RATE_INDEX_OFDM0   4
+/** Rate index for OFDM 7 */
+#define MLAN_RATE_INDEX_OFDM7   11
+/** Rate index for MCS 0 */
+#define MLAN_RATE_INDEX_MCS0    12
+/** Rate index for MCS 7 */
+#define MLAN_RATE_INDEX_MCS7    19
+/** Rate index for MCS 32 */
+#define MLAN_RATE_INDEX_MCS32   44
+/** Rate index for MCS 127 */
+#define MLAN_RATE_INDEX_MCS127  139
+
+/** Rate bitmap for OFDM 0 */
+#define MLAN_RATE_BITMAP_OFDM0  16
+/** Rate bitmap for OFDM 7 */
+#define MLAN_RATE_BITMAP_OFDM7  23
+/** Rate bitmap for MCS 0 */
+#define MLAN_RATE_BITMAP_MCS0   32
+/** Rate bitmap for MCS 127 */
+#define MLAN_RATE_BITMAP_MCS127 159
+
+/** Size of rx data buffer */
+#define MLAN_RX_DATA_BUF_SIZE     (4 * 1024)
+/** Size of rx command buffer */
+#define MLAN_RX_CMD_BUF_SIZE      (2 * 1024)
+
+/** MLAN MAC Address Length */
+#define MLAN_MAC_ADDR_LENGTH     (6)
+/** MLAN 802.11 MAC Address */
+typedef t_u8 mlan_802_11_mac_addr[MLAN_MAC_ADDR_LENGTH];
+
+/** MLAN Maximum SSID Length */
+#define MLAN_MAX_SSID_LENGTH     (32)
+
+/** RTS/FRAG related defines */
+/** Minimum RTS value */
+#define MLAN_RTS_MIN_VALUE              (0)
+/** Maximum RTS value */
+#define MLAN_RTS_MAX_VALUE              (2347)
+/** Minimum FRAG value */
+#define MLAN_FRAG_MIN_VALUE             (256)
+/** Maximum FRAG value */
+#define MLAN_FRAG_MAX_VALUE             (2346)
+
+/** Minimum tx retry count */
+#define MLAN_TX_RETRY_MIN 		(0)
+/** Maximum tx retry count */
+#define MLAN_TX_RETRY_MAX 		(14)
+
+/** define SDIO block size for firmware download */
+#define MLAN_SDIO_BLOCK_SIZE_FW_DNLD	256
+
+/** define SDIO block size for data Tx/Rx */
+/* We support up to 480-byte block size due to FW buffer limitation. */
+#define MLAN_SDIO_BLOCK_SIZE		256
+
+/** define allocated buffer size */
+#define ALLOC_BUF_SIZE           (4 * 1024)
+
+/** Max retry number of CMD53 write */
+#define MAX_WRITE_IOMEM_RETRY		2
+
+/** SDIO IO Port mask */
+#define MLAN_SDIO_IO_PORT_MASK		0xfffff
+/** SDIO Block/Byte mode mask */
+#define MLAN_SDIO_BYTE_MODE_MASK	0x80000000
+
+/** IN parameter */
+#define IN
+/** OUT parameter */
+#define OUT
+
+/** BIT value */
+#define MBIT(x)    (((t_u32)1) << (x))
+
+/** Buffer flag for requeued packet */
+#define MLAN_BUF_FLAG_REQUEUED_PKT      MBIT(0)
+
+#ifdef DEBUG_LEVEL1
+/** Debug level bit definition */
+#define	MMSG        MBIT(0)
+#define MFATAL      MBIT(1)
+#define MERROR      MBIT(2)
+#define MDATA       MBIT(3)
+#define MCMND       MBIT(4)
+#define MEVENT      MBIT(5)
+#define MINTR       MBIT(6)
+
+#define MDAT_D      MBIT(16)
+#define MCMD_D      MBIT(17)
+#define MFW_D       MBIT(18)
+
+#define MENTRY      MBIT(28)
+#define MWARN       MBIT(29)
+#define MINFO       MBIT(30)
+#define MHEX_DUMP   MBIT(31)
+#endif /* DEBUG_LEVEL1 */
+
+/** mlan_status */
+typedef enum _mlan_status
+{
+    MLAN_STATUS_FAILURE = 0xffffffff,
+    MLAN_STATUS_SUCCESS = 0,
+    MLAN_STATUS_PENDING,
+    MLAN_STATUS_RESOURCE,
+} mlan_status;
+
+/** mlan_error_code */
+typedef enum _mlan_error_code
+{
+    /** No error */
+    MLAN_ERROR_NO_ERROR = 0,
+    /** Firmware errors below (MSB=0) */
+    MLAN_ERROR_FW_NOT_READY = 0x00000001,
+    MLAN_ERROR_FW_BUSY,
+    MLAN_ERROR_FW_CMDRESP,
+    /** Driver errors below (MSB=1) */
+    MLAN_ERROR_PKT_SIZE_INVALID = 0x80000001,
+    MLAN_ERROR_PKT_TIMEOUT,
+    MLAN_ERROR_CMD_INVALID,
+    MLAN_ERROR_CMD_TIMEOUT,
+    MLAN_ERROR_CMD_DNLD_FAIL,
+    MLAN_ERROR_CMD_CANCEL,
+    MLAN_ERROR_ASSOC_FAIL,
+    MLAN_ERROR_EVENT_UNKNOWN,
+    MLAN_ERROR_INVALID_PARAMETER,
+    /** More to add */
+} mlan_error_code;
+
+/** mlan_buf_type */
+typedef enum _mlan_buf_type
+{
+    MLAN_BUF_TYPE_CMD = 1,
+    MLAN_BUF_TYPE_DATA,
+    MLAN_BUF_TYPE_EVENT,
+} mlan_buf_type;
+
+/** mlan_bss_type */
+typedef enum _mlan_bss_type
+{
+    MLAN_BSS_TYPE_STA = 0,
+    MLAN_BSS_TYPE_UAP,
+    MLAN_BSS_TYPE_ANY = 0xff,
+} mlan_bss_type;
+
+/** mlan_data_frame_type */
+typedef enum _mlan_data_frame_type
+{
+    MLAN_DATA_FRAME_TYPE_ETH_II = 0,
+    MLAN_DATA_FRAME_TYPE_802_11,
+} mlan_data_frame_type;
+
+/** mlan_event_id */
+typedef enum _mlan_event_id
+{
+    /* Event generated by firmware (MSB=0) */
+    MLAN_EVENT_ID_FW_UNKNOWN = 0x00000001,
+    MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED,
+    MLAN_EVENT_ID_FW_ADHOC_LINK_LOST,
+    MLAN_EVENT_ID_FW_DISCONNECTED,
+    MLAN_EVENT_ID_FW_MIC_ERR_UNI,
+    MLAN_EVENT_ID_FW_MIC_ERR_MUL,
+    MLAN_EVENT_ID_FW_BCN_RSSI_LOW,
+    MLAN_EVENT_ID_FW_BCN_RSSI_HIGH,
+    MLAN_EVENT_ID_FW_BCN_SNR_LOW,
+    MLAN_EVENT_ID_FW_BCN_SNR_HIGH,
+    MLAN_EVENT_ID_FW_MAX_FAIL,
+    MLAN_EVENT_ID_FW_DATA_RSSI_LOW,
+    MLAN_EVENT_ID_FW_DATA_RSSI_HIGH,
+    MLAN_EVENT_ID_FW_DATA_SNR_LOW,
+    MLAN_EVENT_ID_FW_DATA_SNR_HIGH,
+    MLAN_EVENT_ID_FW_LINK_QUALITY,
+    MLAN_EVENT_ID_FW_PORT_RELEASE = 17,
+    MLAN_EVENT_ID_FW_PRE_BCN_LOST,
+    MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE,
+    MLAN_EVENT_ID_FW_HS_WAKEUP,
+    MLAN_EVENT_ID_FW_DS_AWAKE,
+    MLAN_EVENT_ID_FW_BG_SCAN,
+    MLAN_EVENT_ID_FW_WEP_ICV_ERR,
+    MLAN_EVENT_ID_FW_STOP_TX,
+    MLAN_EVENT_ID_FW_START_TX,
+    MLAN_EVENT_ID_FW_BW_CHANGED,
+
+    /* Event generated by MLAN driver (MSB=1) */
+    MLAN_EVENT_ID_DRV_CONNECTED = 0x80000001,
+    MLAN_EVENT_ID_DRV_DEFER_HANDLING,
+    MLAN_EVENT_ID_DRV_HS_ACTIVATED,
+    MLAN_EVENT_ID_DRV_HS_DEACTIVATED,
+    MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM,
+    MLAN_EVENT_ID_DRV_PASSTHU,
+    MLAN_EVENT_ID_DRV_SCAN_REPORT,
+} mlan_event_id;
+
+/** Data Structures */
+/** mlan_image data structure */
+typedef struct _mlan_fw_image
+{
+    /** Helper image buffer pointer */
+    t_u8 *phelper_buf;
+    /** Helper image length */
+    t_u32 helper_len;
+    /** Firmware image buffer pointer */
+    t_u8 *pfw_buf;
+    /** Firmware image length */
+    t_u32 fw_len;
+} mlan_fw_image, *pmlan_fw_image;
+
+/** mlan_event data structure */
+typedef struct _mlan_event
+{
+    /** BSS index number for multiple BSS support */
+    t_u32 bss_num;
+    /** Event ID */
+    mlan_event_id event_id;
+    /** Event length */
+    t_u32 event_len;
+    /** Event buffer */
+    t_u8 event_buf[1];
+} mlan_event, *pmlan_event;
+
+/** mlan_ioctl_req data structure */
+typedef struct _mlan_ioctl_req
+{
+    /** Status code from firmware/driver */
+    t_u32 status_code;
+    /** BSS index number for multiple BSS support */
+    t_u32 bss_num;
+    /** Request id */
+    t_u32 req_id;
+    /** Action: set or get */
+    t_u32 action;
+    /** Pointer to buffer */
+    t_u8 *pbuf;
+    /** Length of buffer */
+    t_u32 buf_len;
+    /** Length of the data read/written in buffer */
+    t_u32 data_read_written;
+    /** Length of buffer needed */
+    t_u32 buf_len_needed;
+    /** Reserved for MOAL module */
+    t_u32 reserved_1;
+} mlan_ioctl_req, *pmlan_ioctl_req;
+
+/** mlan_buffer data structure */
+typedef struct _mlan_buffer
+{
+    /** Pointer to previous mlan_buffer */
+    struct _mlan_buffer *pprev;
+    /** Pointer to next mlan_buffer */
+    struct _mlan_buffer *pnext;
+    /** Status code from firmware/driver */
+    t_u32 status_code;
+    /** Flags for this buffer */
+    t_u32 flags;
+    /** BSS number */
+    t_u32 bss_num;
+    /** Buffer descriptor, e.g. skb in Linux */
+    t_void *pdesc;
+    /** Pointer to buffer */
+    t_u8 *pbuf;
+    /** Offset to data */
+    t_u32 data_offset;
+    /** Data length */
+    t_u32 data_len;
+    /** Buffer type: data, cmd, event etc. */
+    mlan_buf_type buf_type;
+
+    /** Fields below are valid for data packet only */
+    /** QoS priority */
+    t_u32 priority;
+    /** Time stamp when packet is received (seconds) */
+    t_u32 in_ts_sec;
+    /** Time stamp when packet is received (micro seconds) */
+    t_u32 in_ts_usec;
+    /** Time stamp when packet is processed (seconds) */
+    t_u32 out_ts_sec;
+    /** Time stamp when packet is processed (micro seconds) */
+    t_u32 out_ts_usec;
+
+    /** Fields below are valid for MLAN module only */
+    /** Pointer to parent mlan_buffer */
+    struct _mlan_buffer *pparent;
+    /** Use count for this buffer */
+    t_u32 use_count;
+} mlan_buffer, *pmlan_buffer;
+
+/** mlan_bss_attr data structure */
+typedef struct _mlan_bss_attr
+{
+    /** BSS type */
+    t_u32 bss_type;
+    /** Data frame type: Ethernet II, 802.11, etc. */
+    t_u32 frame_type;
+    /** The BSS is active (non-0) or not (0). */
+    t_u32 active;
+    /** BSS Priority */
+    t_u32 bss_priority;
+} mlan_bss_attr, *pmlan_bss_attr;
+
+#ifdef PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+
+/** Type enumeration for the command result */
+typedef MLAN_PACK_START enum _mlan_cmd_result_e
+{
+    MLAN_CMD_RESULT_SUCCESS = 0,
+    MLAN_CMD_RESULT_FAILURE = 1,
+    MLAN_CMD_RESULT_TIMEOUT = 2,
+    MLAN_CMD_RESULT_INVALID_DATA = 3
+} MLAN_PACK_END mlan_cmd_result_e;
+
+/** Type enumeration of WMM AC_QUEUES */
+typedef MLAN_PACK_START enum _mlan_wmm_ac_e
+{
+    WMM_AC_BK,
+    WMM_AC_BE,
+    WMM_AC_VI,
+    WMM_AC_VO
+} MLAN_PACK_END mlan_wmm_ac_e;
+
+/** Type enumeration for the action field in the Queue Config command */
+typedef MLAN_PACK_START enum _mlan_wmm_queue_config_action_e
+{
+    MLAN_WMM_QUEUE_CONFIG_ACTION_GET = 0,
+    MLAN_WMM_QUEUE_CONFIG_ACTION_SET = 1,
+    MLAN_WMM_QUEUE_CONFIG_ACTION_DEFAULT = 2,
+    MLAN_WMM_QUEUE_CONFIG_ACTION_MAX
+} MLAN_PACK_END mlan_wmm_queue_config_action_e;
+
+/** Type enumeration for the action field in the queue stats command */
+typedef MLAN_PACK_START enum _mlan_wmm_queue_stats_action_e
+{
+    MLAN_WMM_STATS_ACTION_START = 0,
+    MLAN_WMM_STATS_ACTION_STOP = 1,
+    MLAN_WMM_STATS_ACTION_GET_CLR = 2,
+    MLAN_WMM_STATS_ACTION_SET_CFG = 3,  /* Not currently used */
+    MLAN_WMM_STATS_ACTION_GET_CFG = 4,  /* Not currently used */
+    MLAN_WMM_STATS_ACTION_MAX
+} MLAN_PACK_END mlan_wmm_queue_stats_action_e;
+
+/** Max Ie length */
+#define MAX_IE_SIZE             256
+
+/** custom IE */
+typedef MLAN_PACK_START struct _custom_ie
+{
+    /** IE Index */
+    t_u16 ie_index;
+    /** Mgmt Subtype Mask */
+    t_u16 mgmt_subtype_mask;
+    /** IE Length */
+    t_u16 ie_length;
+    /** IE buffer */
+    t_u8 ie_buffer[MAX_IE_SIZE];
+} MLAN_PACK_END custom_ie;
+
+#ifdef PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+/** mlan_callbacks data structure */
+typedef struct _mlan_callbacks
+{
+    /** moal_init_fw_complete */
+    mlan_status(*moal_init_fw_complete) (IN t_void * pmoal_handle,
+                                         IN mlan_status status);
+    /** moal_shutdown_fw_complete */
+    mlan_status(*moal_shutdown_fw_complete) (IN t_void * pmoal_handle,
+                                             IN mlan_status status);
+    /** moal_send_packet_complete */
+    mlan_status(*moal_send_packet_complete) (IN t_void * pmoal_handle,
+                                             IN pmlan_buffer pmbuf,
+                                             IN mlan_status status);
+    /** moal_recv_complete */
+    mlan_status(*moal_recv_complete) (IN t_void * pmoal_handle,
+                                      IN pmlan_buffer pmbuf,
+                                      IN t_u32 port, IN mlan_status status);
+    /** moal_recv_packet */
+    mlan_status(*moal_recv_packet) (IN t_void * pmoal_handle,
+                                    IN pmlan_buffer pmbuf);
+    /** moal_recv_event */
+    mlan_status(*moal_recv_event) (IN t_void * pmoal_handle,
+                                   IN pmlan_event pmevent);
+    /** moal_ioctl_complete */
+    mlan_status(*moal_ioctl_complete) (IN t_void * pmoal_handle,
+                                       IN pmlan_ioctl_req pioctl_req,
+                                       IN mlan_status status);
+    /** moal_alloc_mlan_buffer */
+    mlan_status(*moal_alloc_mlan_buffer) (IN t_u32 size,
+                                          OUT pmlan_buffer * pmbuf);
+    /** moal_free_mlan_buffer */
+    mlan_status(*moal_free_mlan_buffer) (IN pmlan_buffer pmbuf);
+    /** moal_write_reg */
+    mlan_status(*moal_write_reg) (IN t_void * pmoal_handle,
+                                  IN t_u32 reg, IN t_u32 data);
+    /** moal_read_reg */
+    mlan_status(*moal_read_reg) (IN t_void * pmoal_handle,
+                                 IN t_u32 reg, OUT t_u32 * data);
+    /** moal_write_data_sync */
+    mlan_status(*moal_write_data_sync) (IN t_void * pmoal_handle,
+                                        IN pmlan_buffer pmbuf,
+                                        IN t_u32 port, IN t_u32 timeout);
+    /** moal_read_data_sync */
+    mlan_status(*moal_read_data_sync) (IN t_void * pmoal_handle,
+                                       IN OUT pmlan_buffer pmbuf,
+                                       IN t_u32 port, IN t_u32 timeout);
+    /** moal_malloc */
+    mlan_status(*moal_malloc) (IN t_u32 size, OUT t_u8 ** ppbuf);
+    /** moal_mfree */
+    mlan_status(*moal_mfree) (IN t_u8 * pbuf);
+    /** moal_memset */
+    t_void *(*moal_memset) (IN t_void * pmem, IN t_u8 byte, IN t_u32 num);
+    /** moal_memcpy */
+    t_void *(*moal_memcpy) (IN t_void * pdest,
+                            IN const t_void * psrc, IN t_u32 num);
+    /** moal_memmove */
+    t_void *(*moal_memmove) (IN t_void * pdest,
+                             IN const t_void * psrc, IN t_u32 num);
+    /** moal_memcmp */
+      t_s32(*moal_memcmp) (IN const t_void * pmem1,
+                           IN const t_void * pmem2, IN t_u32 num);
+    /** moal_get_system_time */
+      mlan_status(*moal_get_system_time) (OUT t_u32 * psec, OUT t_u32 * pusec);
+    /** moal_init_timer*/
+      mlan_status(*moal_init_timer) (OUT t_void ** pptimer,
+                                     IN t_void(*callback) (t_void * pcontext),
+                                     IN t_void * pcontext);
+    /** moal_free_timer */
+      mlan_status(*moal_free_timer) (IN t_void * ptimer);
+    /** moal_start_timer*/
+      mlan_status(*moal_start_timer) (IN t_void * ptimer,
+                                      IN t_u8 periodic, IN t_u32 msec);
+    /** moal_stop_timer*/
+      mlan_status(*moal_stop_timer) (IN t_void * ptimer);
+    /** moal_init_lock */
+      mlan_status(*moal_init_lock) (OUT t_void ** pplock);
+    /** moal_free_lock */
+      mlan_status(*moal_free_lock) (IN t_void * plock);
+    /** moal_spin_lock */
+      mlan_status(*moal_spin_lock) (IN t_void * plock);
+    /** moal_spin_unlock */
+      mlan_status(*moal_spin_unlock) (IN t_void * plock);
+    /** moal_print */
+      t_void(*moal_print) (IN t_u32 level, IN t_s8 * pformat, IN ...);
+} mlan_callbacks, *pmlan_callbacks;
+
+/** mlan_device data structure */
+typedef struct _mlan_device
+{
+    /** MOAL Handle */
+    t_void *pmoal_handle;
+    /** BSS Attributes */
+    mlan_bss_attr bss_attr[MLAN_MAX_BSS_NUM];
+    /** Callbacks */
+    mlan_callbacks callbacks;
+#ifdef MFG_CMD_SUPPORT
+    /** MFG mode */
+    t_u32 mfg_mode;
+#endif
+} mlan_device, *pmlan_device;
+
+/** MLAN API function prototype */
+#define MLAN_API
+
+/** Registration */
+MLAN_API mlan_status mlan_register(IN pmlan_device pmdevice,
+                                   OUT t_void ** ppmlan_adapter);
+
+/** Un-registration */
+MLAN_API mlan_status mlan_unregister(IN t_void * pmlan_adapter);
+
+/** Firmware Downloading */
+MLAN_API mlan_status mlan_dnld_fw(IN t_void * pmlan_adapter,
+                                  IN pmlan_fw_image pmfw);
+
+/** Firmware Initialization */
+MLAN_API mlan_status mlan_init_fw(IN t_void * pmlan_adapter);
+
+/** Firmware Shutdown */
+MLAN_API mlan_status mlan_shutdown_fw(IN t_void * pmlan_adapter);
+
+/** Main Process */
+MLAN_API mlan_status mlan_main_process(IN t_void * pmlan_adapter);
+
+/** Packet Transmission */
+MLAN_API mlan_status mlan_send_packet(IN t_void * pmlan_adapter,
+                                      IN pmlan_buffer pmbuf);
+
+/** interrupt handler */
+MLAN_API t_void mlan_interrupt(IN t_void * pmlan_adapter);
+
+/** mlan ioctl */
+MLAN_API mlan_status mlan_ioctl(IN t_void * pmlan_adapter,
+                                IN pmlan_ioctl_req pioctl_req);
+
+#endif /* !_MLAN_DECL_H_ */
diff --git a/wlan_src/mlan/mlan_fw.h b/wlan_src/mlan/mlan_fw.h
new file mode 100755
index 0000000..79aa037
--- /dev/null
+++ b/wlan_src/mlan/mlan_fw.h
@@ -0,0 +1,3118 @@
+/** @file mlan_fw.h
+ *
+ *  @brief This file contains firmware specific defines.
+ *  structures and declares global function prototypes used
+ *  in MLAN module.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    10/27/2008: initial version
+******************************************************/
+
+#ifndef _MLAN_FW_H_
+#define _MLAN_FW_H_
+
+/** Interface header length */
+#define INTF_HEADER_LEN     4
+
+/** Ethernet header */
+typedef struct
+{
+    /** Ethernet header destination address */
+    t_u8 dest_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Ethernet header source address */
+    t_u8 src_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Ethernet header length */
+    t_u16 h803_len;
+
+} Eth803Hdr_t;
+
+/** RFC 1042 header */
+typedef struct
+{
+    /** LLC DSAP */
+    t_u8 llc_dsap;
+    /** LLC SSAP */
+    t_u8 llc_ssap;
+    /** LLC CTRL */
+    t_u8 llc_ctrl;
+    /** SNAP OUI */
+    t_u8 snap_oui[3];
+    /** SNAP type */
+    t_u16 snap_type;
+
+} Rfc1042Hdr_t;
+
+/** Rx packet header */
+typedef struct
+{
+    /** Etherner header */
+    Eth803Hdr_t eth803_hdr;
+    /** RFC 1042 header */
+    Rfc1042Hdr_t rfc1042_hdr;
+
+} RxPacketHdr_t;
+
+/** Rates supported in band B */
+#define B_SUPPORTED_RATES               5
+/** Rates supported in band G */
+#define G_SUPPORTED_RATES               9
+/** Rates supported in band BG */
+#define BG_SUPPORTED_RATES              13
+
+/** Setup the number of rates passed in the driver/firmware API */
+#define A_SUPPORTED_RATES               9
+
+/** Setup the number of rates passed in the driver/firmware API */
+#define HOSTCMD_SUPPORTED_RATES         14
+
+/** Rates supported in band N */
+#define N_SUPPORTED_RATES               3
+/** All bands (B, G, N) */
+#define ALL_802_11_BANDS           (BAND_A | BAND_B | BAND_G | BAND_GN)
+
+/** Firmware multiple bands support */
+#define FW_MULTI_BANDS_SUPPORT  (MBIT(8) | MBIT(9) | MBIT(10) | MBIT(11))
+/** Check if multiple bands support is enabled in firmware */
+#define IS_SUPPORT_MULTI_BANDS(_adapter)        \
+        (_adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT)
+/** Get default bands of the firmware */
+#define GET_FW_DEFAULT_BANDS(_adapter)  \
+        ((_adapter->fw_cap_info >> 8) & ALL_802_11_BANDS)
+
+extern t_u8 SupportedRates_B[B_SUPPORTED_RATES];
+extern t_u8 SupportedRates_G[G_SUPPORTED_RATES];
+extern t_u8 SupportedRates_BG[BG_SUPPORTED_RATES];
+extern t_u8 SupportedRates_A[A_SUPPORTED_RATES];
+extern t_u8 SupportedRates_N[N_SUPPORTED_RATES];
+extern t_u8 AdhocRates_G[G_SUPPORTED_RATES];
+extern t_u8 AdhocRates_B[B_SUPPORTED_RATES];
+extern t_u8 AdhocRates_BG[BG_SUPPORTED_RATES];
+extern t_u8 AdhocRates_A[A_SUPPORTED_RATES];
+
+/** WEP Key index mask */
+#define HostCmd_WEP_KEY_INDEX_MASK              0x3fff
+
+/** Key information enabled */
+#define KEY_INFO_ENABLED        0x01
+/** KEY_TYPE_ID */
+typedef enum _KEY_TYPE_ID
+{
+    /** Key type : WEP */
+    KEY_TYPE_ID_WEP = 0,
+    /** Key type : TKIP */
+    KEY_TYPE_ID_TKIP,
+    /** Key type : AES */
+    KEY_TYPE_ID_AES,
+    KEY_TYPE_ID_WAPI,
+} KEY_TYPE_ID;
+
+/** KEY_INFO_WEP*/
+typedef enum _KEY_INFO_WEP
+{
+    KEY_INFO_WEP_MCAST = 0x01,
+    KEY_INFO_WEP_UNICAST = 0x02,
+    KEY_INFO_WEP_ENABLED = 0x04
+} KEY_INFO_WEP;
+
+/** KEY_INFO_TKIP */
+typedef enum _KEY_INFO_TKIP
+{
+    KEY_INFO_TKIP_MCAST = 0x01,
+    KEY_INFO_TKIP_UNICAST = 0x02,
+    KEY_INFO_TKIP_ENABLED = 0x04
+} KEY_INFO_TKIP;
+
+/** KEY_INFO_AES*/
+typedef enum _KEY_INFO_AES
+{
+    KEY_INFO_AES_MCAST = 0x01,
+    KEY_INFO_AES_UNICAST = 0x02,
+    KEY_INFO_AES_ENABLED = 0x04
+} KEY_INFO_AES;
+
+/** WPA AES key length */
+#define WPA_AES_KEY_LEN                 16
+/** WPA TKIP key length */
+#define WPA_TKIP_KEY_LEN                32
+
+/** WAPI key length */
+#define WAPI_KEY_LEN            50
+/** KEY_INFO_WAPI*/
+typedef enum _KEY_INFO_WAPI
+{
+    KEY_INFO_WAPI_MCAST = 0x01,
+    KEY_INFO_WAPI_UNICAST = 0x02,
+    KEY_INFO_WAPI_ENABLED = 0x04
+} KEY_INFO_WAPI;
+
+/** Length of SNAP header */
+#define MRVDRV_SNAP_HEADER_LEN          8
+
+/** The number of times to try when polling for status bits */
+#define MAX_POLL_TRIES			100
+
+/** The number of times to try when waiting for downloaded firmware to 
+     become active when multiple interface is present */
+#define MAX_MULTI_INTERFACE_POLL_TRIES  1000
+
+/** The number of times to try when waiting for downloaded firmware to 
+     become active. (polling the scratch register). */
+#define MAX_FIRMWARE_POLL_TRIES		100
+
+/** This is for firmware specific length */
+#define EXTRA_LEN	36
+
+/** Maximum ethernet frame length sans FCS */
+#define MV_ETH_FRAME_LEN   1514
+
+/** Buffer size for ethernet Tx packets */
+#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \
+	(MV_ETH_FRAME_LEN + sizeof(TxPD) + EXTRA_LEN)
+
+/** Buffer size for ethernet Rx packets */
+#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \
+	(MV_ETH_FRAME_LEN + sizeof(RxPD) \
+	 + MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN)
+
+/* Macros in interface module */
+/** Firmware ready */
+#define FIRMWARE_READY          0xfedc
+
+/** Number of firmware blocks to transfer */
+#define FIRMWARE_TRANSFER_NBLOCK	2
+
+/** Enumeration definition*/
+/** WLAN_802_11_PRIVACY_FILTER */
+typedef enum _WLAN_802_11_PRIVACY_FILTER
+{
+    Wlan802_11PrivFilterAcceptAll,
+    Wlan802_11PrivFilter8021xWEP
+} WLAN_802_11_PRIVACY_FILTER;
+
+/** WLAN_802_11_WEP_STATUS */
+typedef enum _WLAN_802_11_WEP_STATUS
+{
+    Wlan802_11WEPEnabled,
+    Wlan802_11WEPDisabled,
+    Wlan802_11WEPKeyAbsent,
+    Wlan802_11WEPNotSupported
+} WLAN_802_11_WEP_STATUS;
+
+/** SNR calculation */
+#define CAL_SNR(RSSI, NF)		((t_s16)((t_s16)(RSSI)-(t_s16)(NF)))
+
+/** TLV  type ID definition */
+#define PROPRIETARY_TLV_BASE_ID                 0x0100
+
+/** Terminating TLV Type */
+#define MRVL_TERMINATE_TLV_ID                   0xffff
+
+/** TLV type : SSID */
+#define TLV_TYPE_SSID                           0x0000
+/** TLV type : Rates */
+#define TLV_TYPE_RATES                          0x0001
+/** TLV type : PHY FH */
+#define TLV_TYPE_PHY_FH                         0x0002
+/** TLV type : PHY DS */
+#define TLV_TYPE_PHY_DS                         0x0003
+/** TLV type : CF */
+#define TLV_TYPE_CF                             0x0004
+/** TLV type : IBSS */
+#define TLV_TYPE_IBSS                           0x0006
+
+/** TLV type : Domain */
+#define TLV_TYPE_DOMAIN                         0x0007
+
+/** TLV type : Power constraint */
+#define TLV_TYPE_POWER_CONSTRAINT               0x0020
+/** TLV type : Power capability */
+#define TLV_TYPE_POWER_CAPABILITY               0x0021
+
+/** TLV type : Key material */
+#define TLV_TYPE_KEY_MATERIAL       (PROPRIETARY_TLV_BASE_ID + 0)
+/** TLV type : Channel list */
+#define TLV_TYPE_CHANLIST           (PROPRIETARY_TLV_BASE_ID + 1)
+/** TLV type : Number of probes */
+#define TLV_TYPE_NUMPROBES          (PROPRIETARY_TLV_BASE_ID + 2)
+/** TLV type : Beacon RSSI low */
+#define TLV_TYPE_RSSI_LOW           (PROPRIETARY_TLV_BASE_ID + 4)
+/** TLV type : Beacon SNR low */
+#define TLV_TYPE_SNR_LOW            (PROPRIETARY_TLV_BASE_ID + 5)
+/** TLV type : Fail count */
+#define TLV_TYPE_FAILCOUNT          (PROPRIETARY_TLV_BASE_ID + 6)
+/** TLV type : BCN miss */
+#define TLV_TYPE_BCNMISS            (PROPRIETARY_TLV_BASE_ID + 7)
+/** TLV type : LED behavior */
+#define TLV_TYPE_LEDBEHAVIOR        (PROPRIETARY_TLV_BASE_ID + 9)
+/** TLV type : Passthrough */
+#define TLV_TYPE_PASSTHROUGH        (PROPRIETARY_TLV_BASE_ID + 10)
+/** TLV type : Power TBL 2.4 Ghz */
+#define TLV_TYPE_POWER_TBL_2_4GHZ   (PROPRIETARY_TLV_BASE_ID + 12)
+/** TLV type : Power TBL 5 GHz */
+#define TLV_TYPE_POWER_TBL_5GHZ     (PROPRIETARY_TLV_BASE_ID + 13)
+/** TLV type : WMM queue status */
+#define TLV_TYPE_WMMQSTATUS         (PROPRIETARY_TLV_BASE_ID + 16)
+/** TLV type : Wildcard SSID */
+#define TLV_TYPE_WILDCARDSSID       (PROPRIETARY_TLV_BASE_ID + 18)
+/** TLV type : TSF timestamp */
+#define TLV_TYPE_TSFTIMESTAMP       (PROPRIETARY_TLV_BASE_ID + 19)
+/** TLV type : Beacon RSSI high */
+#define TLV_TYPE_RSSI_HIGH          (PROPRIETARY_TLV_BASE_ID + 22)
+/** TLV type : Beacon SNR high */
+#define TLV_TYPE_SNR_HIGH           (PROPRIETARY_TLV_BASE_ID + 23)
+
+/** TLV type : Start BG scan later */
+#define TLV_TYPE_STARTBGSCANLATER   (PROPRIETARY_TLV_BASE_ID + 30)
+/** TLV type : Authentication type */
+#define TLV_TYPE_AUTH_TYPE          (PROPRIETARY_TLV_BASE_ID + 31)
+/** TLV type : Link Quality */
+#define TLV_TYPE_LINK_QUALITY       (PROPRIETARY_TLV_BASE_ID + 36)
+/** TLV type : Data RSSI low */
+#define TLV_TYPE_RSSI_LOW_DATA      (PROPRIETARY_TLV_BASE_ID + 38)
+/** TLV type : Data SNR low */
+#define TLV_TYPE_SNR_LOW_DATA       (PROPRIETARY_TLV_BASE_ID + 39)
+/** TLV type : Data RSSI high */
+#define TLV_TYPE_RSSI_HIGH_DATA     (PROPRIETARY_TLV_BASE_ID + 40)
+/** TLV type : Data SNR high */
+#define TLV_TYPE_SNR_HIGH_DATA      (PROPRIETARY_TLV_BASE_ID + 41)
+
+/** TLV type : Channel band list */
+#define TLV_TYPE_CHANNELBANDLIST    (PROPRIETARY_TLV_BASE_ID + 42)
+/** TLV type: WAPI IE */
+#define TLV_TYPE_WAPI_IE            (PROPRIETARY_TLV_BASE_ID + 94)
+
+/** TLV type : Encryption Protocol TLV */
+#define TLV_TYPE_ENCRYPTION_PROTO   (PROPRIETARY_TLV_BASE_ID + 64)
+/** TLV type : Cipher TLV */
+#define TLV_TYPE_CIPHER             (PROPRIETARY_TLV_BASE_ID + 66)
+/** TLV type : PMK */
+#define TLV_TYPE_PMK                (PROPRIETARY_TLV_BASE_ID + 68)
+/** TLV type : Passphrase */
+#define TLV_TYPE_PASSPHRASE         (PROPRIETARY_TLV_BASE_ID + 60)
+/** TLV type : BSSID */
+#define TLV_TYPE_BSSID              (PROPRIETARY_TLV_BASE_ID + 35)
+
+/** 2K buf size */
+#define MLAN_TX_DATA_BUF_SIZE_2K        2048
+
+/** TLV type : HT Capabilities */
+#define TLV_TYPE_HT_CAP                  (PROPRIETARY_TLV_BASE_ID + 74)
+/** TLV type : HT Information */
+#define TLV_TYPE_HT_INFO                 (PROPRIETARY_TLV_BASE_ID + 75)
+/** TLV type : Secondary Channel Offset */
+#define TLV_SECONDARY_CHANNEL_OFFSET     (PROPRIETARY_TLV_BASE_ID + 76)
+/** TLV type : 20/40 BSS Coexistence */
+#define TLV_TYPE_2040BSS_COEXISTENCE     (PROPRIETARY_TLV_BASE_ID + 77)
+/** TLV type : Overlapping BSS Scan Parameters */
+#define TLV_TYPE_OVERLAP_BSS_SCAN_PARAM  (PROPRIETARY_TLV_BASE_ID + 78)
+/** TLV type : Extended capabilities */
+#define TLV_TYPE_EXTCAP                  (PROPRIETARY_TLV_BASE_ID + 79)
+/** TLV type : Set of MCS values that STA desires to use within the BSS */
+#define TLV_TYPE_HT_OPERATIONAL_MCS_SET  (PROPRIETARY_TLV_BASE_ID + 80)
+
+/** ADDBA TID mask */
+#define ADDBA_TID_MASK   (MBIT(2) | MBIT(3) | MBIT(4) | MBIT(5))
+/** DELBA TID mask */
+#define DELBA_TID_MASK   (MBIT(12) | MBIT(13) | MBIT(14) | MBIT(15))
+/** ADDBA Starting Sequence Number Mask */
+#define SSN_MASK         0xfff0
+
+/** Block Ack result status */
+/** Block Ack Result : Success */
+#define BA_RESULT_SUCCESS        0x0
+/** Block Ack Result : Execution failure */
+#define BA_RESULT_FAILURE        0x1
+/** Block Ack Result : Timeout */
+#define BA_RESULT_TIMEOUT        0x2
+/** Block Ack Result : Data invalid */
+#define BA_RESULT_DATA_INVALID   0x3
+
+/** Get the baStatus (NOT_SETUP, COMPLETE, IN_PROGRESS)
+ *  in Tx BA stream table */
+#define IS_BASTREAM_SETUP(ptr)  (ptr->ba_status)
+
+/** An AMPDU/AMSDU could be disallowed for certain TID. 0xff means
+ *  no aggregation is enabled for the assigned TID */
+#define BA_STREAM_NOT_ALLOWED   0xff
+
+/** Test if 11n is enabled by checking the HTCap IE */
+#define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN ||priv->adapter->config_bands & BAND_AN) \
+        && priv->curr_bss_params.bss_descriptor.pht_cap)
+/** Find out if we are the initiator or not */
+#define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) & \
+                        MBIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS)
+
+/** 4K buf size */
+#define MLAN_TX_DATA_BUF_SIZE_4K        4096
+/** 8K buf size */
+#define MLAN_TX_DATA_BUF_SIZE_8K        8192
+/** Max Rx AMPDU Size */
+#define MAX_RX_AMPDU_SIZE_64K   0x03
+/** Non green field station */
+#define NON_GREENFIELD_STAS     0x04
+
+/** Greenfield support */
+#define HWSPEC_GREENFIELD_SUPP	 MBIT(29)
+/** Channel width 40Mhz support */
+#define HWSPEC_RXSTBC_SUPP	 MBIT(26)
+/** ShortGI @ 40Mhz support */
+#define HWSPEC_SHORTGI40_SUPP	 MBIT(24)
+/** ShortGI @ 20Mhz support */
+#define HWSPEC_SHORTGI20_SUPP	 MBIT(23)
+/** Channel width 40Mhz support */
+#define HWSPEC_CHANBW40_SUPP	 MBIT(17)
+/** 40Mhz intolarent enable */
+#define CAPINFO_40MHZ_INTOLARENT MBIT(8)
+
+/** Default 11n capability mask */
+#define DEFAULT_11N_CAP_MASK	(HWSPEC_SHORTGI20_SUPP | HWSPEC_RXSTBC_SUPP)
+/** Bits to ignore in hw_dev_cap as these bits are set in get_hw_spec */
+#define IGN_HW_DEV_CAP		(CAPINFO_40MHZ_INTOLARENT)
+
+/** HW_SPEC FwCapInfo */
+#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & MBIT(11))
+
+/** HW_SPEC Dot11nDevCap : MAX AMSDU supported */
+#define ISSUPP_MAXAMSDU(Dot11nDevCap) (Dot11nDevCap & MBIT(31))
+/** HW_SPEC Dot11nDevCap : Beamforming support */
+#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & MBIT(30))
+/** HW_SPEC Dot11nDevCap : Green field support */
+#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & MBIT(29))
+/** HW_SPEC Dot11nDevCap : AMPDU support */
+#define ISSUPP_AMPDU(Dot11nDevCap) (Dot11nDevCap & MBIT(28))
+/** HW_SPEC Dot11nDevCap : MIMO PS support  */
+#define ISSUPP_MIMOPS(Dot11nDevCap) (Dot11nDevCap & MBIT(27))
+/** HW_SPEC Dot11nDevCap : Rx STBC support */
+#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & MBIT(26))
+/** HW_SPEC Dot11nDevCap : Tx STBC support */
+#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & MBIT(25))
+/** HW_SPEC Dot11nDevCap : Short GI @ 40Mhz support */
+#define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & MBIT(24))
+/** HW_SPEC Dot11nDevCap : Short GI @ 20Mhz support */
+#define ISSUPP_SHORTGI20(Dot11nDevCap) (Dot11nDevCap & MBIT(23))
+/** HW_SPEC Dot11nDevCap : Rx LDPC support */
+#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & MBIT(22))
+/** HW_SPEC Dot11nDevCap : Delayed ACK */
+#define GET_DELAYEDBACK(Dot11nDevCap) (((Dot11nDevCap >> 20) & 0x03))
+/** HW_SPEC Dot11nDevCap : Immediate ACK */
+#define GET_IMMEDIATEBACK(Dot11nDevCap) (((Dot11nDevCap >> 18) & 0x03))
+/** HW_SPEC Dot11nDevCap : Channel BW support @ 40Mhz  support */
+#define ISSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap & MBIT(17))
+/** HW_SPEC Dot11nDevCap : Channel BW support @ 20Mhz  support */
+#define ISSUPP_CHANWIDTH20(Dot11nDevCap) (Dot11nDevCap & MBIT(16))
+/** HW_SPEC Dot11nDevCap : Channel BW support @ 10Mhz  support */
+#define ISSUPP_CHANWIDTH10(Dot11nDevCap) (Dot11nDevCap & MBIT(15))
+/** Dot11nUsrCap : 40Mhz intolarance enabled */
+#define ISENABLED_40MHZ_INTOLARENT(Dot11nDevCap) (Dot11nDevCap & MBIT(8))
+/** HW_SPEC Dot11nDevCap : Rx AntennaD support */
+#define ISSUPP_RXANTENNAD(Dot11nDevCap) (Dot11nDevCap & MBIT(7))
+/** HW_SPEC Dot11nDevCap : Rx AntennaC support */
+#define ISSUPP_RXANTENNAC(Dot11nDevCap) (Dot11nDevCap & MBIT(6))
+/** HW_SPEC Dot11nDevCap : Rx AntennaB support */
+#define ISSUPP_RXANTENNAB(Dot11nDevCap) (Dot11nDevCap & MBIT(5))
+/** HW_SPEC Dot11nDevCap : Rx AntennaA support */
+#define ISSUPP_RXANTENNAA(Dot11nDevCap) (Dot11nDevCap & MBIT(4))
+/** HW_SPEC Dot11nDevCap : Tx AntennaD support */
+#define ISSUPP_TXANTENNAD(Dot11nDevCap) (Dot11nDevCap & MBIT(3))
+/** HW_SPEC Dot11nDevCap : Tx AntennaC support */
+#define ISSUPP_TXANTENNAC(Dot11nDevCap) (Dot11nDevCap & MBIT(2))
+/** HW_SPEC Dot11nDevCap : Tx AntennaB support */
+#define ISSUPP_TXANTENNAB(Dot11nDevCap) (Dot11nDevCap & MBIT(1))
+/** HW_SPEC Dot11nDevCap : Tx AntennaA support */
+#define ISSUPP_TXANTENNAA(Dot11nDevCap) (Dot11nDevCap & MBIT(0))
+
+/** HW_SPEC Dot11nDevCap : Set support of channel bw @ 40Mhz */
+#define SETSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap |= MBIT(17))
+/** HW_SPEC Dot11nDevCap : Reset support of channel bw @ 40Mhz */
+#define RESETSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap &= ~MBIT(17))
+
+/** DevMCSSupported : Tx MCS supported */
+#define GET_TXMCSSUPP(DevMCSSupported) (DevMCSSupported >> 4)
+/** DevMCSSupported : Rx MCS supported */
+#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f)
+
+/** GET HTCapInfo : Supported Channel BW */
+#define GETHT_SUPPCHANWIDTH(HTCapInfo) (HTCapInfo & MBIT(1))
+/** GET HTCapInfo : Support for Greenfield */
+#define GETHT_GREENFIELD(HTCapInfo) (HTCapInfo & MBIT(4))
+/** GET HTCapInfo : Support for Short GI @ 20Mhz */
+#define GETHT_SHORTGI20(HTCapInfo) (HTCapInfo & MBIT(5))
+/** GET HTCapInfo : Support for Short GI @ 40Mhz */
+#define GETHT_SHORTGI40(HTCapInfo) (HTCapInfo & MBIT(6))
+/** GET HTCapInfo : Support for Tx STBC */
+#define GETHT_TXSTBC(HTCapInfo) (HTCapInfo & MBIT(7))
+/** GET HTCapInfo : Support for Rx STBC */
+#define GETHT_RXSTBC(HTCapInfo) ((HTCapInfo >> 8) & 0x03)
+/** GET HTCapInfo : Support for Delayed ACK */
+#define GETHT_DELAYEDBACK(HTCapInfo) (HTCapInfo & MBIT(10))
+/** GET HTCapInfo : Support for Max AMSDU */
+#define GETHT_MAXAMSDU(HTCapInfo) (HTCapInfo & MBIT(11))
+
+/** SET HTCapInfo : Set support for Channel BW */
+#define SETHT_SUPPCHANWIDTH(HTCapInfo) (HTCapInfo |= MBIT(1))
+/** SET HTCapInfo : Set support for Greenfield */
+#define SETHT_GREENFIELD(HTCapInfo) (HTCapInfo |= MBIT(4))
+/** SET HTCapInfo : Set support for Short GI @ 20Mhz */
+#define SETHT_SHORTGI20(HTCapInfo) (HTCapInfo |= MBIT(5))
+/** SET HTCapInfo : Set support for Short GI @ 40Mhz */
+#define SETHT_SHORTGI40(HTCapInfo) (HTCapInfo |= MBIT(6))
+/** SET HTCapInfo : Set support for Tx STBC */
+#define SETHT_TXSTBC(HTCapInfo) (HTCapInfo |= MBIT(7))
+/** SET HTCapInfo : Set support for Rx STBC */
+#define SETHT_RXSTBC(HTCapInfo, value) (HTCapInfo |= (value << 8))
+/** SET HTCapInfo : Set support for delayed block ack */
+#define SETHT_DELAYEDBACK(HTCapInfo) (HTCapInfo |= MBIT(10))
+/** SET HTCapInfo : Set support for Max size AMSDU */
+#define SETHT_MAXAMSDU(HTCapInfo) (HTCapInfo |= MBIT(11))
+/** SET HTCapInfo : Set support for DSSS/CCK Rates @ 40Mhz */
+#define SETHT_DSSSCCK40(HTCapInfo) (HTCapInfo |= MBIT(12))
+/** SET HTCapInfo : Enable 40Mhz Intolarence */
+#define SETHT_40MHZ_INTOLARANT(HTCapInfo) (HTCapInfo |= MBIT(14))
+
+/** RESET HTCapInfo : Set support for Channel BW */
+#define RESETHT_SUPPCHANWIDTH(HTCapInfo) (HTCapInfo &= ~MBIT(1))
+/** RESET HTCapInfo : Set support for Greenfield */
+#define RESETHT_GREENFIELD(HTCapInfo) (HTCapInfo &= ~MBIT(4))
+/** RESET HTCapInfo : Set support for Short GI @ 20Mhz */
+#define RESETHT_SHORTGI20(HTCapInfo) (HTCapInfo &= ~MBIT(5))
+/** RESET HTCapInfo : Set support for Short GI @ 40Mhz */
+#define RESETHT_SHORTGI40(HTCapInfo) (HTCapInfo &= ~MBIT(6))
+/** RESET HTCapInfo : Set support for Tx STBC */
+#define RESETHT_TXSTBC(HTCapInfo) (HTCapInfo &= ~MBIT(7))
+/** RESET HTCapInfo : Set support for Rx STBC */
+#define RESETHT_RXSTBC(HTCapInfo) (HTCapInfo &= ~(0x03 << 8))
+/** RESET HTCapInfo : Set support for delayed block ack */
+#define RESETHT_DELAYEDBACK(HTCapInfo) (HTCapInfo &= ~MBIT(10))
+/** RESET HTCapInfo : Set support for Max size AMSDU */
+#define RESETHT_MAXAMSDU(HTCapInfo) (HTCapInfo &= ~MBIT(11))
+/** RESET HTCapInfo : Disable 40Mhz Intolarence */
+#define RESETHT_40MHZ_INTOLARANT(HTCapInfo) (HTCapInfo &= ~MBIT(14))
+/** SET MCS32 */
+#define SETHT_MCS32(x) (x[4] |= 1)
+/** Set mcs set defined bit */
+#define SETHT_MCS_SET_DEFINED(x) (x[12] |= 1)
+/* Set the highest Rx data rate */
+#define SETHT_RX_HIGHEST_DT_SUPP(x, y) ((*(t_u16 *) (x + 10)) = y)
+/** AMPDU factor size */
+#define AMPDU_FACTOR_64K	0x03
+/** Set AMPDU size in A-MPDU paramter field */
+#define SETAMPDU_SIZE(x, y) do { \
+	x = x & ~0x03; \
+	x |= y & 0x03; \
+} while (0) \
+/** Set AMPDU spacing in A-MPDU paramter field */
+#define SETAMPDU_SPACING(x, y) do { \
+	x = x & ~0x1c; \
+	x |= (y & 0x07) << 2; \
+} while (0) \
+
+/** RadioType : Support for Band A */
+#define ISSUPP_BANDA(FwCapInfo) (FwCapInfo & MBIT(10))
+/** RadioType : Support for 40Mhz channel BW */
+#define ISALLOWED_CHANWIDTH40(Field2) (Field2 & MBIT(2))
+/** RadioType : Set support 40Mhz channel */
+#define SET_CHANWIDTH40(Field2) (Field2 |= MBIT(2))
+/** RadioType : Reset support 40Mhz channel */
+#define RESET_CHANWIDTH40(Field2) (Field2 &= ~(MBIT(0) | MBIT(1) | MBIT(2)))
+/** RadioType : Get secondary channel */
+#define GET_SECONDARYCHAN(Field2) (Field2 & (MBIT(0) | MBIT(1)))
+/** RadioType : Set secondary channel */
+#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4))
+
+/** LLC/SNAP header len   */
+#define LLC_SNAP_LEN    8
+
+/** TLV type : Rate scope */
+#define TLV_TYPE_RATE_DROP_PATTERN  (PROPRIETARY_TLV_BASE_ID + 81)
+/** TLV type : Rate drop pattern */
+#define TLV_TYPE_RATE_DROP_CONTROL  (PROPRIETARY_TLV_BASE_ID + 82)
+/** TLV type : Rate scope */
+#define TLV_TYPE_RATE_SCOPE         (PROPRIETARY_TLV_BASE_ID + 83)
+
+/** TLV type : Power group */
+#define TLV_TYPE_POWER_GROUP        (PROPRIETARY_TLV_BASE_ID + 84)
+
+/** Modulation class for DSSS Rates */
+#define MOD_CLASS_HR_DSSS       0x03
+/** Modulation class for OFDM Rates */
+#define MOD_CLASS_OFDM          0x07
+/** Modulation class for HT Rates */
+#define MOD_CLASS_HT            0x08
+/** HT bandwidth 20 MHz */
+#define HT_BW_20    0
+/** HT bandwidth 40 MHz */
+#define HT_BW_40    1
+
+/** Firmware Host Command ID Constants */
+/** Host Command ID : Get hardware specifications */
+#define HostCmd_CMD_GET_HW_SPEC               0x0003
+/** Host Command ID : 802.11 scan */
+#define HostCmd_CMD_802_11_SCAN               0x0006
+/** Host Command ID : 802.11 get log */
+#define HostCmd_CMD_802_11_GET_LOG            0x000b
+/** Host Command ID : MAC multicast address */
+#define HostCmd_CMD_MAC_MULTICAST_ADR         0x0010
+/** Host Command ID : 802.11 EEPROM access */
+#define HostCmd_CMD_802_11_EEPROM_ACCESS      0x0059
+/** Host Command ID : 802.11 associate */
+#define HostCmd_CMD_802_11_ASSOCIATE          0x0012
+/** Host Command ID : 802.11 SNMP MIB */
+#define HostCmd_CMD_802_11_SNMP_MIB           0x0016
+/** Host Command ID : MAC register access */
+#define HostCmd_CMD_MAC_REG_ACCESS            0x0019
+/** Host Command ID : BBP register access */
+#define HostCmd_CMD_BBP_REG_ACCESS            0x001a
+/** Host Command ID : RF register access */
+#define HostCmd_CMD_RF_REG_ACCESS             0x001b
+/** Host Command ID : PMIC register access */
+#define HostCmd_CMD_PMIC_REG_ACCESS           0x00ad
+/** Host Command ID : 802.11 radio control */
+#define HostCmd_CMD_802_11_RADIO_CONTROL      0x001c
+/** Host Command ID : 802.11 RF channel */
+#define HostCmd_CMD_802_11_RF_CHANNEL         0x001d
+/** Host Command ID : 802.11 RF antenna */
+#define HostCmd_CMD_802_11_RF_ANTENNA         0x0020
+
+/** Host Command ID : 802.11 deauthenticate */
+#define HostCmd_CMD_802_11_DEAUTHENTICATE     0x0024
+/** Host Command ID : MAC control */
+#define HostCmd_CMD_MAC_CONTROL               0x0028
+/** Host Command ID : 802.11 Ad-Hoc start */
+#define HostCmd_CMD_802_11_AD_HOC_START       0x002b
+/** Host Command ID : 802.11 Ad-Hoc join */
+#define HostCmd_CMD_802_11_AD_HOC_JOIN        0x002c
+
+/** Host Command ID : 802.11 key material */
+#define HostCmd_CMD_802_11_KEY_MATERIAL       0x005e
+
+/** Host Command ID : 802.11 Ad-Hoc stop */
+#define HostCmd_CMD_802_11_AD_HOC_STOP        0x0040
+
+/** Host Command ID : 802.22 MAC address */
+#define HostCmd_CMD_802_11_MAC_ADDRESS        0x004D
+
+/** Host Command ID : WMM Traffic Stream Status */
+#define HostCmd_CMD_WMM_TS_STATUS             0x005d
+
+/** Host Command ID : 802.11 D domain information */
+#define HostCmd_CMD_802_11D_DOMAIN_INFO       0x005b
+
+/** Host Command ID : 802.11 TPC information */
+#define HostCmd_CMD_802_11_TPC_INFO           0x005f
+/** Host Command ID : 802.11 TPC adapt req */
+#define HostCmd_CMD_802_11_TPC_ADAPT_REQ      0x0060
+/** Host Command ID : 802.11 channel SW ann */
+#define HostCmd_CMD_802_11_CHAN_SW_ANN        0x0061
+/** Host Command ID : Measurement request */
+#define HostCmd_CMD_MEASUREMENT_REQUEST       0x0062
+/** Host Command ID : Measurement report */
+#define HostCmd_CMD_MEASUREMENT_REPORT        0x0063
+
+/** Host Command ID : 802.11 sleep parameters */
+#define HostCmd_CMD_802_11_SLEEP_PARAMS       0x0066
+
+/** Host Command ID : 802.11 sleep period */
+#define HostCmd_CMD_802_11_SLEEP_PERIOD       0x0068
+/** Host Command ID : 802.11 BCA configuration timeshare */
+#define HostCmd_CMD_802_11_BCA_CONFIG_TIMESHARE  0x0069
+
+/** Host Command ID : 802.11 BG scan query */
+#define HostCmd_CMD_802_11_BG_SCAN_QUERY      0x006c
+
+/** Host Command ID : WMM ADDTS req */
+#define HostCmd_CMD_WMM_ADDTS_REQ             0x006E
+/** Host Command ID : WMM DELTS req */
+#define HostCmd_CMD_WMM_DELTS_REQ             0x006F
+/** Host Command ID : WMM queue configuration */
+#define HostCmd_CMD_WMM_QUEUE_CONFIG          0x0070
+/** Host Command ID : 802.11 get status */
+#define HostCmd_CMD_WMM_GET_STATUS            0x0071
+
+/** Host Command ID : 802.11 Tx rate query */
+#define HostCmd_CMD_802_11_TX_RATE_QUERY      0x007f
+
+/** Host Command ID : WMM queue stats */
+#define HostCmd_CMD_WMM_QUEUE_STATS           0x0081
+
+/** Host Command ID : 802.11 IBSS coalescing status */
+#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083
+
+/** Host Command ID : Memory access */
+#define HostCmd_CMD_MEM_ACCESS                0x0086
+
+#ifdef MFG_CMD_SUPPORT
+/** Host Command ID : Mfg command */
+#define HostCmd_CMD_MFG_COMMAND               0x0089
+#endif
+/** Host Command ID : Inactivity timeout ext */
+#define HostCmd_CMD_INACTIVITY_TIMEOUT_EXT    0x008a
+
+/** Host Command ID : DBGS configuration */
+#define HostCmd_CMD_DBGS_CFG                  0x008b
+/** Host Command ID : Get memory */
+#define HostCmd_CMD_GET_MEM                   0x008c
+
+/** Host Command ID : SDIO pull control */
+#define HostCmd_CMD_SDIO_PULL_CTRL            0x0093
+
+/** Host Command ID : ECL system clock configuration */
+#define HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG   0x0094
+
+/** Host Command ID : 802.11 LDO configuration */
+#define HostCmd_CMD_802_11_LDO_CONFIG         0x0096
+
+/** Host Command ID : Extended version */
+#define HostCmd_CMD_VERSION_EXT               0x0097
+
+/** Host Command ID : 802.11 RSSI INFO*/
+#define HostCmd_CMD_RSSI_INFO                 0x00a4
+
+/** Host Command ID : Function initialization */
+#define HostCmd_CMD_FUNC_INIT                 0x00a9
+/** Host Command ID : Function shutdown */
+#define HostCmd_CMD_FUNC_SHUTDOWN             0x00aa
+
+/** Host Command ID: SUPPLICANT_PMK */
+#define HostCmd_CMD_SUPPLICANT_PMK            0x00c4
+/** Host Command ID: SUPPLICANT_PROFILE */
+#define HostCmd_CMD_SUPPLICANT_PROFILE        0x00c5
+
+/** Host Command ID : Add Block Ack Request */
+#define HostCmd_CMD_11N_ADDBA_REQ             0x00ce
+/** Host Command ID : Delete a Block Ack Request */
+#define HostCmd_CMD_11N_CFG                   0x00cd
+/** Host Command ID : Add Block Ack Response */
+#define HostCmd_CMD_11N_ADDBA_RSP             0x00cf
+/** Host Command ID : Delete a Block Ack Request */
+#define HostCmd_CMD_11N_DELBA                 0x00d0
+/** Host Command ID: Configure Tx Buf size */
+#define HostCmd_CMD_RECONFIGURE_TX_BUFF       0x00d9
+/** Host Command ID: AMSDU Aggr Ctrl */
+#define HostCmd_CMD_AMSDU_AGGR_CTRL	      	  0x00df
+
+/** Host Command ID : 802.11 TX power configuration */
+#define HostCmd_CMD_TXPWR_CFG                 0x00d1
+
+/** Host Command ID : 802.11 b/g/n rate configration */
+#define HostCmd_CMD_TX_RATE_CFG               0x00d6
+
+/** Host Command ID : Enhanced PS mode */
+#define HostCmd_CMD_802_11_PS_MODE_ENH        0x00e4
+/** Host command action : Host sleep configuration */
+#define HostCmd_CMD_802_11_HS_CFG_ENH         0x00e5
+
+/** Host Command ID : CAU register access */
+#define HostCmd_CMD_CAU_REG_ACCESS            0x00ed
+
+/** Enhanced PS modes */
+typedef enum _ENH_PS_MODES
+{
+    EN_PS = 1,
+    DIS_PS,
+    EN_AUTO_DS,
+    DIS_AUTO_DS,
+    SLEEP_CONFIRM,
+} ENH_PS_MODES;
+
+/** Command RET code, MSB is set to 1 */
+#define HostCmd_RET_BIT                       0x8000
+
+/** General purpose action : Get */
+#define HostCmd_ACT_GEN_GET                   0x0000
+/** General purpose action : Set */
+#define HostCmd_ACT_GEN_SET                   0x0001
+/** General purpose action : Get_Current */
+#define HostCmd_ACT_GEN_GET_CURRENT           0x0003
+/** General purpose action : Remove */
+#define HostCmd_ACT_GEN_REMOVE                0x0004
+
+/** Host command action : Set both Rx and Tx */
+#define HostCmd_ACT_SET_BOTH                  0x0003
+/** Host command action : Get Rx */
+#define HostCmd_ACT_GET_RX                    0x0004
+/** Host command action : Get Tx */
+#define HostCmd_ACT_GET_TX                    0x0008
+/** Host command action : Get both Rx and Tx */
+#define HostCmd_ACT_GET_BOTH                  0x000c
+
+/** General Result Code*/
+/** General result code OK */
+#define HostCmd_RESULT_OK                     0x0000
+/** Genenral error */
+#define HostCmd_RESULT_ERROR                  0x0001
+/** Command is not valid */
+#define HostCmd_RESULT_NOT_SUPPORT            0x0002
+/** Command is pending */
+#define HostCmd_RESULT_PENDING                0x0003
+/** System is busy (command ignored) */
+#define HostCmd_RESULT_BUSY                   0x0004
+/** Data buffer is not big enough */
+#define HostCmd_RESULT_PARTIAL_DATA           0x0005
+
+/* Define action or option for HostCmd_CMD_MAC_CONTROL */
+/** MAC action : Rx on */
+#define HostCmd_ACT_MAC_RX_ON                 0x0001
+/** MAC action : Tx on */
+#define HostCmd_ACT_MAC_TX_ON                 0x0002
+/** MAC action : Loopback on */
+#define HostCmd_ACT_MAC_LOOPBACK_ON           0x0004
+/** MAC action : WEP enable */
+#define HostCmd_ACT_MAC_WEP_ENABLE            0x0008
+/** MAC action : EthernetII enable */
+#define HostCmd_ACT_MAC_ETHERNETII_ENABLE     0x0010
+/** MAC action : Promiscous mode enable */
+#define HostCmd_ACT_MAC_PROMISCUOUS_ENABLE    0x0080
+/** MAC action : All multicast enable */
+#define HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE  0x0100
+/** MAC action : RTS/CTS enable */
+#define HostCmd_ACT_MAC_RTS_CTS_ENABLE        0x0200
+/** MAC action : Strict protection enable */
+#define HostCmd_ACT_MAC_STRICT_PROTECTION_ENABLE  0x0400
+/** MAC action : Ad-Hoc G protection on */
+#define HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON     0x2000
+
+/* Define action or option for HostCmd_CMD_802_11_SCAN */
+/** Scan type : BSS */
+#define HostCmd_BSS_MODE_BSS                0x0001
+/** Scan type : IBSS */
+#define HostCmd_BSS_MODE_IBSS               0x0002
+/** Scan type : Any */
+#define HostCmd_BSS_MODE_ANY                0x0003
+
+/* Define action or option for HostCmd_CMD_802_11_SCAN */
+/** Scan type : Active */
+#define HostCmd_SCAN_TYPE_ACTIVE            0x0000
+/** Scan type : Passive */
+#define HostCmd_SCAN_TYPE_PASSIVE           0x0001
+
+/* Radio type definitions for the channel TLV */
+/** Radio type BG */
+#define HostCmd_SCAN_RADIO_TYPE_BG          0
+/** Radio type A */
+#define HostCmd_SCAN_RADIO_TYPE_A           1
+
+/** Define bitmap conditions for HOST_SLEEP_CFG : GPIO FF */
+#define HOST_SLEEP_CFG_GPIO_FF              0xff
+/** Define bitmap conditions for HOST_SLEEP_CFG : GAP FF */
+#define HOST_SLEEP_CFG_GAP_FF               0xff
+
+/** Buffer Constants */
+/** Number of command buffers */
+#define MRVDRV_NUM_OF_CMD_BUFFER        20
+/** Size of command buffer */
+#define MRVDRV_SIZE_OF_CMD_BUFFER       (2 * 1024)
+
+/** Maximum number of BSS Descriptors */
+#define MRVDRV_MAX_BSSID_LIST           64
+
+/** Host command flag in command */
+#define CMD_F_HOSTCMD           (1 << 0)
+
+/** Host Command ID bit mask (bit 11:0) */
+#define HostCmd_CMD_ID_MASK             0x0fff
+
+/** Set BSS number to Host Command (bit 14:12) */
+#define HostCmd_SET_BSS_NO(cmd, bss)    \
+    (((cmd) & HostCmd_CMD_ID_MASK) | \
+        (((bss) & (MLAN_MAX_BSS_NUM - 1)) << 12))
+
+/** Get BSS number from Host Command (bit 14:12) */
+#define HostCmd_GET_BSS_NO(cmd)         \
+        (((cmd) >> 12) & (MLAN_MAX_BSS_NUM - 1))
+
+/** Card Event definition : Dummy host wakeup signal */
+#define EVENT_DUMMY_HOST_WAKEUP_SIGNAL  0x00000001
+/** Card Event definition : Link lost with scan */
+#define EVENT_LINK_LOST_WITH_SCAN       0x00000002
+/** Card Event definition : Link lost */
+#define EVENT_LINK_LOST                 0x00000003
+/** Card Event definition : Link sensed */
+#define EVENT_LINK_SENSED               0x00000004
+/** Card Event definition : MIB changed */
+#define EVENT_MIB_CHANGED               0x00000006
+/** Card Event definition : Init done */
+#define EVENT_INIT_DONE                 0x00000007
+/** Card Event definition : Deauthenticated */
+#define EVENT_DEAUTHENTICATED           0x00000008
+/** Card Event definition : Disassociated */
+#define EVENT_DISASSOCIATED             0x00000009
+/** Card Event definition : Power save awake */
+#define EVENT_PS_AWAKE                  0x0000000a
+/** Card Event definition : Power save sleep */
+#define EVENT_PS_SLEEP                  0x0000000b
+/** Card Event definition : MIC error multicast */
+#define EVENT_MIC_ERR_MULTICAST         0x0000000d
+/** Card Event definition : MIC error unicast */
+#define EVENT_MIC_ERR_UNICAST           0x0000000e
+/** Card Event definition : WM awake */
+#define EVENT_WM_AWAKE                  0x0000000f
+/** Card Event definition : Deep Sleep awake */
+#define EVENT_DEEP_SLEEP_AWAKE          0x00000010
+/** Card Event definition : Ad-Hoc BCN lost */
+#define EVENT_ADHOC_BCN_LOST            0x00000011
+/** Card Event definition : Stop Tx */
+#define EVENT_STOP_TX                   0x00000013
+/** Card Event definition : Start Tx */
+#define EVENT_START_TX                  0x00000014
+/** Card Event definition : Channel switch */
+#define EVENT_CHANNEL_SWITCH            0x00000015
+/** Card Event definition : MEAS report ready */
+#define EVENT_MEAS_REPORT_RDY           0x00000016
+/** Card Event definition : WMM status change */
+#define EVENT_WMM_STATUS_CHANGE         0x00000017
+
+/** Card Event definition : BG scan report */
+#define EVENT_BG_SCAN_REPORT            0x00000018
+
+/** Card Event definition : Beacon RSSI low */
+#define EVENT_RSSI_LOW                  0x00000019
+/** Card Event definition : Beacon SNR low */
+#define EVENT_SNR_LOW                   0x0000001a
+/** Card Event definition : Maximum fail */
+#define EVENT_MAX_FAIL                  0x0000001b
+/** Card Event definition : Beacon RSSI high */
+#define EVENT_RSSI_HIGH                 0x0000001c
+/** Card Event definition : Beacon SNR high */
+#define EVENT_SNR_HIGH                  0x0000001d
+/** Card Event definition : IBSS coalsced */
+#define EVENT_IBSS_COALESCED            0x0000001e
+
+/** Card Event definition : Data RSSI low */
+#define EVENT_DATA_RSSI_LOW             0x00000024
+/** Card Event definition : Data SNR low */
+#define EVENT_DATA_SNR_LOW              0x00000025
+/** Card Event definition : Data RSSI high */
+#define EVENT_DATA_RSSI_HIGH            0x00000026
+/** Card Event definition : Data SNR high */
+#define EVENT_DATA_SNR_HIGH             0x00000027
+/** Card Event definition : Link Quality */
+#define EVENT_LINK_QUALITY              0x00000028
+
+/** Card Event definition : Port release event */
+#define EVENT_PORT_RELEASE              0x0000002b
+
+/** Card Event definition : Pre-Beacon Lost */
+#define EVENT_PRE_BEACON_LOST           0x00000031
+/** Card Event definition : Add BA event */
+#define EVENT_ADDBA                     0x00000033
+/** Card Event definition : Del BA event */
+#define EVENT_DELBA                     0x00000034
+/** Card Event definition: BA stream timeout*/
+#define EVENT_BA_STREAM_TIEMOUT         0x00000037
+/** Card Event definition : AMSDU aggr control */
+#define EVENT_AMSDU_AGGR_CTRL           0x00000042
+/** Card Event definition: WEP ICV error */
+#define EVENT_WEP_ICV_ERR               0x00000046
+/** Card Event definition : Host sleep enable */
+#define EVENT_HS_ACT_REQ                0x00000047
+/** Card Event definition : BW changed */
+#define EVENT_BW_CHANGE                 0x00000048
+
+/** event ID mask */
+#define EVENT_ID_MASK                   0x0fff
+
+/** Get BSS number from event cause (bit 14:12) */
+#define EVENT_GET_BSS_NUM(event_cause)          \
+    (((event_cause) >> 12) & (MLAN_MAX_BSS_NUM - 1))
+
+/** Event_WEP_ICV_ERR structure */
+typedef struct _Event_WEP_ICV_ERR
+{
+    /** Reason code */
+    t_u16 reason_code;
+    /** Source MAC address */
+    t_u8 src_mac_addr[MLAN_MAC_ADDR_LENGTH];
+    /** WEP decryption used key */
+    t_u8 wep_key_index;
+    /** WEP key length */
+    t_u8 wep_key_length;
+    /** WEP key */
+    t_u8 key[MAX_WEP_KEY_SIZE];
+} Event_WEP_ICV_ERR;
+
+/** WLAN_802_11_FIXED_IEs */
+typedef struct _WLAN_802_11_FIXED_IEs
+{
+    /** Timestamp */
+    t_u8 time_stamp[8];
+    /** Beacon interval */
+    t_u16 beacon_interval;
+    /** Capabilities*/
+    t_u16 capabilities;
+} WLAN_802_11_FIXED_IEs;
+
+/** WLAN_802_11_VARIABLE_IEs */
+typedef struct _WLAN_802_11_VARIABLE_IEs
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 length;
+    /** IE data */
+    t_u8 data[1];
+} WLAN_802_11_VARIABLE_IEs;
+
+#ifdef PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+
+/** TLV related data structures*/
+/** MrvlIEtypesHeader_t */
+typedef MLAN_PACK_START struct _MrvlIEtypesHeader
+{
+    /** Header type */
+    t_u16 type;
+    /** Header length */
+    t_u16 len;
+} MLAN_PACK_END MrvlIEtypesHeader_t;
+
+/** MrvlIEtypes_Data_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_Data_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Data */
+    t_u8 data[1];
+} MLAN_PACK_END MrvlIEtypes_Data_t;
+
+/** Bit mask for TxPD status field for null packet */
+#define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01
+/** Bit mask for TxPD status field for last packet */
+#define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08
+
+/** TxPD descriptor */
+typedef MLAN_PACK_START struct _TxPD
+{
+    /** BSS type */
+    t_u8 bss_type;
+    /** BSS number */
+    t_u8 bss_num;
+    /** Tx packet length */
+    t_u16 tx_pkt_length;
+    /** Tx packet offset */
+    t_u16 tx_pkt_offset;
+    /** Tx packet type */
+    t_u16 tx_pkt_type;
+    /** Tx Control */
+    t_u32 tx_control;
+    /** Pkt Priority */
+    t_u8 priority;
+    /** Transmit Pkt Flags*/
+    t_u8 flags;
+    /** Amount of time the packet has been queued in the driver (units = 2ms)*/
+    t_u8 pkt_delay_2ms;
+    /** Reserved */
+    t_u8 reserved1;
+} MLAN_PACK_END TxPD, *PTxPD;
+
+/** RxPD Descriptor */
+typedef MLAN_PACK_START struct _RxPD
+{
+    /** BSS type */
+    t_u8 bss_type;
+    /** BSS number */
+    t_u8 bss_num;
+    /** Rx Packet Length */
+    t_u16 rx_pkt_length;
+    /** Rx Pkt offset */
+    t_u16 rx_pkt_offset;
+    /** Rx packet type */
+    t_u16 rx_pkt_type;
+    /** Sequence number */
+    t_u16 seq_num;
+    /** Packet Priority */
+    t_u8 priority;
+    /** Rx Packet Rate */
+    t_u8 rx_rate;
+    /** SNR */
+    t_s8 snr;
+    /** Noise Floor */
+    t_s8 nf;
+    /** Ht Info [Bit 0] RxRate format: LG=0, HT=1
+     * [Bit 1]  HT Bandwidth: BW20 = 0, BW40 = 1
+     * [Bit 2]  HT Guard Interval: LGI = 0, SGI = 1 */
+    t_u8 ht_info;
+    /** Reserved */
+    t_u8 reserved;
+} MLAN_PACK_END RxPD, *PRxPD;
+
+/** (Beaconsize(256)-5(IEId,len,contrystr(3))/3(FirstChan,NoOfChan,MaxPwr) */
+#define MAX_NO_OF_CHAN          40
+
+/** Channel-power table entries */
+typedef MLAN_PACK_START struct _chan_power_11d
+{
+    /** 11D channel */
+    t_u8 chan;
+    /** 11D channel power */
+    t_u8 pwr;
+} MLAN_PACK_END chan_power_11d_t;
+
+/** Region channel info */
+typedef MLAN_PACK_START struct _parsed_region_chan_11d
+{
+    /** 11D band */
+    t_u8 band;
+    /** 11D region */
+    t_u8 region;
+    /** 11D country code */
+    t_u8 country_code[COUNTRY_CODE_LEN];
+    /** 11D channel power per channel */
+    chan_power_11d_t chan_pwr[MAX_NO_OF_CHAN];
+    /** 11D number of channels */
+    t_u8 no_of_chan;
+} MLAN_PACK_END parsed_region_chan_11d_t;
+
+/** ChanScanMode_t */
+typedef MLAN_PACK_START struct _ChanScanMode_t
+{
+#ifdef BIG_ENDIAN
+    /** Reserved */
+    t_u8 reserved_2_7:6;
+    /** Disble channel filtering flag */
+    t_u8 disable_chan_filt:1;
+    /** Channel scan mode passive flag */
+    t_u8 passive_scan:1;
+#else
+    /** Channel scan mode passive flag */
+    t_u8 passive_scan:1;
+    /** Disble channel filtering flag */
+    t_u8 disable_chan_filt:1;
+    /** Reserved */
+    t_u8 reserved_2_7:6;
+#endif
+} MLAN_PACK_END ChanScanMode_t;
+
+/** ChanScanParamSet_t */
+typedef MLAN_PACK_START struct _ChanScanParamSet_t
+{
+    /** Channel scan parameter : Radio type */
+    t_u8 radio_type;
+    /** Channel scan parameter : Channel number */
+    t_u8 chan_number;
+    /** Channel scan parameter : Channel scan mode */
+    ChanScanMode_t chan_scan_mode;
+    /** Channel scan parameter : Minimum scan time */
+    t_u16 min_scan_time;
+    /** Channel scan parameter : Maximum scan time */
+    t_u16 max_scan_time;
+} MLAN_PACK_END ChanScanParamSet_t;
+
+/** MrvlIEtypes_ChanListParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_ChanListParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Channel scan parameters */
+    ChanScanParamSet_t chan_scan_param[1];
+} MLAN_PACK_END MrvlIEtypes_ChanListParamSet_t;
+
+/** ChanScanParamSet_t */
+typedef struct _ChanBandParamSet_t
+{
+    /** Channel scan parameter : Radio type */
+    t_u8 radio_type;
+    /** Channel number */
+    t_u8 chan_number;
+} ChanBandParamSet_t;
+
+/** MrvlIEtypes_ChanBandListParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_ChanBandListParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Channel Band parameters */
+    ChanBandParamSet_t chan_band_param[1];
+} MLAN_PACK_END MrvlIEtypes_ChanBandListParamSet_t;
+
+/** MrvlIEtypes_RatesParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_RatesParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Rates */
+    t_u8 rates[1];
+} MLAN_PACK_END MrvlIEtypes_RatesParamSet_t;
+
+/** MrvlIEtypes_SsIdParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_SsIdParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** SSID */
+    t_u8 ssid[1];
+} MLAN_PACK_END MrvlIEtypes_SsIdParamSet_t;
+
+/** MrvlIEtypes_NumProbes_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_NumProbes_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Number of probes */
+    t_u16 num_probes;
+} MLAN_PACK_END MrvlIEtypes_NumProbes_t;
+
+/** MrvlIEtypes_WildCardSsIdParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_WildCardSsIdParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Maximum SSID length */
+    t_u8 max_ssid_length;
+    /** SSID */
+    t_u8 ssid[1];
+} MLAN_PACK_END MrvlIEtypes_WildCardSsIdParamSet_t;
+
+/**TSF data size */
+#define TSF_DATA_SIZE            8
+/** Table of TSF values returned in the scan result */
+typedef MLAN_PACK_START struct _MrvlIEtypes_TsfTimestamp_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** the length of each TSF data is 8 bytes, could be multiple TSF here */
+    t_u8 tsf_data[1];
+} MLAN_PACK_END MrvlIEtypes_TsfTimestamp_t;
+
+/** CfParamSet_t */
+typedef MLAN_PACK_START struct _CfParamSet_t
+{
+    /** CF parameter : Count */
+    t_u8 cfp_cnt;
+    /** CF parameter : Period */
+    t_u8 cfp_period;
+    /** CF parameter : Duration */
+    t_u16 cfp_max_duration;
+    /** CF parameter : Duration remaining */
+    t_u16 cfp_duration_remaining;
+} MLAN_PACK_END CfParamSet_t;
+
+/** IbssParamSet_t */
+typedef MLAN_PACK_START struct _IbssParamSet_t
+{
+    /** ATIM window value */
+    t_u16 atim_window;
+} MLAN_PACK_END IbssParamSet_t;
+
+/** MrvlIEtypes_SsParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_SsParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** CF/IBSS parameters sets */
+    union
+    {
+        /** CF parameter set */
+        CfParamSet_t cf_param_set[1];
+        /** IBSS parameter set */
+        IbssParamSet_t ibss_param_set[1];
+    } cf_ibss;
+} MLAN_PACK_END MrvlIEtypes_SsParamSet_t;
+
+/** FhParamSet_t */
+typedef MLAN_PACK_START struct _FhParamSet_t
+{
+    /** FH parameter : Dwell time */
+    t_u16 dwell_time;
+    /** FH parameter : Hop set */
+    t_u8 hop_set;
+    /** FH parameter : Hop pattern */
+    t_u8 hop_pattern;
+    /** FH parameter : Hop index */
+    t_u8 hop_index;
+} MLAN_PACK_END FhParamSet_t;
+
+/** DsParamSet_t */
+typedef MLAN_PACK_START struct _DsParamSet_t
+{
+    /** Current channel number */
+    t_u8 current_chan;
+} MLAN_PACK_END DsParamSet_t;
+
+/** MrvlIEtypes_PhyParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_PhyParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** FH/DS parameters */
+    union
+    {
+        /** FH parameter set */
+        FhParamSet_t fh_param_set[1];
+        /** DS parameter set */
+        DsParamSet_t ds_param_set[1];
+    } fh_ds;
+} MLAN_PACK_END MrvlIEtypes_PhyParamSet_t;
+
+/* Auth type to be used in the Authentication portion of an Assoc seq */
+/** MrvlIEtypes_AuthType_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_AuthType_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Authentication type */
+    t_u16 auth_type;
+} MLAN_PACK_END MrvlIEtypes_AuthType_t;
+
+/** MrvlIETypes_VendorParamSet_t */
+typedef struct _MrvlIETypes_VendorParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Information element */
+    t_u8 ie[MLAN_MAX_VSIE_LEN];
+} MrvlIETypes_VendorParamSet_t;
+
+/** MrvlIEtypes_RsnParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_RsnParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** RSN IE */
+    t_u8 rsn_ie[1];
+} MLAN_PACK_END MrvlIEtypes_RsnParamSet_t;
+
+/** Key_param_set fixed length */
+#define KEYPARAMSET_FIXED_LEN 6
+
+/** MrvlIEtype_KeyParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtype_KeyParamSet_t
+{
+    /** Type ID */
+    t_u16 type;
+    /** Length of Payload */
+    t_u16 length;
+    /** Type of Key: WEP=0, TKIP=1, AES=2 */
+    t_u16 key_type_id;
+    /** Key Control Info specific to a key_type_id */
+    t_u16 key_info;
+    /** Length of key */
+    t_u16 key_len;
+    /** Key material of size key_len */
+    t_u8 key[50];
+} MLAN_PACK_END MrvlIEtype_KeyParamSet_t;
+
+/** HostCmd_DS_802_11_KEY_MATERIAL */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_KEY_MATERIAL
+{
+    /** Action */
+    t_u16 action;
+    /** Key parameter set */
+    MrvlIEtype_KeyParamSet_t key_param_set;
+} MLAN_PACK_END HostCmd_DS_802_11_KEY_MATERIAL;
+
+/* Definition of firmware host command */
+/** HostCmd_DS_GEN */
+typedef struct _HostCmd_DS_GEN
+{
+    /** Command */
+    t_u16 command;
+    /** Size */
+    t_u16 size;
+    /** Sequence number */
+    t_u16 seq_num;
+    /** Result */
+    t_u16 result;
+} HostCmd_DS_GEN;
+
+/** Size of HostCmd_DS_GEN */
+#define S_DS_GEN        sizeof(HostCmd_DS_GEN)
+
+/* HostCmd_DS_802_11_SLEEP_PERIOD */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_SLEEP_PERIOD
+{
+    /** ACT_GET/ACT_SET */
+    t_u16 action;
+
+    /** Sleep Period in msec */
+    t_u16 sleep_pd;
+} MLAN_PACK_END HostCmd_DS_802_11_SLEEP_PERIOD;
+
+/* HostCmd_DS_802_11_SLEEP_PARAMS */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_SLEEP_PARAMS
+{
+    /** ACT_GET/ACT_SET */
+    t_u16 action;
+    /** Sleep clock error in ppm */
+    t_u16 error;
+    /** Wakeup offset in usec */
+    t_u16 offset;
+    /** Clock stabilization time in usec */
+    t_u16 stable_time;
+    /** Control periodic calibration */
+    t_u8 cal_control;
+    /** Control the use of external sleep clock */
+    t_u8 external_sleep_clk;
+    /** Reserved field, should be set to zero */
+    t_u16 reserved;
+} MLAN_PACK_END HostCmd_DS_802_11_SLEEP_PARAMS;
+
+/** Sleep response control */
+typedef enum _sleep_resp_ctrl
+{
+    RESP_NOT_NEEDED = 0,
+    RESP_NEEDED,
+} sleep_resp_ctrl;
+
+/** Structure definition for the new ieee power save parameters*/
+typedef struct __ps_param
+{
+      /** Null packet interval */
+    t_u16 null_pkt_interval;
+      /** Num dtims */
+    t_u16 multiple_dtims;
+      /** becaon miss interval */
+    t_u16 bcn_miss_timeout;
+      /** local listen interval */
+    t_u16 local_listen_interval;
+     /** Adhoc awake period */
+    t_u16 adhoc_wake_period;
+     /** mode - (0x01 - firmware to automatically choose PS_POLL or NULL mode, 0x02 - PS_POLL, 0x03 - NULL mode ) */
+    t_u16 mode;
+     /** Delay to PS in milliseconds */
+    t_u16 delay_to_ps;
+} ps_param;
+
+/** Structure definition for the new auto deep sleep command */
+typedef struct __auto_ds_param
+{
+     /** Deep sleep inactivity timeout */
+    t_u16 deep_sleep_timeout;
+} auto_ds_param;
+
+/** Structure definition for sleep confirmation in the new ps command */
+typedef struct __sleep_confirm_param
+{
+     /** response control 0x00 - response not needed, 0x01 - response needed */
+    t_u16 resp_ctrl;
+} sleep_confirm_param;
+
+/** Structure definition for new power save command */
+typedef MLAN_PACK_START struct _HostCmd_DS_PS_MODE_ENH
+{
+    /** Action */
+    t_u16 action;
+    /** Data speciifc to action */
+    /* For IEEE power save data will be as UINT16 mode (0x01 - firmware to
+       automatically choose PS_POLL or NULL mode, 0x02 - PS_POLL, 0x03 - NULL
+       mode ) UINT16 NullpacketInterval UINT16 NumDtims UINT16
+       BeaconMissInterval UINT16 locallisteninterval UINT16 adhocawakeperiod */
+
+    /* For auto deep sleep */
+    /* UINT16 Deep sleep inactivity timeout */
+
+    /* For PS sleep confirm UINT16 responeCtrl - 0x00 - reponse from fw not
+       needed, 0x01 - response from fw is needed */
+
+    union
+    {
+    /** PS param definition */
+        ps_param opt_ps;
+    /** Auto ds param definition */
+        auto_ds_param auto_ds;
+    /** Sleep comfirm param definition */
+        sleep_confirm_param sleep_cfm;
+    } params;
+} MLAN_PACK_END HostCmd_DS_802_11_PS_MODE_ENH;
+
+/** HostCmd_DS_GET_HW_SPEC */
+typedef MLAN_PACK_START struct _HostCmd_DS_GET_HW_SPEC
+{
+    /** HW Interface version number */
+    t_u16 hw_if_version;
+    /** HW version number */
+    t_u16 version;
+    /** Reserved field */
+    t_u16 reserved;
+    /** Max no of Multicast address  */
+    t_u16 num_of_mcast_adr;
+    /** MAC address */
+    t_u8 permanent_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Region Code */
+    t_u16 region_code;
+    /** Number of antenna used */
+    t_u16 number_of_antenna;
+    /** FW release number, example 0x1234=1.2.3.4 */
+    t_u32 fw_release_number;
+    /** Reserved field */
+    t_u32 reserved_1;
+    /** Reserved field */
+    t_u32 reserved_2;
+    /** Reserved field */
+    t_u32 reserved_3;
+    /** FW/HW Capability */
+    t_u32 fw_cap_info;
+    /** 802.11n Device Capabilities */
+    t_u32 dot_11n_dev_cap;
+    /** MIMO abstraction of MCSs supported by device */
+    t_u8 dev_mcs_support;
+        /** Valid end port at init */
+    t_u16 mp_end_port;
+    /* Reserved */
+    t_u16 reserved_4;
+} MLAN_PACK_END HostCmd_DS_GET_HW_SPEC;
+
+/**  HostCmd_DS_CMD_802_11_RSSI_INFO */
+typedef struct _HostCmd_DS_802_11_RSSI_INFO
+{
+    /** Action */
+    t_u16 action;
+    /** Parameter used for exponential averaging for Data */
+    t_u16 ndata;
+    /** Parameter used for exponential averaging for Beacon */
+    t_u16 nbcn;
+    /** Reserved field 0 */
+    t_u16 reserved[9];
+    /** Reserved field 1 */
+    t_u64 reserved_1;
+} HostCmd_DS_802_11_RSSI_INFO;
+
+/** HostCmd_DS_802_11_RSSI_INFO_RSP */
+typedef struct _HostCmd_DS_802_11_RSSI_INFO_RSP
+{
+    /** Action */
+    t_u16 action;
+    /** Parameter used for exponential averaging for Data */
+    t_u16 ndata;
+    /** Parameter used for exponential averaging for beacon */
+    t_u16 nbcn;
+    /** Last Data RSSI in dBm */
+    t_s16 data_rssi_last;
+    /** Last Data NF in dBm */
+    t_s16 data_nf_last;
+    /** AVG DATA RSSI in dBm */
+    t_s16 data_rssi_avg;
+    /** AVG DATA NF in dBm */
+    t_s16 data_nf_avg;
+    /** Last BEACON RSSI in dBm */
+    t_s16 bcn_rssi_last;
+    /** Last BEACON NF in dBm */
+    t_s16 bcn_nf_last;
+    /** AVG BEACON RSSI in dBm */
+    t_s16 bcn_rssi_avg;
+    /** AVG BEACON NF in dBm */
+    t_s16 bcn_nf_avg;
+    /** Last RSSI Beacon TSF */
+    t_u64 tsf_bcn;
+} HostCmd_DS_802_11_RSSI_INFO_RSP;
+
+/** HostCmd_DS_802_11_MAC_ADDRESS */
+typedef struct _HostCmd_DS_802_11_MAC_ADDRESS
+{
+    /** Action */
+    t_u16 action;
+    /** MAC address */
+    t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH];
+} HostCmd_DS_802_11_MAC_ADDRESS;
+
+/** HostCmd_DS_MAC_CONTROL */
+typedef struct _HostCmd_DS_MAC_CONTROL
+{
+    /** Action */
+    t_u16 action;
+    /** Reserved field */
+    t_u16 reserved;
+} HostCmd_DS_MAC_CONTROL;
+
+/**  HostCmd_CMD_MAC_MULTICAST_ADR */
+typedef MLAN_PACK_START struct _HostCmd_DS_MAC_MULTICAST_ADR
+{
+    /** Action */
+    t_u16 action;
+    /** Number of addresses */
+    t_u16 num_of_adrs;
+    /** List of MAC */
+    t_u8 mac_list[MLAN_MAC_ADDR_LENGTH * MLAN_MAX_MULTICAST_LIST_SIZE];
+} MLAN_PACK_END HostCmd_DS_MAC_MULTICAST_ADR;
+
+/**  HostCmd_CMD_802_11_DEAUTHENTICATE */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_DEAUTHENTICATE
+{
+    /** MAC address */
+    t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Deauthentication resaon code */
+    t_u16 reason_code;
+} MLAN_PACK_END HostCmd_DS_802_11_DEAUTHENTICATE;
+
+/** HostCmd_DS_802_11_ASSOCIATE */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_ASSOCIATE
+{
+    /** Peer STA address */
+    t_u8 peer_sta_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Capability information */
+    IEEEtypes_CapInfo_t cap_info;
+    /** Listen interval */
+    t_u16 listen_interval;
+    /** Beacon period */
+    t_u16 beacon_period;
+    /** DTIM period */
+    t_u8 dtim_period;
+
+    /**
+     *  MrvlIEtypes_SsIdParamSet_t  SsIdParamSet;
+     *  MrvlIEtypes_PhyParamSet_t   PhyParamSet;
+     *  MrvlIEtypes_SsParamSet_t    SsParamSet;
+     *  MrvlIEtypes_RatesParamSet_t RatesParamSet;
+     */
+} MLAN_PACK_END HostCmd_DS_802_11_ASSOCIATE;
+
+/** HostCmd_CMD_802_11_ASSOCIATE response */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_ASSOCIATE_RSP
+{
+    /** Association response structure */
+    IEEEtypes_AssocRsp_t assoc_rsp;
+} MLAN_PACK_END HostCmd_DS_802_11_ASSOCIATE_RSP;
+
+/** HostCmd_DS_802_11_AD_HOC_START*/
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_AD_HOC_START
+{
+    /** AdHoc SSID */
+    t_u8 ssid[MLAN_MAX_SSID_LENGTH];
+    /** BSS mode */
+    t_u8 bss_mode;
+    /** Beacon period */
+    t_u16 beacon_period;
+    /** DTIM period */
+    t_u8 dtim_period;
+    /** SS parameter set */
+    IEEEtypes_SsParamSet_t ss_param_set;
+    /** PHY parameter set */
+    IEEEtypes_PhyParamSet_t phy_param_set;
+    /** Reserved field */
+    t_u16 reserved1;
+    /** Capability information */
+    IEEEtypes_CapInfo_t cap;
+    /** Supported data rates */
+    t_u8 DataRate[HOSTCMD_SUPPORTED_RATES];
+} MLAN_PACK_END HostCmd_DS_802_11_AD_HOC_START;
+
+/**  HostCmd_CMD_802_11_AD_HOC_START response */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_AD_HOC_RESULT
+{
+    /** Padding */
+    t_u8 pad[3];
+    /** AdHoc BSSID */
+    t_u8 bssid[MLAN_MAC_ADDR_LENGTH];
+} MLAN_PACK_END HostCmd_DS_802_11_AD_HOC_RESULT;
+
+/** AdHoc_BssDesc_t */
+typedef MLAN_PACK_START struct _AdHoc_BssDesc_t
+{
+    /** BSSID */
+    t_u8 bssid[MLAN_MAC_ADDR_LENGTH];
+    /** SSID */
+    t_u8 ssid[MLAN_MAX_SSID_LENGTH];
+    /** BSS mode */
+    t_u8 bss_mode;
+    /** Beacon period */
+    t_u16 beacon_period;
+    /** DTIM period */
+    t_u8 dtim_period;
+    /** Timestamp */
+    t_u8 time_stamp[8];
+    /** Local time */
+    t_u8 local_time[8];
+    /** PHY parameter set */
+    IEEEtypes_PhyParamSet_t phy_param_set;
+    /** SS parameter set */
+    IEEEtypes_SsParamSet_t ss_param_set;
+    /** Capability information */
+    IEEEtypes_CapInfo_t cap;
+    /** Supported data rates */
+    t_u8 data_rates[HOSTCMD_SUPPORTED_RATES];
+
+    /* 
+     *  DO NOT ADD ANY FIELDS TO THIS STRUCTURE.
+     *  It is used in the Adhoc join command and will cause a 
+     *  binary layout mismatch with the firmware 
+     */
+} MLAN_PACK_END AdHoc_BssDesc_t;
+
+/** HostCmd_DS_802_11_AD_HOC_JOIN */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_AD_HOC_JOIN
+{
+    /** AdHoc BSS descriptor */
+    AdHoc_BssDesc_t bss_descriptor;
+    /** Reserved field */
+    t_u16 reserved1;
+    /** Reserved field */
+    t_u16 reserved2;
+} MLAN_PACK_END HostCmd_DS_802_11_AD_HOC_JOIN;
+
+typedef MLAN_PACK_START struct _HostCmd_DS_SDIO_PULL_CTRL
+{
+    /** Action */
+    t_u16 action;
+    /** The delay of pulling up in us */
+    t_u16 pull_up;
+    /** The delay of pulling down in us */
+    t_u16 pull_down;
+} MLAN_PACK_END HostCmd_DS_SDIO_PULL_CTRL;
+
+/** HostCmd_DS_802_11_GET_LOG */
+typedef struct _HostCmd_DS_802_11_GET_LOG
+{
+    /** Number of multicast transmitted frames */
+    t_u32 mcast_tx_frame;
+    /** Number of failures */
+    t_u32 failed;
+    /** Number of retries */
+    t_u32 retry;
+    /** Number of multiretries */
+    t_u32 multiretry;
+    /** Number of duplicate frames */
+    t_u32 frame_dup;
+    /** Number of RTS success */
+    t_u32 rts_success;
+    /** Number of RTS failure */
+    t_u32 rts_failure;
+    /** Number of acknowledgement failure */
+    t_u32 ack_failure;
+    /** Number of fragmented packets received */
+    t_u32 rx_frag;
+    /** Number of multicast frames received */
+    t_u32 mcast_rx_frame;
+    /** FCS error */
+    t_u32 fcs_error;
+    /** Number of transmitted frames */
+    t_u32 tx_frame;
+    /** Reserved field */
+    t_u32 reserved;
+    /** Number of WEP icv error for each key */
+    t_u32 wep_icv_err_cnt[4];
+} HostCmd_DS_802_11_GET_LOG;
+
+/**_HostCmd_TX_RATE_QUERY */
+typedef MLAN_PACK_START struct _HostCmd_TX_RATE_QUERY
+{
+    /** Tx rate */
+    t_u8 tx_rate;
+    /** Ht Info [Bit 0] RxRate format: LG=0, HT=1
+     * [Bit 1]  HT Bandwidth: BW20 = 0, BW40 = 1
+     * [Bit 2]  HT Guard Interval: LGI = 0, SGI = 1 */
+    t_u8 ht_info;
+} MLAN_PACK_END HostCmd_TX_RATE_QUERY;
+
+/** HS Action 0x0001 - Configure enhanced host sleep mode, 0x0002 - Activate enhanced host sleep mode */
+typedef enum _Host_Sleep_Action
+{
+    HS_CONFIGURE = 0x0001,
+    HS_ACTIVATE = 0x0002,
+} Host_Sleep_Action;
+
+typedef MLAN_PACK_START struct _hs_config_param
+{
+    /** bit0=1: non-unicast data
+      * bit1=1: unicast data
+      * bit2=1: mac events
+      * bit3=1: magic packet 
+      */
+    t_u32 conditions;
+    /** GPIO */
+    t_u8 gpio;
+    /** in milliseconds */
+    t_u8 gap;
+} MLAN_PACK_END hs_config_param;
+
+/** Structure definition for activating enhanced hs */
+typedef MLAN_PACK_START struct __hs_activate_param
+{
+     /** response control 0x00 - response not needed, 0x01 - response needed */
+    t_u16 resp_ctrl;
+} MLAN_PACK_END hs_activate_param;
+
+/** HostCmd_DS_802_11_HS_CFG_ENH */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_HS_CFG_ENH
+{
+    /** Action 0x0001 - Configure enhanced host sleep mode, 0x0002 - Activate enhanced host sleep mode */
+    t_u16 action;
+
+    union
+    {
+    /** Configure enhanced hs */
+        hs_config_param hs_config;
+    /** Activate enhanced hs */
+        hs_activate_param hs_activate;
+    } params;
+} MLAN_PACK_END HostCmd_DS_802_11_HS_CFG_ENH;
+
+/** HostCmd_DS_802_11_BCA_TIMESHARE */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_BCA_TIMESHARE
+{
+    /** Action */
+    t_u16 action;
+    /** Type: WLAN, BT */
+    t_u16 traffic_type;
+    /** 20msec - 60000msec */
+    t_u32 timeshare_interval;
+    /** PTA arbiter time in msec */
+    t_u32 bt_time;
+} MLAN_PACK_END HostCmd_DS_802_11_BCA_TIMESHARE;
+
+/** SNMP_MIB_INDEX */
+typedef enum _SNMP_MIB_INDEX
+{
+    OpRateSet_i = 1,
+    DtimPeriod_i = 3,
+    RtsThresh_i = 5,
+    ShortRetryLim_i = 6,
+    LongRetryLim_i = 7,
+    FragThresh_i = 8,
+    Dot11D_i = 9,
+    Dot11H_i = 10,
+    WwsMode_i = 17
+} SNMP_MIB_INDEX;
+
+/** max SNMP buf size */
+#define MAX_SNMP_BUF_SIZE   128
+
+/**  HostCmd_CMD_802_11_SNMP_MIB */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_SNMP_MIB
+{
+    /** SNMP query type */
+    t_u16 query_type;
+    /** SNMP object ID */
+    t_u16 oid;
+    /** SNMP buffer size */
+    t_u16 buf_size;
+    /** Value */
+    t_u8 value[1];
+} MLAN_PACK_END HostCmd_DS_802_11_SNMP_MIB;
+
+/** Radio on */
+#define RADIO_ON                                0x01
+/** Radio off */
+#define RADIO_OFF                               0x00
+
+/** HostCmd_CMD_802_11_RADIO_CONTROL */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_RADIO_CONTROL
+{
+    /** Action */
+    t_u16 action;
+    /** Control */
+    t_u16 control;
+} MLAN_PACK_END HostCmd_DS_802_11_RADIO_CONTROL;
+
+/** MrvlRateScope_t */
+typedef MLAN_PACK_START struct _MrvlRateScope_t
+{
+    /** Header Type */
+    t_u16 type;
+    /** Header Length */
+    t_u16 length;
+    /** Bitmap of HR/DSSS rates */
+    t_u16 hr_dsss_rate_bitmap;
+    /** Bitmap of OFDM rates */
+    t_u16 ofdm_rate_bitmap;
+    /** Bitmap of HT-MCSs allowed for initial rate */
+    t_u16 ht_mcs_rate_bitmap[8];
+} MLAN_PACK_END MrvlRateScope_t;
+
+/** MrvlRateDropControl_t */
+typedef MLAN_PACK_START struct _MrvlRateDropControl_t
+{
+    /** Header Length */
+    t_u16 length;
+    /** Rate Information */
+    t_u32 rate_info[1];
+} MLAN_PACK_END MrvlRateDropControl_t;
+
+/** MrvlRateDropPattern_t */
+typedef MLAN_PACK_START struct _MrvlRateDropPattern_t
+{
+    /** Header Type */
+    t_u16 type;
+    /** Header Length */
+    t_u16 length;
+    /** Rate Drop Mode */
+    t_u32 rate_drop_mode;
+    /* MrvlRateDropControl_t RateDropControl[0]; */
+} MLAN_PACK_END MrvlRateDropPattern_t;
+
+/** HostCmd_DS_TX_RATE_CFG */
+typedef MLAN_PACK_START struct _HostCmd_DS_TX_RATE_CFG
+{
+    /** Action */
+    t_u16 action;
+    /** Tx Rate Configuration Index */
+    t_u16 cfg_index;
+    /* MrvlRateScope_t RateScope; MrvlRateDropPattern_t RateDrop; */
+} MLAN_PACK_END HostCmd_DS_TX_RATE_CFG;
+
+/** Power_Group_t */
+typedef MLAN_PACK_START struct _Power_Group_t
+{
+    /** Modulation Class */
+    t_u8 modulation_class;
+    /** MCS Code or Legacy RateID */
+    t_u8 first_rate_code;
+    /** MCS Code or Legacy RateID */
+    t_u8 last_rate_code;
+    /** Power Adjustment Step */
+    t_s8 power_step;
+    /** Minimal Tx Power Level [dBm] */
+    t_s8 power_min;
+    /** Maximal Tx Power Level [dBm] */
+    t_s8 power_max;
+    /** 0: HTBW20, 1: HTBW40 */
+    t_u8 ht_bandwidth;
+    /** Reserved */
+    t_u8 reserved;
+} MLAN_PACK_END Power_Group_t;
+
+/** MrvlTypes_Power_Group_t */
+typedef MLAN_PACK_START struct _MrvlTypes_Power_Group_t
+{
+    /** Header Type */
+    t_u16 type;
+    /** Header Length */
+    t_u16 length;
+    /* Power_Group_t PowerGroups */
+} MLAN_PACK_END MrvlTypes_Power_Group_t;
+
+/** HostCmd_CMD_TXPWR_CFG */
+typedef MLAN_PACK_START struct _HostCmd_DS_TXPWR_CFG
+{
+    /** Action */
+    t_u16 action;
+    /** Power group configuration index */
+    t_u16 cfg_index;
+    /** Power group configuration mode */
+    t_u32 mode;
+    /* MrvlTypes_Power_Group_t PowerGrpCfg[0] */
+} MLAN_PACK_END HostCmd_DS_TXPWR_CFG;
+
+/** Maximum number of channels that can be sent in user scan config */
+#define WLAN_USER_SCAN_CHAN_MAX             50
+
+/** Maximum length of SSID list */
+#define MRVDRV_MAX_SSID_LIST_LENGTH         10
+
+/**
+ * @brief Structure used internally in the wlan driver to configure a scan.
+ *
+ * Sent to the command process module to configure the firmware
+ *   scan command prepared by wlan_cmd_802_11_scan.
+ *
+ * @sa wlan_scan_networks
+ *
+ */
+typedef MLAN_PACK_START struct _wlan_scan_cmd_config
+{
+    /**
+     *  BSS Type to be sent in the firmware command
+     *
+     *  Field can be used to restrict the types of networks returned in the
+     *    scan.  Valid settings are:
+     *
+     *   - MLAN_SCAN_MODE_BSS  (infrastructure)
+     *   - MLAN_SCAN_MODE_IBSS (adhoc)
+     *   - MLAN_SCAN_MODE_ANY  (unrestricted, adhoc and infrastructure)
+     */
+    t_u8 bss_mode;
+
+    /**
+     *  Specific BSSID used to filter scan results in the firmware
+     */
+    t_u8 specific_bssid[MLAN_MAC_ADDR_LENGTH];
+
+    /**
+     *  Length of TLVs sent in command starting at tlvBuffer
+     */
+    t_u32 tlv_buf_len;
+
+    /**
+     *  SSID TLV(s) and ChanList TLVs to be sent in the firmware command
+     *
+     *  TLV_TYPE_CHANLIST, MrvlIEtypes_ChanListParamSet_t
+     *  TLV_TYPE_SSID, MrvlIEtypes_SsIdParamSet_t
+     */
+    t_u8 tlv_buf[1];            /* SSID TLV(s) and ChanList TLVs are stored
+                                   here */
+} MLAN_PACK_END wlan_scan_cmd_config;
+
+/**
+ *  @brief IOCTL channel sub-structure sent in wlan_ioctl_user_scan_cfg
+ *
+ *  Multiple instances of this structure are included in the IOCTL command
+ *   to configure a instance of a scan on the specific channel.
+ */
+typedef MLAN_PACK_START struct _wlan_user_scan_chan
+{
+    /** Channel Number to scan */
+    t_u8 chan_number;
+    /** Radio type: 'B/G' Band = 0, 'A' Band = 1 */
+    t_u8 radio_type;
+    /** Scan type: Active = 0, Passive = 1 */
+    t_u8 scan_type;
+    /** Reserved */
+    t_u8 reserved;
+    /** Scan duration in milliseconds; if 0 default used */
+    t_u32 scan_time;
+} MLAN_PACK_END wlan_user_scan_chan;
+
+/**
+ *  IOCTL SSID List sub-structure sent in wlan_ioctl_user_scan_cfg
+ * 
+ *  Used to specify SSID specific filters as well as SSID pattern matching
+ *    filters for scan result processing in firmware.
+ */
+typedef MLAN_PACK_START struct _wlan_user_scan_ssid
+{
+    /** SSID */
+    t_u8 ssid[MLAN_MAX_SSID_LENGTH + 1];
+    /** Maximum length of SSID */
+    t_u8 max_len;
+} MLAN_PACK_END wlan_user_scan_ssid;
+
+/**
+ *  Input structure to configure an immediate scan cmd to firmware
+ *
+ *  Specifies a number of parameters to be used in general for the scan 
+ *    as well as a channel list (wlan_user_scan_chan) for each scan period
+ *    desired.
+ */
+typedef MLAN_PACK_START struct
+{
+    /**
+     *  Flag set to keep the previous scan table intact
+     *
+     *  If set, the scan results will accumulate, replacing any previous
+     *   matched entries for a BSS with the new scan data
+     */
+    t_u8 keep_previous_scan;
+    /**
+     *  BSS mode to be sent in the firmware command
+     *
+     *  Field can be used to restrict the types of networks returned in the
+     *    scan.  Valid settings are:
+     *
+     *   - MLAN_SCAN_MODE_BSS  (infrastructure)
+     *   - MLAN_SCAN_MODE_IBSS (adhoc)
+     *   - MLAN_SCAN_MODE_ANY  (unrestricted, adhoc and infrastructure)        
+     */
+    t_u8 bss_mode;
+    /**
+     *  Configure the number of probe requests for active chan scans
+     */
+    t_u8 num_probes;
+    /**
+     *  @brief Reserved
+     */
+    t_u8 reserved;
+    /**
+     *  @brief BSSID filter sent in the firmware command to limit the results
+     */
+    t_u8 specific_bssid[MLAN_MAC_ADDR_LENGTH];
+    /**
+     *  SSID filter list used in the to limit the scan results
+     */
+    wlan_user_scan_ssid ssid_list[MRVDRV_MAX_SSID_LIST_LENGTH];
+    /**
+     *  Variable number (fixed maximum) of channels to scan up
+     */
+    wlan_user_scan_chan chan_list[WLAN_USER_SCAN_CHAN_MAX];
+} MLAN_PACK_END wlan_user_scan_cfg;
+
+/**
+ *  Sructure to retrieve the scan table
+ */
+typedef MLAN_PACK_START struct
+{
+    /**
+     *  - Zero based scan entry to start retrieval in command request
+     *  - Number of scans entries returned in command response
+     */
+    t_u32 scan_number;
+    /**
+     * Buffer marker for multiple wlan_ioctl_get_scan_table_entry structures.
+     *   Each struct is padded to the nearest 32 bit boundary.
+     */
+    t_u8 scan_table_entry_buf[1];
+} MLAN_PACK_END wlan_get_scan_table_info;
+
+/** Generic structure defined for parsing WPA/RSN IEs for GTK/PTK OUIs */
+typedef MLAN_PACK_START struct
+{
+        /** Group key oui */
+    t_u8 GrpKeyOui[4];
+        /** Number of PTKs */
+    t_u8 PtkCnt[2];
+        /** Ptk body starts here */
+    t_u8 PtkBody[4];
+} MLAN_PACK_END IEBody;
+
+/* 
+ * This scan handle Country Information IE(802.11d compliant) 
+ * Define data structure for HostCmd_CMD_802_11_SCAN 
+ */
+/** HostCmd_DS_802_11_SCAN */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_SCAN
+{
+    /** BSS mode */
+    t_u8 bss_mode;
+    /** BSSID */
+    t_u8 bssid[MLAN_MAC_ADDR_LENGTH];
+    /** TLV buffer */
+    t_u8 tlv_buffer[1];
+    /** MrvlIEtypes_SsIdParamSet_t      SsIdParamSet; 
+     *  MrvlIEtypes_ChanListParamSet_t  ChanListParamSet;
+     *  MrvlIEtypes_RatesParamSet_t     OpRateSet; 
+     */
+} MLAN_PACK_END HostCmd_DS_802_11_SCAN;
+
+/** HostCmd_DS_802_11_SCAN_RSP */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_SCAN_RSP
+{
+    /** Size of BSS descriptor */
+    t_u16 bss_descript_size;
+    /** Numner of sets */
+    t_u8 number_of_sets;
+    /** BSS descriptor and TLV buffer */
+    t_u8 bss_desc_and_tlv_buffer[1];
+} MLAN_PACK_END HostCmd_DS_802_11_SCAN_RSP;
+
+/** HostCmd_DS_802_11_BG_SCAN_QUERY */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_BG_SCAN_QUERY
+{
+    /** Flush */
+    t_u8 flush;
+} MLAN_PACK_END HostCmd_DS_802_11_BG_SCAN_QUERY;
+
+/** HostCmd_DS_802_11_BG_SCAN_QUERY_RSP */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_BG_SCAN_QUERY_RSP
+{
+    /** Report condition */
+    t_u32 report_condition;
+    /** Scan response */
+    HostCmd_DS_802_11_SCAN_RSP scan_resp;
+} MLAN_PACK_END HostCmd_DS_802_11_BG_SCAN_QUERY_RSP;
+
+/** MrvlIEtypes_DomainParamSet_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_DomainParamSet
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Country code */
+    t_u8 country_code[COUNTRY_CODE_LEN];
+    /** Set of subbands */
+    IEEEtypes_SubbandSet_t sub_band[1];
+} MLAN_PACK_END MrvlIEtypes_DomainParamSet_t;
+
+/** HostCmd_DS_802_11D_DOMAIN_INFO */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11D_DOMAIN_INFO
+{
+    /** Action */
+    t_u16 action;
+    /** Domain parameter set */
+    MrvlIEtypes_DomainParamSet_t domain;
+} MLAN_PACK_END HostCmd_DS_802_11D_DOMAIN_INFO;
+
+/** HostCmd_DS_802_11D_DOMAIN_INFO_RSP */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11D_DOMAIN_INFO_RSP
+{
+    /** Action */
+    t_u16 action;
+    /** Domain parameter set */
+    MrvlIEtypes_DomainParamSet_t domain;
+} MLAN_PACK_END HostCmd_DS_802_11D_DOMAIN_INFO_RSP;
+
+/** HostCmd_DS_11N_ADDBA_REQ */
+typedef MLAN_PACK_START struct _HostCmd_DS_11N_ADDBA_REQ
+{
+    /** Result of the ADDBA Request Operation */
+    t_u8 add_req_result;
+    /** Peer MAC address */
+    t_u8 peer_mac_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Dialog Token */
+    t_u8 dialog_token;
+    /** Block Ack Parameter Set */
+    t_u16 block_ack_param_set;
+    /** Block Act Timeout Value */
+    t_u16 block_ack_tmo;
+    /** Starting Sequence Number */
+    t_u16 ssn;
+} MLAN_PACK_END HostCmd_DS_11N_ADDBA_REQ;
+
+/** HostCmd_DS_11N_ADDBA_RSP */
+typedef MLAN_PACK_START struct _HostCmd_DS_11N_ADDBA_RSP
+{
+    /** Result of the ADDBA Response Operation */
+    t_u8 add_rsp_result;
+    /** Peer MAC address */
+    t_u8 peer_mac_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Dialog Token */
+    t_u8 dialog_token;
+    /** Status Code */
+    t_u16 status_code;
+    /** Block Ack Parameter Set */
+    t_u16 block_ack_param_set;
+    /** Block Act Timeout Value */
+    t_u16 block_ack_tmo;
+    /** Starting Sequence Number */
+    t_u16 ssn;
+} MLAN_PACK_END HostCmd_DS_11N_ADDBA_RSP;
+
+/** HostCmd_DS_11N_DELBA */
+typedef MLAN_PACK_START struct _HostCmd_DS_11N_DELBA
+{
+    /** Result of the ADDBA Request Operation */
+    t_u8 del_result;
+    /** Peer MAC address */
+    t_u8 peer_mac_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Delete Block Ack Parameter Set */
+    t_u16 del_ba_param_set;
+    /** Reason Code sent for DELBA */
+    t_u16 reason_code;
+    /** Reserved */
+    t_u8 reserved;
+} MLAN_PACK_END HostCmd_DS_11N_DELBA;
+
+/** HostCmd_DS_11N_BATIMEOUT */
+typedef MLAN_PACK_START struct _HostCmd_DS_11N_BATIMEOUT
+{
+    /** TID */
+    t_u8 tid;
+    /** Peer MAC address */
+    t_u8 peer_mac_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Delete Block Ack Parameter Set */
+    t_u8 origninator;
+} MLAN_PACK_END HostCmd_DS_11N_BATIMEOUT;
+
+/** HostCmd_DS_11N_CFG */
+typedef MLAN_PACK_START struct _HostCmd_DS_11N_CFG
+{
+    /** Action */
+    t_u16 action;
+    /** HTTxCap */
+    t_u16 ht_tx_cap;
+    /** HTTxInfo */
+    t_u16 ht_tx_info;
+} MLAN_PACK_END HostCmd_DS_11N_CFG;
+
+/** HostCmd_DS_TXBUF_CFG*/
+typedef MLAN_PACK_START struct _HostCmd_DS_TXBUF_CFG
+{
+    /** Action */
+    t_u16 action;
+    /** Buffer Size */
+    t_u16 buff_size;
+    /** End Port_for Multiport */
+    t_u16 mp_end_port;
+    /** Reserved */
+    t_u16 reserved3;
+} MLAN_PACK_END HostCmd_DS_TXBUF_CFG;
+
+/** HostCmd_DS_AMSDU_AGGR_CTRL */
+typedef MLAN_PACK_START struct _HostCmd_DS_AMSDU_AGGR_CTRL
+{
+    /** Action */
+    t_u16 action;
+    /** Enable */
+    t_u16 enable;
+    /** Get the current Buffer Size valid */
+    t_u16 curr_buf_size;
+} MLAN_PACK_END HostCmd_DS_AMSDU_AGGR_CTRL;
+
+/** HostCmd_DS_802_11_LDO_CFG */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_LDO_CFG
+{
+    /** Action */
+    t_u16 action;
+    /** PM Source: 0 = LDO_INTERNAL, 1 = LDO_EXTERNAL */
+    t_u16 pmsource;
+} MLAN_PACK_END HostCmd_DS_802_11_LDO_CFG;
+
+/** HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG */
+typedef MLAN_PACK_START struct _HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG
+{
+    /** Action */
+    t_u16 action;
+    /** Current system clock */
+    t_u16 cur_sys_clk;
+    /** Clock type */
+    t_u16 sys_clk_type;
+    /** Length of clocks */
+    t_u16 sys_clk_len;
+    /** System clocks */
+    t_u16 sys_clk[16];
+} MLAN_PACK_END HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG;
+
+/** MrvlIEtypes_WmmParamSet_t */
+typedef struct _MrvlIEtypes_WmmParamSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** WMM IE */
+    t_u8 wmm_ie[1];
+} MrvlIEtypes_WmmParamSet_t;
+
+/** MrvlIEtypes_WmmQueueStatus_t */
+typedef struct
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Queue index */
+    t_u8 queue_index;
+    /** Disabled flag */
+    t_u8 disabled;
+    /** Medium time allocation in 32us units*/
+    t_u16 medium_time;
+    /** Flow required flag */
+    t_u8 flow_required;
+    /** Flow created flag */
+    t_u8 flow_created;
+    /** Reserved */
+    t_u32 reserved;
+} MrvlIEtypes_WmmQueueStatus_t;
+
+/** Size of a TSPEC.  Used to allocate necessary buffer space in commands */
+#define WMM_TSPEC_SIZE              63
+
+/** Maximum number of AC QOS queues available in the driver/firmware */
+#define MAX_AC_QUEUES               4
+
+/** Extra IE bytes allocated in messages for appended IEs after a TSPEC */
+#define WMM_ADDTS_EXTRA_IE_BYTES    256
+
+/** Extra TLV bytes allocated in messages for configuring WMM Queues */
+#define WMM_QUEUE_CONFIG_EXTRA_TLV_BYTES 64
+
+/** Number of bins in the histogram for the HostCmd_DS_WMM_QUEUE_STATS */
+#define WMM_STATS_PKTS_HIST_BINS  7
+
+/**
+ *  @brief Firmware command structure to retrieve the firmware WMM status.
+ *
+ *  Used to retrieve the status of each WMM AC Queue in TLV 
+ *    format (MrvlIEtypes_WmmQueueStatus_t) as well as the current WMM
+ *    parameter IE advertised by the AP.  
+ *  
+ *  Used in response to a EVENT_WMM_STATUS_CHANGE event signaling
+ *    a QOS change on one of the ACs or a change in the WMM Parameter in
+ *    the Beacon.
+ *
+ *  TLV based command, byte arrays used for max sizing purpose. There are no 
+ *    arguments sent in the command, the TLVs are returned by the firmware.
+ */
+typedef MLAN_PACK_START struct
+{
+    /** Queue status TLV */
+    t_u8 queue_status_tlv[sizeof(MrvlIEtypes_WmmQueueStatus_t) * MAX_AC_QUEUES];
+    /** WMM parameter TLV */
+    t_u8 wmm_param_tlv[sizeof(IEEEtypes_WmmParameter_t) + 2];
+}
+MLAN_PACK_END HostCmd_DS_WMM_GET_STATUS;
+
+/**
+ *  @brief Command structure for the HostCmd_CMD_WMM_ADDTS_REQ firmware command
+ */
+typedef MLAN_PACK_START struct
+{
+    mlan_cmd_result_e command_result;                   /**< Command result */
+    t_u32 timeout_ms;                                   /**< Timeout value in milliseconds */
+    t_u8 dialog_token;                                  /**< Dialog token */
+    t_u8 ieee_status_code;                              /**< IEEE status code */
+    t_u8 tspec_data[WMM_TSPEC_SIZE];                    /**< TSPEC data */
+    t_u8 addts_extra_ie_buf[WMM_ADDTS_EXTRA_IE_BYTES];  /**< ADDTS extra IE buffer */
+} MLAN_PACK_END HostCmd_DS_WMM_ADDTS_REQ;
+
+/**
+ *  @brief Command structure for the HostCmd_CMD_WMM_DELTS_REQ firmware command
+ */
+typedef MLAN_PACK_START struct
+{
+    mlan_cmd_result_e command_result;   /**< Command result */
+    t_u8 dialog_token;                  /**< Dialog token */
+    t_u8 ieee_reason_code;              /**< IEEE reason code */
+    t_u8 tspec_data[WMM_TSPEC_SIZE];    /**< TSPEC data */
+} MLAN_PACK_END HostCmd_DS_WMM_DELTS_REQ;
+
+/**
+ *  @brief Command structure for the HostCmd_CMD_WMM_QUEUE_CONFIG firmware cmd
+ *
+ *  Set/Get/Default the Queue parameters for a specific AC in the firmware.
+ */
+typedef MLAN_PACK_START struct
+{
+    mlan_wmm_queue_config_action_e action;  /**< Set, Get, or Default */
+    mlan_wmm_ac_e access_category;          /**< WMM_AC_BK(0) to WMM_AC_VO(3) */
+    /** @brief MSDU lifetime expiry per 802.11e
+     *
+     *   - Ignored if 0 on a set command 
+     *   - Set to the 802.11e specified 500 TUs when defaulted
+     */
+    t_u16 msdu_lifetime_expiry;
+    t_u8 tlv_buffer[WMM_QUEUE_CONFIG_EXTRA_TLV_BYTES];  /**< Not supported yet */
+} MLAN_PACK_END HostCmd_DS_WMM_QUEUE_CONFIG;
+
+/**
+ *  @brief Command structure for the HostCmd_CMD_WMM_QUEUE_STATS firmware cmd
+ *
+ *  Turn statistical collection on/off for a given AC or retrieve the
+ *    accumulated stats for an AC and clear them in the firmware.
+ */
+typedef MLAN_PACK_START struct
+{
+    mlan_wmm_queue_stats_action_e action;  /**< Start, Stop, or Get */
+    mlan_wmm_ac_e access_category;    /**< WMM_AC_BK(0) to WMM_AC_VO(3) */
+    t_u16 pkt_count;      /**< Number of successful packets transmitted */
+    t_u16 pkt_loss;       /**< Packets lost; not included in pktCount */
+    t_u32 avg_queue_delay; /**< Average Queue delay in microseconds */
+    t_u32 avg_tx_delay;    /**< Average Transmission delay in microseconds */
+    t_u16 used_time;      /**< Calculated used time - units of 32 microseconds */
+    t_u16 policed_time;   /**< Calculated policed time - units of 32 microseconds */
+    /** @brief Queue Delay Histogram; number of packets per queue delay range
+     *
+     *  [0] -  0ms <= delay < 5ms
+     *  [1] -  5ms <= delay < 10ms
+     *  [2] - 10ms <= delay < 20ms
+     *  [3] - 20ms <= delay < 30ms
+     *  [4] - 30ms <= delay < 40ms
+     *  [5] - 40ms <= delay < 50ms
+     *  [6] - 50ms <= delay < msduLifetime (TUs)
+     */
+    t_u16 delay_histogram[WMM_STATS_PKTS_HIST_BINS];
+    /** Reserved */
+    t_u16 reserved_1;
+} MLAN_PACK_END HostCmd_DS_WMM_QUEUE_STATS;
+
+/**
+ *  @brief Command structure for the HostCmd_CMD_WMM_TS_STATUS firmware cmd
+ *
+ *  Query the firmware to get the status of the WMM Traffic Streams
+ */
+typedef MLAN_PACK_START struct
+{
+    /** TSID: Range: 0->7 */
+    t_u8 tid;
+    /** TSID specified is valid */
+    t_u8 valid;
+    /** AC TSID is active on */
+    t_u8 access_category;
+    /** UP specified for the TSID */
+    t_u8 user_priority;
+    /** Power save mode for TSID: 0 (legacy), 1 (UAPSD) */
+    t_u8 psb;
+    /** Upstream(0), Downlink(1), Bidirectional(3) */
+    t_u8 flow_dir;
+    /** Medium time granted for the TSID */
+    t_u16 medium_time;
+} MLAN_PACK_END HostCmd_DS_WMM_TS_STATUS;
+
+/** Firmware status for a specific AC */
+typedef struct
+{
+    /** Disabled flag */
+    t_u8 disabled;
+    /** Flow required flag */
+    t_u8 flow_required;
+    /** Flow created flag */
+    t_u8 flow_created;
+} WmmAcStatus_t;
+
+/**  Local Power Capability */
+typedef MLAN_PACK_START struct _MrvlIEtypes_PowerCapability_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Minmum power */
+    t_s8 min_power;
+    /** Maximum power */
+    t_s8 max_power;
+} MLAN_PACK_END MrvlIEtypes_PowerCapability_t;
+
+/** HT Capabilities element */
+typedef MLAN_PACK_START struct _MrvlIETypes_HTCap_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+
+    /** HTCap struct */
+    HTCap_t ht_cap;
+} MLAN_PACK_END MrvlIETypes_HTCap_t;
+
+/** HT Information element */
+typedef MLAN_PACK_START struct _MrvlIETypes_HTInfo_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+
+    /** HTInfo struct */
+    HTInfo_t ht_info;
+} MLAN_PACK_END MrvlIETypes_HTInfo_t;
+
+/** 20/40 BSS Coexistence element */
+typedef MLAN_PACK_START struct _MrvlIETypes_2040BSSCo_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+
+    /** BSSCo2040_t struct */
+    BSSCo2040_t bss_co_2040;
+} MLAN_PACK_END MrvlIETypes_2040BSSCo_t;
+
+/** Extended Capabilities element */
+typedef MLAN_PACK_START struct _MrvlIETypes_ExtCap_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+
+    /** ExtCap_t struct */
+    ExtCap_t ext_cap;
+} MLAN_PACK_END MrvlIETypes_ExtCap_t;
+
+/** Overlapping BSS Scan Parameters element */
+typedef MLAN_PACK_START struct _MrvlIETypes_OverlapBSSScanParam_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+
+    /** OBSSScanParam_t struct */
+    OBSSScanParam_t obss_scan_param;
+} MLAN_PACK_END MrvlIETypes_OverlapBSSScanParam_t;
+
+/** Set of MCS values that STA desires to use within the BSS */
+typedef MLAN_PACK_START struct _MrvlIETypes_HTOperationalMCSSet_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+
+    /** Bitmap indicating MCSs that STA desires to use within the BSS */
+    t_u8 ht_operational_mcs_bitmap[16];
+} MLAN_PACK_END MrvlIETypes_HTOperationalMCSSet_t;
+
+/** MrvlIEtypes_PMK_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_PMK_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** PMK */
+    t_u8 pmk[1];
+} MLAN_PACK_END MrvlIEtypes_PMK_t;
+/** MrvlIEtypes_Passphrase_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_Passphrase_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Passphrase */
+    char passphrase[1];
+} MLAN_PACK_END MrvlIEtypes_Passphrase_t;
+/* unicastCipher -
+ *      Bit 0   : RFU
+ *      Bit 1   : RFU
+ *      Bit 2   : TKIP
+ *      Bit 3   : AES CCKM
+ *      Bit 2-7 : RFU
+ * multicastCipher -
+ *      Bit 0   : WEP40
+ *      Bit 1   : WEP104
+ *      Bit 2   : TKIP
+ *      Bit 3   : AES
+ *      Bit 4-7 : Reserved for now
+ */
+/** MrvlIEtypes_Cipher_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_Cipher_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** PairCipher */
+    t_u8 pair_cipher;
+    /** GroupCipher */
+    t_u8 group_cipher;
+} MLAN_PACK_END MrvlIEtypes_Cipher_t;
+/* rsnMode -    
+ *      Bit 0    : No RSN
+ *      Bit 1-2  : RFU
+ *      Bit 3    : WPA
+ *      Bit 4    : WPA-NONE
+ *      Bit 5    : WPA2
+ *      Bit 6    : AES CCKM
+ *      Bit 7-15 : RFU
+ */
+/** MrvlIEtypes_Cipher_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_EncrProto_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** EncrProto */
+    t_u16 rsn_mode;
+} MLAN_PACK_END MrvlIEtypes_EncrProto_t;
+
+/** MrvlIEtypes_Bssid_t */
+typedef MLAN_PACK_START struct _MrvlIEtypes_Bssid_t
+{
+    /** Header */
+    MrvlIEtypesHeader_t header;
+    /** Bssid */
+    t_u8 bssid[MLAN_MAC_ADDR_LENGTH];
+} MLAN_PACK_END MrvlIEtypes_Bssid_t;
+
+/*
+ * This struct will handle GET,SET,CLEAR function for embedded
+ * supplicant.
+ * Define data structure for HostCmd_CMD_802_11_SUPPLICANT_PMK
+ */
+/** HostCmd_DS_802_11_SUPPLICANT_PMK */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_SUPPLICANT_PMK
+{
+    /** CMD Action GET/SET/CLEAR */
+    t_u16 action;
+    /** CacheResult initialized to 0 */
+    t_u16 cache_result;
+    /** TLV Buffer */
+    t_u8 tlv_buffer[1];
+    /** MrvlIEtypes_SsidParamSet_t  SsidParamSet;
+      * MrvlIEtypes_PMK_t           Pmk;
+      * MrvlIEtypes_Passphrase_t    Passphrase;
+      * MrvlIEtypes_Bssid_t         Bssid;
+      **/
+} MLAN_PACK_END HostCmd_DS_802_11_SUPPLICANT_PMK;
+
+/*
+ * This struct will GET the Supplicant supported bitmaps
+ * The GET_CURRENT action will get the network profile used
+ * for the current assocation.
+ * Define data structure for HostCmd_CMD_802_11_SUPPLICANT_PROFILE
+ */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_SUPPLICANT_PROFILE
+{
+    /** GET/SET/GET_CURRENT */
+    t_u16 action;
+    /** Reserved */
+    t_u16 reserved;
+    /** TLVBuffer */
+    t_u8 tlv_buf[1];
+    /* MrvlIEtypes_EncrProto_t */
+} MLAN_PACK_END HostCmd_DS_802_11_SUPPLICANT_PROFILE;
+
+/** HostCmd_CMD_802_11_RF_CHANNEL */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_RF_CHANNEL
+{
+    /** Action */
+    t_u16 action;
+    /** Current channel */
+    t_u16 current_channel;
+    /** RF type */
+    t_u16 rf_type;
+    /** Reserved field */
+    t_u16 reserved;
+    /** Reserved */
+    t_u8 reserved_1[32];
+} MLAN_PACK_END HostCmd_DS_802_11_RF_CHANNEL;
+
+/** HostCmd_DS_VERSION_EXT */
+typedef MLAN_PACK_START struct _HostCmd_DS_VERSION_EXT
+{
+    /** Selected version string */
+    t_u8 version_str_sel;
+    /** Version string */
+    char version_str[128];
+} MLAN_PACK_END HostCmd_DS_VERSION_EXT;
+
+/** HostCmd_CMD_802_11_RF_ANTENNA */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_RF_ANTENNA
+{
+    /** Action */
+    t_u16 action;
+    /**  Number of antennas or 0xffff(diversity) */
+    t_u16 antenna_mode;
+} MLAN_PACK_END HostCmd_DS_802_11_RF_ANTENNA;
+
+/** HostCmd_DS_802_11_IBSS_STATUS */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_IBSS_STATUS
+{
+    /** Action */
+    t_u16 action;
+    /** Enable */
+    t_u16 enable;
+    /** BSSID */
+    t_u8 bssid[MLAN_MAC_ADDR_LENGTH];
+    /** Beacon interval */
+    t_u16 beacon_interval;
+    /** ATIM window interval */
+    t_u16 atim_window;
+    /** User G rate protection */
+    t_u16 use_g_rate_protect;
+} MLAN_PACK_END HostCmd_DS_802_11_IBSS_STATUS;
+
+/** HostCmd_CMD_MAC_REG_ACCESS */
+typedef MLAN_PACK_START struct _HostCmd_DS_MAC_REG_ACCESS
+{
+    /** Action */
+    t_u16 action;
+    /** MAC register offset */
+    t_u16 offset;
+    /** MAC register value */
+    t_u32 value;
+} MLAN_PACK_END HostCmd_DS_MAC_REG_ACCESS;
+
+/** HostCmd_CMD_BBP_REG_ACCESS */
+typedef MLAN_PACK_START struct _HostCmd_DS_BBP_REG_ACCESS
+{
+    /** Acion */
+    t_u16 action;
+    /** BBP register offset */
+    t_u16 offset;
+    /** BBP register value */
+    t_u8 value;
+    /** Reserved field */
+    t_u8 reserved[3];
+} MLAN_PACK_END HostCmd_DS_BBP_REG_ACCESS;
+
+/**  HostCmd_CMD_RF_REG_ACCESS */
+typedef MLAN_PACK_START struct _HostCmd_DS_RF_REG_ACCESS
+{
+    /** Action */
+    t_u16 action;
+    /** RF register offset */
+    t_u16 offset;
+    /** RF register value */
+    t_u8 value;
+    /** Reserved field */
+    t_u8 reserved[3];
+} MLAN_PACK_END HostCmd_DS_RF_REG_ACCESS;
+
+/**  HostCmd_CMD_PMIC_REG_ACCESS */
+typedef MLAN_PACK_START struct _HostCmd_DS_PMIC_REG_ACCESS
+{
+    /** Action */
+    t_u16 action;
+    /** PMIC register offset */
+    t_u16 offset;
+    /** PMIC register value */
+    t_u8 value;
+    /** Reserved field */
+    t_u8 reserved[3];
+} MLAN_PACK_END HostCmd_DS_PMIC_REG_ACCESS;
+
+/** HostCmd_DS_802_11_EEPROM_ACCESS */
+typedef MLAN_PACK_START struct _HostCmd_DS_802_11_EEPROM_ACCESS
+{
+        /** Action */
+    t_u16 action;
+
+        /** multiple 4 */
+    t_u16 offset;
+        /** Number of bytes */
+    t_u16 byte_count;
+        /** Value */
+    t_u8 value;
+} MLAN_PACK_END HostCmd_DS_802_11_EEPROM_ACCESS;
+
+/** HostCmd_DS_MEM_ACCESS */
+typedef MLAN_PACK_START struct _HostCmd_DS_MEM_ACCESS
+{
+        /** Action */
+    t_u16 action;
+        /** Reserved field */
+    t_u16 reserved;
+        /** Address */
+    t_u32 addr;
+        /** Value */
+    t_u32 value;
+} MLAN_PACK_END HostCmd_DS_MEM_ACCESS;
+
+/** HostCmd_DS_INACTIVITY_TIMEOUT_EXT */
+typedef MLAN_PACK_START struct _HostCmd_DS_INACTIVITY_TIMEOUT_EXT
+{
+    /** ACT_GET/ACT_SET */
+    t_u16 action;
+    /** uS, 0 means 1000uS(1ms) */
+    t_u16 timeout_unit;
+    /** Inactivity timeout for unicast data */
+    t_u16 unicast_timeout;
+    /** Inactivity timeout for multicast data */
+    t_u16 mcast_timeout;
+    /** Timeout for additional RX traffic after Null PM1 packet exchange */
+    t_u16 ps_entry_timeout;
+    /** Reserved to further expansion */
+    t_u16 reserved;
+} MLAN_PACK_END HostCmd_DS_INACTIVITY_TIMEOUT_EXT;
+
+/**
+ * @brief 802.11h Local Power Constraint Marvell extended TLV
+ */
+typedef MLAN_PACK_START struct
+{
+    MrvlIEtypesHeader_t header;  /**< Marvell TLV header: ID/Len */
+    t_u8 chan;                     /**< Channel local constraint applies to */
+
+    /** Power constraint included in beacons and used by fw to offset 11d info */
+    t_u8 constraint;
+
+} MLAN_PACK_END MrvlIEtypes_LocalPowerConstraint_t;
+
+/*
+ *
+ * Data structures for driver/firmware command processing
+ *
+ */
+
+/**  TPC Info structure sent in CMD_802_11_TPC_INFO command to firmware */
+typedef MLAN_PACK_START struct
+{
+    MrvlIEtypes_LocalPowerConstraint_t local_constraint;  /**< Local constraint */
+    MrvlIEtypes_PowerCapability_t power_cap;              /**< Power Capability */
+
+} MLAN_PACK_END HostCmd_DS_802_11_TPC_INFO;
+
+/**  TPC Request structure sent in CMD_802_11_TPC_ADAPT_REQ command to firmware */
+typedef MLAN_PACK_START struct
+{
+    t_u8 dest_mac[MLAN_MAC_ADDR_LENGTH];        /**< Destination STA address  */
+    t_u16 timeout;                              /**< Response timeout in ms */
+    t_u8 rate_index;                            /**< IEEE Rate index to send request */
+
+} MLAN_PACK_END HostCmd_TpcRequest;
+
+/**  TPC Response structure received from the CMD_802_11_TPC_ADAPT_REQ command */
+typedef MLAN_PACK_START struct
+{
+    t_u8 tpc_ret_code;      /**< Firmware command result status code */
+    t_s8 tx_power;          /**< Reported TX Power from the TPC Report element */
+    t_s8 link_margin;       /**< Reported link margin from the TPC Report element */
+    t_s8 rssi;              /**< RSSI of the received TPC Report frame */
+
+} MLAN_PACK_END HostCmd_TpcResponse;
+
+/**  CMD_802_11_TPC_ADAPT_REQ substruct. Union of the TPC request and response */
+typedef MLAN_PACK_START union
+{
+    HostCmd_TpcRequest req;   /**< Request struct sent to firmware */
+    HostCmd_TpcResponse resp; /**< Response struct received from firmware */
+
+} MLAN_PACK_END HostCmd_DS_802_11_TPC_ADAPT_REQ;
+
+/**  CMD_802_11_CHAN_SW_ANN firmware command substructure */
+typedef MLAN_PACK_START struct
+{
+    t_u8 switch_mode;   /**< Set to 1 for a quiet switch request, no STA tx */
+    t_u8 new_chan;      /**< Requested new channel */
+    t_u8 switch_count;  /**< Number of TBTTs until the switch is to occur */
+} MLAN_PACK_END HostCmd_DS_802_11_CHAN_SW_ANN;
+
+/**        
+ * @brief Enumeration of measurement types, including max supported 
+ *        enum for 11h/11k
+ */
+typedef MLAN_PACK_START enum
+{
+    WLAN_MEAS_BASIC = 0,              /**< 11h: Basic */
+    WLAN_MEAS_NUM_TYPES,              /**< Number of enumerated measurements */
+    WLAN_MEAS_11H_MAX_TYPE = WLAN_MEAS_BASIC,          /**< Max 11h measurement */
+
+} MLAN_PACK_END MeasType_t;
+
+/**        
+ * @brief Mode octet of the measurement request element (7.3.2.21)
+ */
+typedef MLAN_PACK_START struct
+{
+#ifdef BIG_ENDIAN
+    t_u8 rsvd5_7:3;               /**< Reserved */
+    t_u8 duration_mandatory:1;    /**< 11k: duration spec. for meas. is mandatory */
+    t_u8 report:1;                /**< 11h: en/disable report rcpt. of spec. type */
+    t_u8 request:1;               /**< 11h: en/disable requests of specified type */
+    t_u8 enable:1;                /**< 11h: enable report/request bits */
+    t_u8 parallel:1;              /**< 11k: series or parallel with previous meas */
+#else
+    t_u8 parallel:1;              /**< 11k: series or parallel with previous meas */
+    t_u8 enable:1;                /**< 11h: enable report/request bits */
+    t_u8 request:1;               /**< 11h: en/disable requests of specified type */
+    t_u8 report:1;                /**< 11h: en/disable report rcpt. of spec. type */
+    t_u8 duration_mandatory:1;    /**< 11k: duration spec. for meas. is mandatory */
+    t_u8 rsvd5_7:3;               /**< Reserved */
+#endif                          /* BIG_ENDIAN */
+
+} MLAN_PACK_END MeasReqMode_t;
+
+/**        
+ * @brief Common measurement request structure (7.3.2.21.1 to 7.3.2.21.3)
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 channel;      /**< Channel to measure */
+    t_u64 start_time;  /**< TSF Start time of measurement (0 for immediate) */
+    t_u16 duration;    /**< TU duration of the measurement */
+
+} MLAN_PACK_END MeasReqCommonFormat_t;
+
+/**        
+ * @brief Basic measurement request structure (7.3.2.21.1)
+ */
+typedef MeasReqCommonFormat_t MeasReqBasic_t;
+
+/**        
+ * @brief CCA measurement request structure (7.3.2.21.2)
+ */
+typedef MeasReqCommonFormat_t MeasReqCCA_t;
+
+/**        
+ * @brief RPI measurement request structure (7.3.2.21.3)
+ */
+typedef MeasReqCommonFormat_t MeasReqRPI_t;
+
+/**        
+ * @brief Union of the availble measurement request types.  Passed in the 
+ *        driver/firmware interface.
+ */
+typedef union
+{
+    MeasReqBasic_t basic; /**< Basic measurement request */
+    MeasReqCCA_t cca;     /**< CCA measurement request */
+    MeasReqRPI_t rpi;     /**< RPI measurement request */
+
+} MeasRequest_t;
+
+/**        
+ * @brief Mode octet of the measurement report element (7.3.2.22)
+ */
+typedef MLAN_PACK_START struct
+{
+#ifdef BIG_ENDIAN
+    t_u8 rsvd3_7:5;        /**< Reserved */
+    t_u8 refused:1;        /**< Measurement refused */
+    t_u8 incapable:1;      /**< Incapable of performing measurement */
+    t_u8 late:1;           /**< Start TSF time missed for measurement */
+#else
+    t_u8 late:1;           /**< Start TSF time missed for measurement */
+    t_u8 incapable:1;      /**< Incapable of performing measurement */
+    t_u8 refused:1;        /**< Measurement refused */
+    t_u8 rsvd3_7:5;        /**< Reserved */
+#endif                          /* BIG_ENDIAN */
+
+} MLAN_PACK_END MeasRptMode_t;
+
+/**        
+ * @brief Basic measurement report (7.3.2.22.1)
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 channel;              /**< Channel to measured */
+    t_u64 start_time;          /**< Start time (TSF) of measurement */
+    t_u16 duration;            /**< Duration of measurement in TUs */
+    MeasRptBasicMap_t map;     /**< Basic measurement report */
+
+} MLAN_PACK_END MeasRptBasic_t;
+
+/**        
+ * @brief CCA measurement report (7.3.2.22.2)
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 channel;                /**< Channel to measured */
+    t_u64 start_time;            /**< Start time (TSF) of measurement */
+    t_u16 duration;              /**< Duration of measurement in TUs  */
+    t_u8 busy_fraction;          /**< Fractional duration CCA indicated chan busy */
+
+} MLAN_PACK_END MeasRptCCA_t;
+
+/**        
+ * @brief RPI measurement report (7.3.2.22.3)
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 channel;              /**< Channel to measured  */
+    t_u64 start_time;          /**< Start time (TSF) of measurement */
+    t_u16 duration;            /**< Duration of measurement in TUs  */
+    t_u8 density[8];           /**< RPI Density histogram report */
+
+} MLAN_PACK_END MeasRptRPI_t;
+
+/**        
+ * @brief Union of the availble measurement report types.  Passed in the 
+ *        driver/firmware interface.
+ */
+typedef union
+{
+    MeasRptBasic_t basic;    /**< Basic measurement report */
+    MeasRptCCA_t cca;        /**< CCA measurement report */
+    MeasRptRPI_t rpi;        /**< RPI measurement report */
+
+} MeasReport_t;
+
+/**        
+ * @brief Structure passed to firmware to perform a measurement
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH];            /**< Reporting STA address */
+    t_u8 dialog_token;                              /**< Measurement dialog toke */
+    MeasReqMode_t req_mode;                         /**< Report mode  */
+    MeasType_t meas_type;                           /**< Measurement type */
+    MeasRequest_t req;                              /**< Measurement request data */
+
+} MLAN_PACK_END HostCmd_DS_MEASUREMENT_REQUEST;
+
+/**        
+ * @brief Structure passed back from firmware with a measurement report,
+ *        also can be to send a measurement report to another STA
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH];            /**< Reporting STA address */
+    t_u8 dialog_token;                              /**< Measurement dialog token */
+    MeasRptMode_t rpt_mode;                         /**< Report mode */
+    MeasType_t meas_type;                           /**< Measurement type */
+    MeasReport_t rpt;                               /**< Measurement report data */
+
+} MLAN_PACK_END HostCmd_DS_MEASUREMENT_REPORT;
+
+/** HostCmd_DS_COMMAND */
+typedef struct MLAN_PACK_START _HostCmd_DS_COMMAND
+{
+    /** Command Header : Command */
+    t_u16 command;
+    /** Command Header : Size */
+    t_u16 size;
+    /** Command Header : Sequence number */
+    t_u16 seq_num;
+    /** Command Header : Result */
+    t_u16 result;
+    /** Command Body */
+    union
+    {
+        /** Hardware specifications */
+        HostCmd_DS_GET_HW_SPEC hw_spec;
+        /** MAC control */
+        HostCmd_DS_MAC_CONTROL mac_ctrl;
+        /** MAC address */
+        HostCmd_DS_802_11_MAC_ADDRESS mac_addr;
+        /** MAC muticast address */
+        HostCmd_DS_MAC_MULTICAST_ADR mc_addr;
+        /** Get log */
+        HostCmd_DS_802_11_GET_LOG get_log;
+        /** RSSI information */
+        HostCmd_DS_802_11_RSSI_INFO rssi_info;
+        /** RSSI information response */
+        HostCmd_DS_802_11_RSSI_INFO_RSP rssi_info_rsp;
+        /** SNMP MIB */
+        HostCmd_DS_802_11_SNMP_MIB smib;
+        /** Radio control */
+        HostCmd_DS_802_11_RADIO_CONTROL radio;
+        /** RF channel */
+        HostCmd_DS_802_11_RF_CHANNEL rf_channel;
+        /** Tx rate query */
+        HostCmd_TX_RATE_QUERY tx_rate;
+        /** Tx rate configuration */
+        HostCmd_DS_TX_RATE_CFG tx_rate_cfg;
+        /** Tx power configuration */
+        HostCmd_DS_TXPWR_CFG txp_cfg;
+        /** RF antenna */
+        HostCmd_DS_802_11_RF_ANTENNA antenna;
+        /** Enhanced power save command */
+        HostCmd_DS_802_11_PS_MODE_ENH psmode_enh;
+        HostCmd_DS_802_11_HS_CFG_ENH opt_hs_cfg;
+        /** Scan */
+        HostCmd_DS_802_11_SCAN scan;
+        /** Scan response */
+        HostCmd_DS_802_11_SCAN_RSP scan_resp;
+
+        HostCmd_DS_802_11_BG_SCAN_QUERY bg_scan_query;
+        HostCmd_DS_802_11_BG_SCAN_QUERY_RSP bg_scan_query_resp;
+
+        /** Associate */
+        HostCmd_DS_802_11_ASSOCIATE associate;
+
+        /** Associate response */
+        HostCmd_DS_802_11_ASSOCIATE_RSP associate_rsp;
+        /** Deauthenticate */
+        HostCmd_DS_802_11_DEAUTHENTICATE deauth;
+        /** Ad-Hoc start */
+        HostCmd_DS_802_11_AD_HOC_START adhoc_start;
+        /** Ad-Hoc result */
+        HostCmd_DS_802_11_AD_HOC_RESULT adhoc_result;
+        /** Ad-Hoc join */
+        HostCmd_DS_802_11_AD_HOC_JOIN adhoc_join;
+        /** Domain information */
+        HostCmd_DS_802_11D_DOMAIN_INFO domain_info;
+        /** Domain information response */
+        HostCmd_DS_802_11D_DOMAIN_INFO_RSP domain_info_resp;
+        HostCmd_DS_802_11_TPC_ADAPT_REQ tpc_req;
+        HostCmd_DS_802_11_TPC_INFO tpc_info;
+        HostCmd_DS_802_11_CHAN_SW_ANN chan_sw_ann;
+        HostCmd_DS_MEASUREMENT_REQUEST meas_req;
+        HostCmd_DS_MEASUREMENT_REPORT meas_rpt;
+        /** Add BA request */
+        HostCmd_DS_11N_ADDBA_REQ add_ba_req;
+        /** Add BA response */
+        HostCmd_DS_11N_ADDBA_RSP add_ba_rsp;
+        /** Delete BA entry */
+        HostCmd_DS_11N_DELBA del_ba;
+        /** Tx buffer configuration */
+        HostCmd_DS_TXBUF_CFG tx_buf;
+        /** AMSDU Aggr Ctrl configuration */
+        HostCmd_DS_AMSDU_AGGR_CTRL amsdu_aggr_ctrl;
+        /** 11n configuration */
+        HostCmd_DS_11N_CFG htcfg;
+        /** WMM status get */
+        HostCmd_DS_WMM_GET_STATUS get_wmm_status;
+        /** WMM ADDTS */
+        HostCmd_DS_WMM_ADDTS_REQ add_ts;
+        /** WMM DELTS */
+        HostCmd_DS_WMM_DELTS_REQ del_ts;
+        /** WMM set/get queue config */
+        HostCmd_DS_WMM_QUEUE_CONFIG queue_config;
+        /** WMM on/of/get queue statistics */
+        HostCmd_DS_WMM_QUEUE_STATS queue_stats;
+        /** WMM get traffic stream status */
+        HostCmd_DS_WMM_TS_STATUS ts_status;
+        /** Key material */
+        HostCmd_DS_802_11_KEY_MATERIAL key_material;
+        /** E-Supplicant PSK */
+        HostCmd_DS_802_11_SUPPLICANT_PMK esupplicant_psk;
+        /** E-Supplicant profile */
+        HostCmd_DS_802_11_SUPPLICANT_PROFILE esupplicant_profile;
+        /** Extended version */
+        HostCmd_DS_VERSION_EXT verext;
+        /** Adhoc Coalescing */
+        HostCmd_DS_802_11_IBSS_STATUS ibss_coalescing;
+        /** LDO configuration */
+        HostCmd_DS_802_11_LDO_CFG ldo_cfg;
+        /** System clock configuration */
+        HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG sys_clock_cfg;
+        /** MAC register access */
+        HostCmd_DS_MAC_REG_ACCESS mac_reg;
+        /** BBP register access */
+        HostCmd_DS_BBP_REG_ACCESS bbp_reg;
+        /** RF register access */
+        HostCmd_DS_RF_REG_ACCESS rf_reg;
+        /** PMIC register access */
+        HostCmd_DS_PMIC_REG_ACCESS pmic_reg;
+        /** EEPROM register access */
+        HostCmd_DS_802_11_EEPROM_ACCESS eeprom;
+        /** Memory access */
+        HostCmd_DS_MEM_ACCESS mem;
+
+        /** Inactivity timeout extend */
+        HostCmd_DS_INACTIVITY_TIMEOUT_EXT inactivity_to;
+        /** BCA Timeshare */
+        HostCmd_DS_802_11_BCA_TIMESHARE bca_timeshare;
+
+       /** Sleep period command */
+        HostCmd_DS_802_11_SLEEP_PERIOD sleep_pd;
+       /** Sleep params command */
+        HostCmd_DS_802_11_SLEEP_PARAMS sleep_param;
+
+    } params;
+} MLAN_PACK_END HostCmd_DS_COMMAND;
+
+typedef struct MLAN_PACK_START _opt_sleep_confirm_buffer
+{
+    /** Header for interface */
+    t_u8 hdr[4];
+    /** New power save command used to send sleep confirmation to the firmware */
+    HostCmd_DS_COMMAND ps_cfm_sleep;
+} MLAN_PACK_END opt_sleep_confirm_buffer;
+
+#ifdef PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+#endif /* !_MLAN_FW_H_ */
diff --git a/wlan_src/mlan/mlan_ieee.h b/wlan_src/mlan/mlan_ieee.h
new file mode 100755
index 0000000..139c6ab
--- /dev/null
+++ b/wlan_src/mlan/mlan_ieee.h
@@ -0,0 +1,832 @@
+/** @file mlan_ieee.h
+ *
+ *  @brief This file contains IEEE information element related 
+ *  definitions used in MLAN and MOAL module.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    11/03/2008: initial version
+******************************************************/
+
+#ifndef _MLAN_IEEE_H_
+#define _MLAN_IEEE_H_
+
+/** WLAN supported rates */
+#define WLAN_SUPPORTED_RATES            	14
+
+/** WLAN supported rates extension*/
+#define WLAN_SUPPORTED_RATES_EXT            32
+
+/** Enumeration definition*/
+/** WLAN_802_11_NETWORK_TYPE */
+typedef enum _WLAN_802_11_NETWORK_TYPE
+{
+    Wlan802_11FH,
+    Wlan802_11DS,
+    /* Defined as upper bound */
+    Wlan802_11NetworkTypeMax
+} WLAN_802_11_NETWORK_TYPE;
+
+/** Maximum size of IEEE Information Elements */
+#define IEEE_MAX_IE_SIZE      256
+
+#ifdef PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+
+/** IEEE Type definitions  */
+typedef MLAN_PACK_START enum _IEEEtypes_ElementId_e
+{
+    SSID = 0,
+    SUPPORTED_RATES = 1,
+    FH_PARAM_SET = 2,
+    DS_PARAM_SET = 3,
+    CF_PARAM_SET = 4,
+
+    IBSS_PARAM_SET = 6,
+
+    COUNTRY_INFO = 7,
+
+    POWER_CONSTRAINT = 32,
+    POWER_CAPABILITY = 33,
+    TPC_REQUEST = 34,
+    TPC_REPORT = 35,
+    SUPPORTED_CHANNELS = 36,
+    CHANNEL_SWITCH_ANN = 37,
+    QUIET = 40,
+    IBSS_DFS = 41,
+    HT_CAPABILITY = 45,
+    HT_OPERATION = 61,
+    BSSCO_2040 = 72,
+    OVERLAPBSSSCANPARAM = 74,
+    EXT_CAPABILITY = 127,
+
+    ERP_INFO = 42,
+
+    EXTENDED_SUPPORTED_RATES = 50,
+
+    VENDOR_SPECIFIC_221 = 221,
+    WMM_IE = VENDOR_SPECIFIC_221,
+
+    WPS_IE = VENDOR_SPECIFIC_221,
+
+    WPA_IE = VENDOR_SPECIFIC_221,
+    RSN_IE = 48,
+    VS_IE = VENDOR_SPECIFIC_221,
+    WAPI_IE = 68,
+} MLAN_PACK_END IEEEtypes_ElementId_e;
+
+/** IEEE IE header */
+typedef MLAN_PACK_START struct _IEEEtypes_Header_t
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 len;
+} MLAN_PACK_END IEEEtypes_Header_t, *pIEEEtypes_Header_t;
+
+/** Vendor specific IE header */
+typedef MLAN_PACK_START struct _IEEEtypes_VendorHeader_t
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 len;
+    /** OUI */
+    t_u8 oui[3];
+    /** OUI type */
+    t_u8 oui_type;
+    /** OUI subtype */
+    t_u8 oui_subtype;
+    /** Version */
+    t_u8 version;
+} MLAN_PACK_END IEEEtypes_VendorHeader_t, *pIEEEtypes_VendorHeader_t;
+
+/** Vendor specific IE */
+typedef MLAN_PACK_START struct _IEEEtypes_VendorSpecific_t
+{
+    /** Vendor specific IE header */
+    IEEEtypes_VendorHeader_t vend_hdr;
+    /** IE Max - size of previous fields */
+    t_u8 data[IEEE_MAX_IE_SIZE - sizeof(IEEEtypes_VendorHeader_t)];
+}
+MLAN_PACK_END IEEEtypes_VendorSpecific_t, *pIEEEtypes_VendorSpecific_t;
+
+/** IEEE IE */
+typedef MLAN_PACK_START struct _IEEEtypes_Generic_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** IE Max - size of previous fields */
+    t_u8 data[IEEE_MAX_IE_SIZE - sizeof(IEEEtypes_Header_t)];
+}
+MLAN_PACK_END IEEEtypes_Generic_t, *pIEEEtypes_Generic_t;
+
+/** Capability information mask */
+#define CAPINFO_MASK    (~(MBIT(15) | MBIT(14) |            \
+                           MBIT(12) | MBIT(11) | MBIT(9)))
+
+/** Capability Bit Map*/
+#ifdef BIG_ENDIAN
+typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t
+{
+    t_u8 rsrvd1:2;
+    t_u8 dsss_ofdm:1;
+    t_u8 rsvrd2:2;
+    t_u8 short_slot_time:1;
+    t_u8 rsrvd3:1;
+    t_u8 spectrum_mgmt:1;
+    t_u8 chan_agility:1;
+    t_u8 pbcc:1;
+    t_u8 short_preamble:1;
+    t_u8 privacy:1;
+    t_u8 cf_poll_rqst:1;
+    t_u8 cf_pollable:1;
+    t_u8 ibss:1;
+    t_u8 ess:1;
+} MLAN_PACK_END IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t;
+#else
+typedef MLAN_PACK_START struct _IEEEtypes_CapInfo_t
+{
+    /** Capability Bit Map : ESS */
+    t_u8 ess:1;
+    /** Capability Bit Map : IBSS */
+    t_u8 ibss:1;
+    /** Capability Bit Map : CF pollable */
+    t_u8 cf_pollable:1;
+    /** Capability Bit Map : CF poll request */
+    t_u8 cf_poll_rqst:1;
+    /** Capability Bit Map : privacy */
+    t_u8 privacy:1;
+    /** Capability Bit Map : Short preamble */
+    t_u8 short_preamble:1;
+    /** Capability Bit Map : PBCC */
+    t_u8 pbcc:1;
+    /** Capability Bit Map : Channel agility */
+    t_u8 chan_agility:1;
+    /** Capability Bit Map : Spectrum management */
+    t_u8 spectrum_mgmt:1;
+    /** Capability Bit Map : Reserved */
+    t_u8 rsrvd3:1;
+    /** Capability Bit Map : Short slot time */
+    t_u8 short_slot_time:1;
+    /** Capability Bit Map : APSD */
+    t_u8 Apsd:1;
+    /** Capability Bit Map : Reserved */
+    t_u8 rsvrd2:1;
+    /** Capability Bit Map : DSS OFDM */
+    t_u8 dsss_ofdm:1;
+    /** Capability Bit Map : Reserved */
+    t_u8 rsrvd1:2;
+} MLAN_PACK_END IEEEtypes_CapInfo_t, *pIEEEtypes_CapInfo_t;
+#endif /* BIG_ENDIAN */
+
+/** IEEEtypes_CfParamSet_t */
+typedef MLAN_PACK_START struct _IEEEtypes_CfParamSet_t
+{
+    /** CF peremeter : Element ID */
+    t_u8 element_id;
+    /** CF peremeter : Length */
+    t_u8 len;
+    /** CF peremeter : Count */
+    t_u8 cfp_cnt;
+    /** CF peremeter : Period */
+    t_u8 cfp_period;
+    /** CF peremeter : Maximum duration */
+    t_u16 cfp_max_duration;
+    /** CF peremeter : Remaining duration */
+    t_u16 cfp_duration_remaining;
+} MLAN_PACK_END IEEEtypes_CfParamSet_t, *pIEEEtypes_CfParamSet_t;
+
+/** IEEEtypes_IbssParamSet_t */
+typedef MLAN_PACK_START struct _IEEEtypes_IbssParamSet_t
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 len;
+    /** ATIM window value */
+    t_u16 atim_window;
+} MLAN_PACK_END IEEEtypes_IbssParamSet_t, *pIEEEtypes_IbssParamSet_t;
+
+/** IEEEtypes_SsParamSet_t */
+typedef MLAN_PACK_START union _IEEEtypes_SsParamSet_t
+{
+    /** SS parameter : CF parameter set */
+    IEEEtypes_CfParamSet_t cf_param_set;
+    /** SS parameter : IBSS parameter set */
+    IEEEtypes_IbssParamSet_t ibss_param_set;
+} MLAN_PACK_END IEEEtypes_SsParamSet_t, *pIEEEtypes_SsParamSet_t;
+
+/** IEEEtypes_FhParamSet_t */
+typedef MLAN_PACK_START struct _IEEEtypes_FhParamSet_t
+{
+    /** FH parameter : Element ID */
+    t_u8 element_id;
+    /** FH parameter : Length */
+    t_u8 len;
+    /** FH parameter : Dwell time */
+    t_u16 dwell_time;
+    /** FH parameter : Hop set */
+    t_u8 hop_set;
+    /** FH parameter : Hop pattern */
+    t_u8 hop_pattern;
+    /** FH parameter : Hop index */
+    t_u8 hop_index;
+} MLAN_PACK_END IEEEtypes_FhParamSet_t, *pIEEEtypes_FhParamSet_t;
+
+/** IEEEtypes_DsParamSet_t */
+typedef MLAN_PACK_START struct _IEEEtypes_DsParamSet_t
+{
+    /** DS parameter : Element ID */
+    t_u8 element_id;
+    /** DS parameter : Length */
+    t_u8 len;
+    /** DS parameter : Current channel */
+    t_u8 current_chan;
+} MLAN_PACK_END IEEEtypes_DsParamSet_t, *pIEEEtypes_DsParamSet_t;
+
+/** IEEEtypes_PhyParamSet_t */
+typedef MLAN_PACK_START union _IEEEtypes_PhyParamSet_t
+{
+    /** FH parameter set */
+    IEEEtypes_FhParamSet_t fh_param_set;
+    /** DS parameter set */
+    IEEEtypes_DsParamSet_t ds_param_set;
+} MLAN_PACK_END IEEEtypes_PhyParamSet_t, *pIEEEtypes_PhyParamSet_t;
+
+/** IEEEtypes_ERPInfo_t */
+typedef MLAN_PACK_START struct _IEEEtypes_ERPInfo_t
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 len;
+    /** ERP flags */
+    t_u8 erp_flags;
+} MLAN_PACK_END IEEEtypes_ERPInfo_t, *pIEEEtypes_ERPInfo_t;
+
+/** IEEEtypes_AId_t */
+typedef t_u16 IEEEtypes_AId_t;
+
+/** IEEEtypes_StatusCode_t */
+typedef t_u16 IEEEtypes_StatusCode_t;
+
+/** IEEEtypes_AssocRsp_t */
+typedef MLAN_PACK_START struct _IEEEtypes_AssocRsp_t
+{
+    /** Capability information */
+    IEEEtypes_CapInfo_t capability;
+    /** Association response status code */
+    IEEEtypes_StatusCode_t status_code;
+    /** Association ID */
+    IEEEtypes_AId_t a_id;
+    /** IE data buffer */
+    t_u8 ie_buffer[1];
+} MLAN_PACK_END IEEEtypes_AssocRsp_t, *pIEEEtypes_AssocRsp_t;
+
+/** 802.11 supported rates */
+typedef t_u8 WLAN_802_11_RATES[WLAN_SUPPORTED_RATES];
+
+/** Maximum number of AC QOS queues available in the driver/firmware */
+#define MAX_AC_QUEUES 4
+
+/** Data structure of WMM QoS information */
+typedef MLAN_PACK_START struct _IEEEtypes_WmmQosInfo_t
+{
+#ifdef BIG_ENDIAN
+    /** QoS UAPSD */
+    t_u8 qos_uapsd:1;
+    /** Reserved */
+    t_u8 reserved:3;
+    /** Parameter set count */
+    t_u8 para_set_count:4;
+#else
+    /** Parameter set count */
+    t_u8 para_set_count:4;
+    /** Reserved */
+    t_u8 reserved:3;
+    /** QoS UAPSD */
+    t_u8 qos_uapsd:1;
+#endif                          /* BIG_ENDIAN */
+} MLAN_PACK_END IEEEtypes_WmmQosInfo_t, *pIEEEtypes_WmmQosInfo_t;
+
+/** Data structure of WMM Aci/Aifsn */
+typedef MLAN_PACK_START struct _IEEEtypes_WmmAciAifsn_t
+{
+#ifdef BIG_ENDIAN
+    /** Reserved */
+    t_u8 reserved:1;
+    /** Aci */
+    t_u8 aci:2;
+    /** Acm */
+    t_u8 acm:1;
+    /** Aifsn */
+    t_u8 aifsn:4;
+#else
+    /** Aifsn */
+    t_u8 aifsn:4;
+    /** Acm */
+    t_u8 acm:1;
+    /** Aci */
+    t_u8 aci:2;
+    /** Reserved */
+    t_u8 reserved:1;
+#endif                          /* BIG_ENDIAN */
+} MLAN_PACK_END IEEEtypes_WmmAciAifsn_t, *pIEEEtypes_WmmAciAifsn_t;
+
+/** Data structure of WMM ECW */
+typedef MLAN_PACK_START struct _IEEEtypes_WmmEcw_t
+{
+#ifdef BIG_ENDIAN
+    /** Maximum Ecw */
+    t_u8 ecw_max:4;
+    /** Minimum Ecw */
+    t_u8 ecw_min:4;
+#else
+    /** Minimum Ecw */
+    t_u8 ecw_min:4;
+    /** Maximum Ecw */
+    t_u8 ecw_max:4;
+#endif                          /* BIG_ENDIAN */
+} MLAN_PACK_END IEEEtypes_WmmEcw_t, *pIEEEtypes_WmmEcw_t;
+
+/** Data structure of WMM AC parameters  */
+typedef MLAN_PACK_START struct _IEEEtypes_WmmAcParameters_t
+{
+    IEEEtypes_WmmAciAifsn_t aci_aifsn;       /**< AciAifSn */
+    IEEEtypes_WmmEcw_t ecw;                 /**< Ecw */
+    t_u16 tx_op_limit;                        /**< Tx op limit */
+} MLAN_PACK_END IEEEtypes_WmmAcParameters_t, *pIEEEtypes_WmmAcParameters_t;
+
+/** Data structure of WMM Info IE  */
+typedef MLAN_PACK_START struct _IEEEtypes_WmmInfo_t
+{
+
+    /**
+     * WMM Info IE - Vendor Specific Header:
+     *   element_id  [221/0xdd]
+     *   Len         [7] 
+     *   Oui         [00:50:f2]
+     *   OuiType     [2]
+     *   OuiSubType  [0]
+     *   Version     [1]
+     */
+    IEEEtypes_VendorHeader_t vend_hdr;
+
+    /** QoS information */
+    IEEEtypes_WmmQosInfo_t qos_info;
+
+} MLAN_PACK_END IEEEtypes_WmmInfo_t, *pIEEEtypes_WmmInfo_t;
+
+/** Data structure of WMM parameter IE  */
+typedef MLAN_PACK_START struct _IEEEtypes_WmmParameter_t
+{
+    /**
+     * WMM Parameter IE - Vendor Specific Header:
+     *   element_id  [221/0xdd]
+     *   Len         [24] 
+     *   Oui         [00:50:f2]
+     *   OuiType     [2]
+     *   OuiSubType  [1]
+     *   Version     [1]
+     */
+    IEEEtypes_VendorHeader_t vend_hdr;
+
+    /** QoS information */
+    IEEEtypes_WmmQosInfo_t qos_info;
+    /** Reserved */
+    t_u8 reserved;
+
+    /** AC Parameters Record WMM_AC_BE, WMM_AC_BK, WMM_AC_VI, WMM_AC_VO */
+    IEEEtypes_WmmAcParameters_t ac_params[MAX_AC_QUEUES];
+} MLAN_PACK_END IEEEtypes_WmmParameter_t, *pIEEEtypes_WmmParameter_t;
+
+/** Maximum subbands for 11d */
+#define MRVDRV_MAX_SUBBAND_802_11D              83
+/** Country code length */
+#define COUNTRY_CODE_LEN                        3
+
+/** Data structure for subband set */
+typedef MLAN_PACK_START struct _IEEEtypes_SubbandSet_t
+{
+    /** First channel */
+    t_u8 first_chan;
+    /** Number of channels */
+    t_u8 no_of_chan;
+    /** Maximum Tx power */
+    t_u8 max_tx_pwr;
+} MLAN_PACK_END IEEEtypes_SubbandSet_t, *pIEEEtypes_SubbandSet_t;
+
+/** Data structure for Country IE */
+typedef MLAN_PACK_START struct _IEEEtypes_CountryInfoSet_t
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 len;
+    /** Country code */
+    t_u8 country_code[COUNTRY_CODE_LEN];
+    /** Set of subbands */
+    IEEEtypes_SubbandSet_t sub_band[1];
+} MLAN_PACK_END IEEEtypes_CountryInfoSet_t, *pIEEEtypes_CountryInfoSet_t;
+
+/** Data structure for Country IE full set */
+typedef MLAN_PACK_START struct _IEEEtypes_CountryInfoFullSet_t
+{
+    /** Element ID */
+    t_u8 element_id;
+    /** Length */
+    t_u8 len;
+    /** Country code */
+    t_u8 country_code[COUNTRY_CODE_LEN];
+    /** Set of subbands */
+    IEEEtypes_SubbandSet_t sub_band[MRVDRV_MAX_SUBBAND_802_11D];
+} MLAN_PACK_END IEEEtypes_CountryInfoFullSet_t,
+    *pIEEEtypes_CountryInfoFullSet_t;
+
+/** HT Capabilities Data */
+typedef struct MLAN_PACK_START _HTCap_t
+{
+    /** HT Capabilities Info field */
+    t_u16 ht_cap_info;
+    /** A-MPDU Parameters field */
+    t_u8 ampdu_param;
+    /** Supported MCS Set field */
+    t_u8 supported_mcs_set[16];
+    /** HT Extended Capabilities field */
+    t_u16 ht_ext_cap;
+    /** Transmit Beamforming Capabilities field */
+    t_u32 tx_bf_cap;
+    /** Antenna Selection Capability field */
+    t_u8 asel;
+} MLAN_PACK_END HTCap_t, *pHTCap_t;
+
+/** HT Information Data */
+typedef struct MLAN_PACK_START _HTInfo_t
+{
+    /** Primary channel */
+    t_u8 pri_chan;
+    /** Field 2 */
+    t_u8 field2;
+    /** Field 3 */
+    t_u16 field3;
+    /** Field 4 */
+    t_u16 field4;
+    /** Bitmap indicating MCSs supported by all HT STAs in the BSS */
+    t_u8 basic_mcs_set[16];
+} MLAN_PACK_END HTInfo_t, *pHTInfo_t;
+
+/** 20/40 BSS Coexistence Data */
+typedef struct MLAN_PACK_START _BSSCo2040_t
+{
+    /** 20/40 BSS Coexistence value */
+    t_u8 bss_co_2040_value;
+} MLAN_PACK_END BSSCo2040_t, *pBSSCo2040_t;
+
+/** Extended Capabilities Data */
+typedef struct MLAN_PACK_START _ExtCap_t
+{
+    /** Extended Capabilities value */
+    t_u8 ext_cap_value;
+} MLAN_PACK_END ExtCap_t, *pExtCap_t;
+
+/** Overlapping BSS Scan Parameters Data */
+typedef struct MLAN_PACK_START _OverlapBSSScanParam_t
+{
+    /** OBSS Scan Passive Dwell */
+    t_u16 obss_scan_passive_dwell;
+    /** OBSS Scan Active Dwell */
+    t_u16 obss_scan_active_dwell;
+    /** BSS Channel Width Trigger Scan Interval */
+    t_u16 bss_chan_width_trigger_scan_int;
+    /** OBSS Scan Passive Total Per Channel */
+    t_u16 obss_scan_passive_total;
+    /** OBSS Scan Active Total Per Channel */
+    t_u16 obss_scan_active_total;
+    /** BSS Width Channel Transition Delay Factor */
+    t_u16 bss_width_chan_trans_delay;
+    /** OBSS Scan Activity Threshold */
+    t_u16 obss_scan_active_threshold;
+} MLAN_PACK_END OBSSScanParam_t, *pOBSSScanParam_t;
+
+/** HT Capabilities IE */
+typedef MLAN_PACK_START struct _IEEEtypes_HTCap_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** HTCap struct */
+    HTCap_t ht_cap;
+} MLAN_PACK_END IEEEtypes_HTCap_t, *pIEEEtypes_HTCap_t;
+
+/** HT Information IE */
+typedef MLAN_PACK_START struct _IEEEtypes_HTInfo_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** HTInfo struct */
+    HTInfo_t ht_info;
+} MLAN_PACK_END IEEEtypes_HTInfo_t, *pIEEEtypes_HTInfo_t;
+
+/** 20/40 BSS Coexistence IE */
+typedef MLAN_PACK_START struct _IEEEtypes_2040BSSCo_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** BSSCo2040_t struct */
+    BSSCo2040_t bss_co_2040;
+} MLAN_PACK_END IEEEtypes_2040BSSCo_t, *pIEEEtypes_2040BSSCo_t;
+
+/** Extended Capabilities IE */
+typedef MLAN_PACK_START struct _IEEEtypes_ExtCap_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** ExtCap_t struct */
+    ExtCap_t ext_cap;
+} MLAN_PACK_END IEEEtypes_ExtCap_t, *pIEEEtypes_ExtCap_t;
+
+/** Overlapping BSS Scan Parameters IE */
+typedef MLAN_PACK_START struct _IEEEtypes_OverlapBSSScanParam_t
+{
+    /** Generic IE header */
+    IEEEtypes_Header_t ieee_hdr;
+    /** OBSSScanParam_t struct */
+    OBSSScanParam_t obss_scan_param;
+} MLAN_PACK_END IEEEtypes_OverlapBSSScanParam_t,
+    *pIEEEtypes_OverlapBSSScanParam_t;
+
+/** Maximum number of subbands in the IEEEtypes_SupportedChannels_t structure */
+#define WLAN_11H_MAX_SUBBANDS  5
+
+/** Maximum number of DFS channels configured in IEEEtypes_IBSS_DFS_t */
+#define WLAN_11H_MAX_IBSS_DFS_CHANNELS 25
+
+/**  IEEE Power Constraint element (7.3.2.15) */
+typedef MLAN_PACK_START struct
+{
+    t_u8 element_id;        /**< IEEE Element ID = 32 */
+    t_u8 len;               /**< Element length after id and len */
+    t_u8 local_constraint;  /**< Local power constraint applied to 11d chan info */
+} MLAN_PACK_END IEEEtypes_PowerConstraint_t;
+
+/**  IEEE Power Capability element (7.3.2.16) */
+typedef MLAN_PACK_START struct
+{
+    t_u8 element_id;                /**< IEEE Element ID = 33 */
+    t_u8 len;                       /**< Element length after id and len */
+    t_s8 min_tx_power_capability;   /**< Minimum Transmit power (dBm) */
+    t_s8 max_tx_power_capability;   /**< Maximum Transmit power (dBm) */
+} MLAN_PACK_END IEEEtypes_PowerCapability_t;
+
+/**  IEEE TPC Report element (7.3.2.18) */
+typedef MLAN_PACK_START struct
+{
+    t_u8 element_id;    /**< IEEE Element ID = 35 */
+    t_u8 len;           /**< Element length after id and len */
+    t_s8 tx_power;      /**< Max power used to transmit the TPC Report frame (dBm) */
+    t_s8 link_margin;   /**< Link margin when TPC Request received (dB) */
+} MLAN_PACK_END IEEEtypes_TPCReport_t;
+
+/*  IEEE Supported Channel sub-band description (7.3.2.19) */
+/**  
+ *  Sub-band description used in the supported channels element. 
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 start_chan;    /**< Starting channel in the subband */
+    t_u8 num_chans;     /**< Number of channels in the subband */
+
+} MLAN_PACK_END IEEEtypes_SupportChan_Subband_t;
+
+/*  IEEE Supported Channel element (7.3.2.19) */
+/**
+ *  Sent in association requests. Details the sub-bands and number
+ *    of channels supported in each subband
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 element_id;    /**< IEEE Element ID = 36 */
+    t_u8 len;           /**< Element length after id and len */
+
+    /** Configured sub-bands information in the element */
+    IEEEtypes_SupportChan_Subband_t subband[WLAN_11H_MAX_SUBBANDS];
+
+} MLAN_PACK_END IEEEtypes_SupportedChannels_t;
+
+/*  IEEE Quiet Period Element (7.3.2.23) */
+/**
+ *  Provided in beacons and probe responses.  Indicates times during 
+ *    which the STA should not be transmitting data.  Only starting STAs in
+ *    an IBSS and APs are allowed to originate a quiet element. 
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 element_id;        /**< IEEE Element ID = 40 */
+    t_u8 len;               /**< Element length after id and len */
+    t_u8 quiet_count;       /**< Number of TBTTs until beacon with the quiet period */
+    t_u8 quiet_period;      /**< Regular quiet period, # of TBTTS between periods */
+    t_u16 quiet_duration;   /**< Duration of the quiet period in TUs */
+    t_u16 quiet_offset;     /**< Offset in TUs from the TBTT for the quiet period */
+
+} MLAN_PACK_END IEEEtypes_Quiet_t;
+
+/**
+***  @brief Map octet of the basic measurement report (7.3.2.22.1)
+**/
+typedef MLAN_PACK_START struct
+{
+#ifdef BIG_ENDIAN
+    t_u8 rsvd5_7:3;                /**< Reserved */
+    t_u8 unmeasured:1;             /**< Channel is unmeasured */
+    t_u8 radar:1;                  /**< Radar detected on channel */
+    t_u8 unidentified_sig:1;       /**< Unidentified signal found on channel */
+    t_u8 ofdm_preamble:1;          /**< OFDM preamble detected on channel */
+    t_u8 bss:1;                    /**< At least one valid MPDU received on channel */
+#else
+    t_u8 bss:1;                    /**< At least one valid MPDU received on channel */
+    t_u8 ofdm_preamble:1;          /**< OFDM preamble detected on channel */
+    t_u8 unidentified_sig:1;       /**< Unidentified signal found on channel */
+    t_u8 radar:1;                  /**< Radar detected on channel */
+    t_u8 unmeasured:1;             /**< Channel is unmeasured */
+    t_u8 rsvd5_7:3;                /**< Reserved */
+#endif                          /* BIG_ENDIAN */
+
+} MLAN_PACK_END MeasRptBasicMap_t;
+
+/*  IEEE DFS Channel Map field (7.3.2.24) */
+/**
+ *  Used to list supported channels and provide a octet "map" field which 
+ *    contains a basic measurement report for that channel in the 
+ *    IEEEtypes_IBSS_DFS_t element
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 channel_number;        /**< Channel number */
+    MeasRptBasicMap_t rpt_map;  /**< Basic measurement report for the channel */
+
+} MLAN_PACK_END IEEEtypes_ChannelMap_t;
+
+/*  IEEE IBSS DFS Element (7.3.2.24) */
+/**
+ *  IBSS DFS element included in ad hoc beacons and probe responses.  
+ *    Provides information regarding the IBSS DFS Owner as well as the
+ *    originating STAs supported channels and basic measurement results.
+ */
+typedef MLAN_PACK_START struct
+{
+    t_u8 element_id;                        /**< IEEE Element ID = 41 */
+    t_u8 len;                               /**< Element length after id and len */
+    t_u8 dfs_owner[MLAN_MAC_ADDR_LENGTH];   /**< DFS Owner STA Address */
+    t_u8 dfs_recovery_interval;             /**< DFS Recovery time in TBTTs */
+
+    /** Variable length map field, one Map entry for each supported channel */
+    IEEEtypes_ChannelMap_t channel_map[WLAN_11H_MAX_IBSS_DFS_CHANNELS];
+
+} MLAN_PACK_END IEEEtypes_IBSS_DFS_t;
+
+/* 802.11h BSS information kept for each BSSID received in scan results */
+/**
+ * IEEE BSS information needed from scan results for later processing in
+ *    join commands 
+ */
+typedef struct
+{
+    t_u8 sensed_11h;  /**< Capability bit set or 11h IE found in this BSS */
+
+    IEEEtypes_PowerConstraint_t power_constraint; /**< Power Constraint IE */
+    IEEEtypes_PowerCapability_t power_capability; /**< Power Capability IE */
+    IEEEtypes_TPCReport_t tpc_report;             /**< TPC Report IE */
+    IEEEtypes_Quiet_t quiet;                      /**< Quiet IE */
+    IEEEtypes_IBSS_DFS_t ibss_dfs;                /**< IBSS DFS Element IE */
+
+} wlan_11h_bss_info_t;
+
+#ifdef PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+/** BSSDescriptor_t
+ *    Structure used to store information for beacon/probe response
+ */
+typedef struct _BSSDescriptor_t
+{
+    /** MAC address */
+    mlan_802_11_mac_addr mac_address;
+
+    /** SSID */
+    mlan_802_11_ssid ssid;
+
+    /** WEP encryption requirement */
+    t_u32 privacy;
+
+    /** Receive signal strength in dBm */
+    t_s32 rssi;
+
+    /** Channel */
+    t_u32 channel;
+
+    /** Freq */
+    t_u32 freq;
+
+    /** Beacon period */
+    t_u16 beacon_period;
+
+    /** ATIM window */
+    t_u32 atim_window;
+
+    /** ERP flags */
+    t_u8 erp_flags;
+
+    /** Type of network in use */
+    WLAN_802_11_NETWORK_TYPE network_type_use;
+
+    /** Network infrastructure mode */
+    t_u32 bss_mode;
+
+    /** Network supported rates */
+    WLAN_802_11_RATES supported_rates;
+
+    /** Supported data rates */
+    t_u8 data_rates[WLAN_SUPPORTED_RATES];
+
+    /** Network band.
+     * BAND_B(0x01): 'b' band
+     * BAND_G(0x02): 'g' band
+     * BAND_A(0X04): 'a' band
+     */
+    t_u16 bss_band;
+
+    /** TSF timestamp from the current firmware TSF */
+    t_u64 network_tsf;
+
+    /** TSF value included in the beacon/probe response */
+    t_u8 time_stamp[8];
+
+    /** PHY parameter set */
+    IEEEtypes_PhyParamSet_t phy_param_set;
+
+    /** SS parameter set */
+    IEEEtypes_SsParamSet_t ss_param_set;
+
+    /** Capability information */
+    IEEEtypes_CapInfo_t cap_info;
+
+    /** WMM IE */
+    IEEEtypes_WmmParameter_t wmm_ie;
+
+    /** 802.11h BSS information */
+    wlan_11h_bss_info_t wlan_11h_bss_info;
+
+    /** 802.11n BSS information */
+    /** HT Capabilities IE */
+    IEEEtypes_HTCap_t *pht_cap;
+    /** HT Capabilities Offset */
+    t_u16 ht_cap_offset;
+    /** HT Information IE */
+    IEEEtypes_HTInfo_t *pht_info;
+    /** HT Information Offset */
+    t_u16 ht_info_offset;
+    /** 20/40 BSS Coexistence IE */
+    IEEEtypes_2040BSSCo_t *pbss_co_2040;
+    /** 20/40 BSS Coexistence Offset */
+    t_u16 bss_co_2040_offset;
+    /** Extended Capabilities IE */
+    IEEEtypes_ExtCap_t *pext_cap;
+    /** Extended Capabilities Offset */
+    t_u16 ext_cap_offset;
+    /** Overlapping BSS Scan Parameters IE */
+    IEEEtypes_OverlapBSSScanParam_t *poverlap_bss_scan_param;
+    /** Overlapping BSS Scan Parameters Offset */
+    t_u16 overlap_bss_offset;
+
+    /** Country information set */
+    IEEEtypes_CountryInfoFullSet_t country_info;
+
+    /** WPA IE */
+    IEEEtypes_VendorSpecific_t *pwpa_ie;
+    /** WPA IE offset in the beacon buffer */
+    t_u16 wpa_offset;
+    /** RSN IE */
+    IEEEtypes_Generic_t *prsn_ie;
+    /** RSN IE offset in the beacon buffer */
+    t_u16 rsn_offset;
+    /** WAPI IE */
+    IEEEtypes_Generic_t *pwapi_ie;
+    /** WAPI IE offset in the beacon buffer */
+    t_u16 wapi_offset;
+
+    /** Pointer to the returned scan response */
+    t_u8 *pbeacon_buf;
+    /** Length of the stored scan response */
+    t_u32 beacon_buf_size;
+    /** Max allocated size for updated scan response */
+    t_u32 beacon_buf_size_max;
+
+} BSSDescriptor_t, *pBSSDescriptor_t;
+
+#endif /* !_MLAN_IEEE_H_ */
diff --git a/wlan_src/mlan/mlan_init.c b/wlan_src/mlan/mlan_init.c
new file mode 100755
index 0000000..4f2bafc
--- /dev/null
+++ b/wlan_src/mlan/mlan_init.c
@@ -0,0 +1,654 @@
+/** @file mlan_init.c
+ *  
+ *  @brief This file contains the initialization for FW
+ *  and HW. 
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    10/13/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_init.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_11h.h"
+#include "mlan_meas.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+        Global Variables
+********************************************************/
+
+/********************************************************
+        Local Functions
+********************************************************/
+
+/**
+ *  @brief This function adds a BSS priority table
+ *  
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param bss_num  	BSS number
+ *
+ *  @return		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_add_bsspriotbl(pmlan_adapter pmadapter, t_u8 bss_num)
+{
+    pmlan_private priv = pmadapter->priv[bss_num];
+    mlan_bssprio_node *pbssprio;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    if ((status = pmadapter->callbacks.moal_malloc(sizeof(mlan_bssprio_node),
+                                                   (t_u8 **) & pbssprio))) {
+        PRINTM(MERROR, "Allocation failed for add_bsspriotbl\n");
+        return status;
+    }
+
+    pbssprio->priv = priv;
+
+    util_init_list((pmlan_linked_list) pbssprio);
+
+    if (!pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur)
+        pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur = pbssprio;
+
+    util_enqueue_list_tail(&pmadapter->bssprio_tbl[priv->bss_priority].
+                           bssprio_head, (pmlan_linked_list) pbssprio,
+                           pmadapter->callbacks.moal_spin_lock,
+                           pmadapter->callbacks.moal_spin_unlock);
+
+    LEAVE();
+    return status;
+}
+
+/**
+ *  @brief This function initializes the private structure
+ *  		and sets default values to the members of mlan_private.
+ *  
+ *  @param priv    A pointer to mlan_private structure
+ *
+ *  @return        N/A
+ */
+t_void
+wlan_init_priv(pmlan_private priv)
+{
+    t_u32 i;
+    pmlan_adapter pmadapter = priv->adapter;
+
+    ENTER();
+
+    priv->media_connected = MFALSE;
+    memset(priv->curr_addr, 0xff, MLAN_MAC_ADDR_LENGTH);
+
+    priv->pkt_tx_ctrl = 0;
+    priv->bss_mode = MLAN_BSS_MODE_INFRA;
+    priv->data_rate = 0;        /* Initially indicate the rate as auto */
+    priv->is_data_rate_auto = MTRUE;
+    priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
+    priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
+
+    priv->sec_info.wep_status = Wlan802_11WEPDisabled;
+    priv->sec_info.authentication_mode = MLAN_AUTH_MODE_OPEN;
+    priv->sec_info.encryption_mode = MLAN_ENCRYPTION_MODE_NONE;
+    for (i = 0; i < sizeof(priv->wep_key) / sizeof(priv->wep_key[0]); i++)
+        memset(&priv->wep_key[i], 0, sizeof(mrvl_wep_key_t));
+    priv->wep_key_curr_index = 0;
+    priv->adhoc_aes_enabled = MFALSE;
+    priv->curr_pkt_filter =
+        HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
+        HostCmd_ACT_MAC_ETHERNETII_ENABLE;
+
+    priv->beacon_period = MLAN_BEACON_INTERVAL;
+    priv->pattempted_bss_desc = MNULL;
+    memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params));
+    priv->listen_interval = MLAN_DEFAULT_LISTEN_INTERVAL;
+
+    memset(&priv->prev_ssid, 0, sizeof(priv->prev_ssid));
+    memset(&priv->prev_bssid, 0, sizeof(priv->prev_bssid));
+    memset(&priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf));
+    priv->assoc_rsp_size = 0;
+    priv->adhoc_auto_sel = MTRUE;
+    priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+    priv->atim_window = 0;
+    priv->adhoc_state = ADHOC_IDLE;
+    priv->tx_power_level = 0;
+    priv->max_tx_power_level = 0;
+    priv->min_tx_power_level = 0;
+    priv->tx_rate = 0;
+    priv->rxpd_htinfo = 0;
+    priv->rxpd_rate = 0;
+    priv->rate_bitmap = 0;
+    priv->data_rssi_last = 0;
+    priv->data_rssi_avg = 0;
+    priv->data_nf_avg = 0;
+    priv->data_nf_last = 0;
+    priv->bcn_rssi_last = 0;
+    priv->bcn_rssi_avg = 0;
+    priv->bcn_nf_avg = 0;
+    priv->bcn_nf_last = 0;
+    memset(&priv->wpa_ie, 0, sizeof(priv->wpa_ie));
+    memset(&priv->aes_key, 0, sizeof(priv->aes_key));
+    priv->wpa_ie_len = 0;
+    priv->wpa_is_gtk_set = MFALSE;
+
+    memset(&priv->mrvl_assoc_tlv_buf, 0, sizeof(priv->mrvl_assoc_tlv_buf));
+    priv->mrvl_assoc_tlv_buf_len = 0;
+    memset(&priv->wps, 0, sizeof(priv->wps));
+    memset(&priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf));
+    priv->gen_ie_buf_len = 0;
+    memset(priv->vs_ie, 0, sizeof(priv->vs_ie));
+
+    priv->wmm_required = MTRUE;
+    priv->wmm_enabled = MFALSE;
+    priv->wmm_qosinfo = 0;
+    priv->gen_null_pkg = MTRUE; /* Enable NULL Pkg generation */
+    pmadapter->callbacks.moal_init_lock(&priv->rx_pkt_lock);
+    priv->pcurr_bcn_buf = MNULL;
+    priv->curr_bcn_size = 0;
+    pmadapter->callbacks.moal_init_lock(&priv->curr_bcn_buf_lock);
+
+    for (i = 0; i < MAX_NUM_TID; i++)
+        priv->addba_reject[i] = ADDBA_RSP_STATUS_ACCEPT;
+
+    util_init_list_head(&priv->tx_ba_stream_tbl_ptr, MTRUE,
+                        pmadapter->callbacks.moal_init_lock);
+    util_init_list_head(&priv->rx_reorder_tbl_ptr, MTRUE,
+                        pmadapter->callbacks.moal_init_lock);
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function allocates buffer for the members of adapter
+ *  		structure like command buffer and BSSID list.
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_allocate_adapter(pmlan_adapter pmadapter)
+{
+    int i;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u32 buf_size;
+    BSSDescriptor_t *ptemp_scan_table;
+    t_u8 *head_ptr = MNULL;
+
+    ENTER();
+
+    /* Allocate buffer to store the BSSID list */
+    buf_size = sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST;
+    ret =
+        pmadapter->callbacks.moal_malloc(buf_size,
+                                         (t_u8 **) & ptemp_scan_table);
+    if (ret != MLAN_STATUS_SUCCESS || !ptemp_scan_table) {
+        PRINTM(MERROR, "Failed to allocate scan table\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    pmadapter->pscan_table = ptemp_scan_table;
+
+    /* Initialize cmd_free_q */
+    util_init_list_head(&pmadapter->cmd_free_q, MTRUE,
+                        pmadapter->callbacks.moal_init_lock);
+    /* Initialize cmd_pending_q */
+    util_init_list_head(&pmadapter->cmd_pending_q, MTRUE,
+                        pmadapter->callbacks.moal_init_lock);
+    /* Initialize scan_pending_q */
+    util_init_list_head(&pmadapter->scan_pending_q, MTRUE,
+                        pmadapter->callbacks.moal_init_lock);
+
+    /* Allocate command buffer */
+    ret = wlan_alloc_cmd_buffer(pmadapter);
+    if (ret != MLAN_STATUS_SUCCESS) {
+        PRINTM(MERROR, "Failed to allocate command buffer\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    for (i = 0; i < MLAN_MAX_BSS_NUM; ++i) {
+        util_init_list_head(&pmadapter->bssprio_tbl[i].bssprio_head,
+                            MTRUE, pmadapter->callbacks.moal_init_lock);
+
+        pmadapter->bssprio_tbl[i].bssprio_cur = MNULL;
+    }
+    ret =
+        pmadapter->callbacks.moal_malloc(MAX_MP_REGS + HEADER_ALIGNMENT,
+                                         (t_u8 **) & pmadapter->mp_regs_buf);
+    if (ret != MLAN_STATUS_SUCCESS || !pmadapter->mp_regs_buf) {
+        PRINTM(MERROR, "Failed to allocate mp_regs_buf\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    pmadapter->mp_regs =
+        (t_u8 *) ALIGN_ADDR(pmadapter->mp_regs_buf, HEADER_ALIGNMENT);
+
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+    ret = wlan_alloc_sdio_mpa_buffers(pmadapter, SDIO_MP_TX_AGGR_DEF_BUF_SIZE,
+                                      SDIO_MP_RX_AGGR_DEF_BUF_SIZE);
+    if (ret != MLAN_STATUS_SUCCESS) {
+        PRINTM(MERROR, "Failed to allocate sdio mp-a buffers\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+#endif
+
+    pmadapter->psleep_cfm =
+        wlan_alloc_mlan_buffer(&pmadapter->callbacks,
+                               HEADER_ALIGNMENT +
+                               sizeof(opt_sleep_confirm_buffer));
+
+    if (pmadapter->psleep_cfm) {
+        head_ptr =
+            (t_u8 *) ALIGN_ADDR(pmadapter->psleep_cfm->pbuf +
+                                pmadapter->psleep_cfm->data_offset,
+                                HEADER_ALIGNMENT);
+        pmadapter->psleep_cfm->data_offset +=
+            (t_u32) (head_ptr -
+                     (pmadapter->psleep_cfm->pbuf +
+                      pmadapter->psleep_cfm->data_offset));
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function initializes the adapter structure
+ *  		and sets default values to the members of adapter.
+ *  
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *
+ *  @return		N/A
+ */
+t_void
+wlan_init_adapter(pmlan_adapter pmadapter)
+{
+    int i;
+
+    opt_sleep_confirm_buffer *sleep_cfm_buf = MNULL;
+
+    ENTER();
+    sleep_cfm_buf = (opt_sleep_confirm_buffer *) (pmadapter->psleep_cfm->pbuf +
+                                                  pmadapter->psleep_cfm->
+                                                  data_offset);
+
+    pmadapter->cmd_sent = MFALSE;
+    pmadapter->data_sent = MTRUE;
+    pmadapter->mp_rd_bitmap = 0;
+    pmadapter->mp_wr_bitmap = 0;
+    pmadapter->curr_rd_port = 1;
+    pmadapter->curr_wr_port = 1;
+    for (i = 0; i < MAX_NUM_TID; i++) {
+        pmadapter->tx_eligibility[i] = 1;
+    }
+    pmadapter->mp_data_port_mask = DATA_PORT_MASK;
+
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+    pmadapter->mpa_tx.buf_len = 0;
+    pmadapter->mpa_tx.pkt_cnt = 0;
+    pmadapter->mpa_tx.start_port = 0;
+
+    pmadapter->mpa_tx.enabled = 0;
+    pmadapter->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
+#endif /* SDIO_MULTI_PORT_TX_AGGR */
+
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+    pmadapter->mpa_rx.buf_len = 0;
+    pmadapter->mpa_rx.pkt_cnt = 0;
+    pmadapter->mpa_rx.start_port = 0;
+
+    pmadapter->mpa_rx.enabled = 0;
+    pmadapter->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
+#endif /* SDIO_MULTI_PORT_RX_AGGR */
+
+    pmadapter->cmd_resp_received = MFALSE;
+    pmadapter->event_received = MFALSE;
+    pmadapter->data_received = MFALSE;
+
+    pmadapter->cmd_timer_is_set = MFALSE;
+
+    /* PnP and power profile */
+    pmadapter->surprise_removed = MFALSE;
+
+    /* Status variables */
+    pmadapter->hw_status = WlanHardwareStatusInitializing;
+
+    pmadapter->ps_mode = Wlan802_11PowerModeCAM;
+    pmadapter->ps_state = PS_STATE_AWAKE;
+    pmadapter->need_to_wakeup = MFALSE;
+
+    /* Scan type */
+    pmadapter->scan_type = HostCmd_SCAN_TYPE_ACTIVE;
+    /* Scan mode */
+    pmadapter->scan_mode = HostCmd_BSS_MODE_ANY;
+    /* Scan time */
+    pmadapter->specific_scan_time = MRVDRV_SPECIFIC_SCAN_CHAN_TIME;
+    pmadapter->active_scan_time = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
+    pmadapter->passive_scan_time = MRVDRV_PASSIVE_SCAN_CHAN_TIME;
+
+    pmadapter->num_in_scan_table = 0;
+    memset(pmadapter->pscan_table, 0,
+           (sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST));
+    pmadapter->scan_probes = 0;
+
+    memset(pmadapter->bcn_buf, 0, sizeof(pmadapter->bcn_buf));
+    pmadapter->pbcn_buf_end = pmadapter->bcn_buf;
+
+    pmadapter->radio_on = RADIO_ON;
+    pmadapter->multiple_dtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
+
+    pmadapter->local_listen_interval = 0;       /* default value in firmware
+                                                   will be used */
+
+    pmadapter->is_deep_sleep = MFALSE;
+
+    pmadapter->delay_null_pkt = MFALSE;
+    pmadapter->delay_to_ps = 100;
+    pmadapter->enhanced_ps_mode = PS_MODE_AUTO;
+
+    pmadapter->pm_wakeup_card_req = MFALSE;
+
+    pmadapter->pm_wakeup_fw_try = MFALSE;
+
+    pmadapter->max_tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;
+    pmadapter->tx_buf_size = MLAN_TX_DATA_BUF_SIZE_2K;
+
+    pmadapter->is_hs_configured = MFALSE;
+    pmadapter->hs_cfg.params.hs_config.conditions = HOST_SLEEP_CFG_CANCEL;
+    pmadapter->hs_cfg.params.hs_config.gpio = 0;
+    pmadapter->hs_cfg.params.hs_config.gap = 0;
+    pmadapter->hs_activated = MFALSE;
+
+    memset(pmadapter->event_body, 0, sizeof(pmadapter->event_body));
+    pmadapter->hw_dot_11n_dev_cap = 0;
+    pmadapter->hw_dev_mcs_support = 0;
+    pmadapter->usr_dot_11n_dev_cap = 0;
+    pmadapter->usr_dev_mcs_support = 0;
+    pmadapter->chan_offset = 0;
+    pmadapter->adhoc_11n_enabled = MFALSE;
+
+    /* Initialize 802.11d */
+    wlan_11d_init(pmadapter);
+
+    wlan_meas_init(pmadapter);
+
+    wlan_11h_init(pmadapter);
+
+    wlan_wmm_init(pmadapter);
+    if (pmadapter->psleep_cfm) {
+        pmadapter->psleep_cfm->buf_type = MLAN_BUF_TYPE_CMD;
+        pmadapter->psleep_cfm->data_len = sizeof(HostCmd_DS_COMMAND);
+        memset(&sleep_cfm_buf->ps_cfm_sleep, 0, sizeof(HostCmd_DS_COMMAND));
+        sleep_cfm_buf->ps_cfm_sleep.command =
+            wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
+        sleep_cfm_buf->ps_cfm_sleep.size =
+            wlan_cpu_to_le16(sizeof(HostCmd_DS_COMMAND));
+        sleep_cfm_buf->ps_cfm_sleep.result = 0;
+        sleep_cfm_buf->ps_cfm_sleep.params.psmode_enh.action =
+            wlan_cpu_to_le16(SLEEP_CONFIRM);
+    }
+    memset(&pmadapter->sleep_params, 0, sizeof(pmadapter->sleep_params));
+    memset(&pmadapter->sleep_period, 0, sizeof(pmadapter->sleep_period));
+    pmadapter->tx_lock_flag = MFALSE;
+    pmadapter->null_pkt_interval = 0;
+    pmadapter->fw_bands = 0;
+    pmadapter->config_bands = 0;
+    pmadapter->adhoc_start_band = 0;
+    pmadapter->pscan_channels = MNULL;
+    pmadapter->fw_release_number = 0;
+    pmadapter->fw_cap_info = 0;
+    memset(&pmadapter->upld_buf, 0, sizeof(pmadapter->upld_buf));
+    pmadapter->upld_len = 0;
+    pmadapter->event_cause = 0;
+    memset(&pmadapter->region_channel, 0, sizeof(pmadapter->region_channel));
+    pmadapter->region_code = 0;
+    pmadapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
+    pmadapter->adhoc_awake_period = 0;
+    memset(&pmadapter->arp_filter, 0, sizeof(pmadapter->arp_filter));
+    pmadapter->arp_filter_size = 0;
+
+    LEAVE();
+    return;
+}
+
+/********************************************************
+        Global Functions
+********************************************************/
+/**
+ *  @brief  This function initializes firmware
+ *
+ *  @param pmadapter		A pointer to mlan_adapter
+ *
+ *  @return		MLAN_STATUS_SUCCESS or error code
+ */
+mlan_status
+wlan_init_fw(IN pmlan_adapter pmadapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private priv = MNULL;
+    t_u8 i = 0;
+    t_u8 first_sta = MTRUE;
+
+    ENTER();
+
+    /* Allocate memory for member of adapter structure */
+    ret = wlan_allocate_adapter(pmadapter);
+    if (ret) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Initialize adapter structure */
+    wlan_init_adapter(pmadapter);
+
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        if (pmadapter->priv[i]) {
+            priv = pmadapter->priv[i];
+
+            /* Initialize private structure */
+            wlan_init_priv(priv);
+
+            if ((ret = wlan_add_bsspriotbl(pmadapter, i))) {
+                ret = MLAN_STATUS_FAILURE;
+                goto done;
+            }
+        }
+    }
+#ifdef MFG_CMD_SUPPORT
+    if (pmadapter->mfg_mode != MTRUE) {
+#endif
+        for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+            if (pmadapter->priv[i]) {
+                ret =
+                    pmadapter->priv[i]->ops.init_cmd(pmadapter->priv[i],
+                                                     first_sta);
+                if (ret == MLAN_STATUS_FAILURE)
+                    goto done;
+                first_sta = MFALSE;
+            }
+        }
+#ifdef MFG_CMD_SUPPORT
+    }
+#endif
+
+    if (util_peek_list(&pmadapter->cmd_pending_q,
+                       pmadapter->callbacks.moal_spin_lock,
+                       pmadapter->callbacks.moal_spin_unlock)) {
+        /* Send the first command in queue and return */
+        if (mlan_main_process(pmadapter) == MLAN_STATUS_FAILURE)
+            ret = MLAN_STATUS_FAILURE;
+        else
+            ret = MLAN_STATUS_PENDING;
+    } else {
+        pmadapter->hw_status = WlanHardwareStatusReady;
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function frees the structure of adapter
+ *    
+ *  @param pmadapter      A pointer to mlan_adapter structure
+ *
+ *  @return             N/A
+ */
+t_void
+wlan_free_adapter(pmlan_adapter pmadapter)
+{
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
+
+    ENTER();
+
+    if (!pmadapter) {
+        PRINTM(MERROR, "The adapter is MNULL.\n");
+        LEAVE();
+        return;
+    }
+
+    wlan_cancel_all_pending_cmd(pmadapter);
+    /* Free command buffer */
+    PRINTM(MINFO, "Free Command buffer\n");
+    wlan_free_cmd_buffer(pmadapter);
+
+    util_free_list_head(&pmadapter->cmd_free_q,
+                        pmadapter->callbacks.moal_free_lock);
+
+    util_free_list_head(&pmadapter->cmd_pending_q,
+                        pmadapter->callbacks.moal_free_lock);
+
+    util_free_list_head(&pmadapter->scan_pending_q,
+                        pmadapter->callbacks.moal_free_lock);
+
+    if (pmadapter->cmd_timer_is_set) {
+        /* Cancel command timeout timer */
+        pcb->moal_stop_timer(pmadapter->pmlan_cmd_timer);
+        pmadapter->cmd_timer_is_set = MFALSE;
+    }
+
+    PRINTM(MINFO, "Free ScanTable\n");
+    if (pmadapter->pscan_table) {
+        pcb->moal_mfree((t_u8 *) pmadapter->pscan_table);
+        pmadapter->pscan_table = MNULL;
+    }
+
+    if (pmadapter->mp_regs_buf) {
+        pcb->moal_mfree((t_u8 *) pmadapter->mp_regs_buf);
+        pmadapter->mp_regs_buf = MNULL;
+        pmadapter->mp_regs = MNULL;
+    }
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+    wlan_free_sdio_mpa_buffers(pmadapter);
+#endif
+    wlan_free_mlan_buffer(&pmadapter->callbacks, pmadapter->psleep_cfm);
+
+    LEAVE();
+    return;
+}
+
+/**
+ *  @brief The cmdresp handler calls this function for init_fw_complete callback
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *
+ *  @return		MLAN_STATUS_SUCCESS
+ *                      	The firmware initialization callback succeeded.
+ * 			MLAN_STATUS_FAILURE
+ *                      	The firmware initialization callback failed.
+ */
+mlan_status
+wlan_init_fw_complete(IN pmlan_adapter pmadapter)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    ENTER();
+
+    /* Check if hardware is ready */
+    if (pmadapter->hw_status != WlanHardwareStatusReady)
+        status = MLAN_STATUS_FAILURE;
+
+    LEAVE();
+    /* Invoke callback */
+    return pcb->moal_init_fw_complete(pmadapter->pmoal_handle, status);
+}
+
+/**
+ *  @brief The cmdresp handler calls this function for shutdown_fw_complete callback
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *
+ *  @return		MLAN_STATUS_SUCCESS
+ *                      	The firmware shutdown callback succeeded.
+ *			MLAN_STATUS_FAILURE
+ *                      	The firmware shutdown callback failed.
+ */
+mlan_status
+wlan_shutdown_fw_complete(IN pmlan_adapter pmadapter)
+{
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    pmadapter->hw_status = WlanHardwareStatusNotReady;
+    /* Invoke callback */
+    return pcb->moal_shutdown_fw_complete(pmadapter->pmoal_handle, status);
+}
+
+/**
+ *  @brief This function deletes the BSS priority table
+ *  
+ *  @param priv		A pointer to mlan_private structure
+ *
+ *  @return		N/A
+ */
+t_void
+wlan_delete_bsspriotbl(pmlan_private priv)
+{
+    int i;
+    pmlan_adapter pmadapter = priv->adapter;
+    mlan_bssprio_node *pbssprio_node, *ptmp_node;
+    pmlan_list_head phead;
+
+    ENTER();
+
+    for (i = 0; i < MLAN_MAX_BSS_NUM; ++i) {
+        phead = &pmadapter->bssprio_tbl[i].bssprio_head;
+        if (phead) {
+            pbssprio_node = (mlan_bssprio_node *) util_peek_list(phead,
+                                                                 pmadapter->
+                                                                 callbacks.
+                                                                 moal_spin_lock,
+                                                                 pmadapter->
+                                                                 callbacks.
+                                                                 moal_spin_unlock);
+            while (pbssprio_node && ((pmlan_list_head) pbssprio_node != phead)) {
+                ptmp_node = pbssprio_node->pnext;
+                if (pbssprio_node->priv == priv) {
+                    util_unlink_list(phead,
+                                     (pmlan_linked_list) pbssprio_node,
+                                     pmadapter->callbacks.moal_spin_lock,
+                                     pmadapter->callbacks.moal_spin_unlock);
+
+                    pmadapter->callbacks.moal_mfree((t_u8 *) pbssprio_node);
+                }
+                pbssprio_node = ptmp_node;
+            }
+        }
+    }
+
+    LEAVE();
+}
diff --git a/wlan_src/mlan/mlan_init.h b/wlan_src/mlan/mlan_init.h
new file mode 100755
index 0000000..742f1b8
--- /dev/null
+++ b/wlan_src/mlan/mlan_init.h
@@ -0,0 +1,76 @@
+/** @file mlan_init.h
+ *
+ *  @brief This file defines the FW initialization data
+ *  structures.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    10/13/2008: initial version
+******************************************************/
+
+#ifndef _MLAN_INIT_H_
+#define _MLAN_INIT_H_
+
+/** Tx buffer size for firmware download*/
+#define FW_DNLD_TX_BUF_SIZE	620
+/** Rx buffer size for firmware download*/
+#define FW_DNLD_RX_BUF_SIZE       2048
+/** Max firmware retry */
+#define MAX_FW_RETRY        	3
+
+/** Firmware has last block */
+#define FW_HAS_LAST_BLOCK		0x00000004
+
+/** Firmware data transmit size */
+#define FW_DATA_XMIT_SIZE \
+	sizeof(FWHeader) + DataLength + sizeof(t_u32)
+
+/** FWHeader */
+typedef struct _FWHeader
+{
+    /** FW download command */
+    t_u32 dnld_cmd;
+    /** FW base address */
+    t_u32 base_addr;
+    /** FW data length */
+    t_u32 data_length;
+    /** FW CRC */
+    t_u32 crc;
+} FWHeader;
+
+/** FWData */
+typedef struct _FWData
+{
+    /** FW data header */
+    FWHeader fw_header;
+    /** FW data sequence number */
+    t_u32 seq_num;
+    /** FW data buffer */
+    t_u8 data[1];
+} FWData;
+
+/** FWSyncHeader */
+typedef struct _FWSyncHeader
+{
+    /** FW sync header command */
+    t_u32 cmd;
+    /** FW sync header sequence number */
+    t_u32 seq_num;
+} FWSyncHeader;
+
+#ifdef BIG_ENDIAN
+/** Convert sequence number and command fields of fwheader to correct endian format */
+#define endian_convert_syncfwheader(x); { \
+		(x)->cmd = wlan_le32_to_cpu((x)->cmd); \
+		(x)->seq_num = wlan_le32_to_cpu((x)->seq_num); \
+	}
+#else
+/** Convert sequence number and command fields of fwheader to correct endian format */
+#define endian_convert_syncfwheader(x)
+#endif /* BIG_ENDIAN */
+
+#endif /* _MLAN_INIT_H_ */
diff --git a/wlan_src/mlan/mlan_ioctl.h b/wlan_src/mlan/mlan_ioctl.h
new file mode 100755
index 0000000..bdf5342
--- /dev/null
+++ b/wlan_src/mlan/mlan_ioctl.h
@@ -0,0 +1,1829 @@
+/** @file mlan_ioctl.h
+ *
+ *  @brief This file declares the IOCTL data structures and APIs.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    11/07/2008: initial version
+******************************************************/
+
+#ifndef _MLAN_IOCTL_H_
+#define _MLAN_IOCTL_H_
+
+/** mlan_802_11_ssid data structure */
+typedef struct _mlan_802_11_ssid
+{
+    /** SSID Length */
+    t_u32 ssid_len;
+    /** SSID information field */
+    t_u8 ssid[MLAN_MAX_SSID_LENGTH];
+} mlan_802_11_ssid, *pmlan_802_11_ssid;
+
+/** Enumeration for IOCTL request ID */
+enum
+{
+    /* Scan Group */
+    MLAN_IOCTL_SCAN = 0x00010000,
+    MLAN_OID_SCAN_NORMAL,
+    MLAN_OID_SCAN_SPECIFIC_SSID,
+    MLAN_OID_SCAN_USER_CONFIG,
+    MLAN_OID_SCAN_CONFIG,
+
+    /* BSS Configuration Group */
+    MLAN_IOCTL_BSS = 0x00020000,
+    MLAN_OID_BSS_START,
+    MLAN_OID_BSS_STOP,
+    MLAN_OID_BSS_MODE,
+    MLAN_OID_BSS_CHANNEL,
+    MLAN_OID_BSS_CHANNEL_LIST,
+    MLAN_OID_BSS_MAC_ADDR,
+    MLAN_OID_BSS_MULTICAST_LIST,
+    MLAN_OID_BSS_FIND_BSS,
+    MLAN_OID_IBSS_BCN_INTERVAL,
+    MLAN_OID_IBSS_ATIM_WINDOW,
+    MLAN_OID_IBSS_CHANNEL,
+
+    /* Radio Configuration Group */
+    MLAN_IOCTL_RADIO_CFG = 0x00030000,
+    MLAN_OID_RADIO_CTRL,
+    MLAN_OID_BAND_CFG,
+    MLAN_OID_ANT_CFG,
+
+    /* SNMP MIB Group */
+    MLAN_IOCTL_SNMP_MIB = 0x00040000,
+    MLAN_OID_SNMP_MIB_RTS_THRESHOLD,
+    MLAN_OID_SNMP_MIB_FRAG_THRESHOLD,
+    MLAN_OID_SNMP_MIB_RETRY_COUNT,
+
+    /* Status Information Group */
+    MLAN_IOCTL_GET_INFO = 0x00050000,
+    MLAN_OID_GET_STATS,
+    MLAN_OID_GET_SIGNAL,
+    MLAN_OID_GET_FW_INFO,
+    MLAN_OID_GET_VER_EXT,
+    MLAN_OID_GET_BSS_INFO,
+    MLAN_OID_GET_DEBUG_INFO,
+
+    /* Security Configuration Group */
+    MLAN_IOCTL_SEC_CFG = 0x00060000,
+    MLAN_OID_SEC_CFG_AUTH_MODE,
+    MLAN_OID_SEC_CFG_ENCRYPT_MODE,
+    MLAN_OID_SEC_CFG_WPA_ENABLED,
+    MLAN_OID_SEC_CFG_ENCRYPT_KEY,
+    MLAN_OID_SEC_CFG_PASSPHRASE,
+    MLAN_OID_SEC_CFG_EWPA_ENABLED,
+    MLAN_OID_SEC_CFG_ESUPP_MODE,
+    MLAN_OID_SEC_CFG_WAPI_ENABLED,
+
+    /* Rate Group */
+    MLAN_IOCTL_RATE = 0x00070000,
+    MLAN_OID_RATE_CFG,
+    MLAN_OID_GET_DATA_RATE,
+    MLAN_OID_SUPPORTED_RATES,
+
+    /* Power Configuration Group */
+    MLAN_IOCTL_POWER_CFG = 0x00080000,
+    MLAN_OID_POWER_CFG,
+    MLAN_OID_POWER_CFG_EXT,
+
+    /* Power Management Configuration Group */
+    MLAN_IOCTL_PM_CFG = 0x00090000,
+    MLAN_OID_PM_CFG_IEEE_PS,
+    MLAN_OID_PM_CFG_HS_CFG,
+    MLAN_OID_PM_CFG_INACTIVITY_TO,
+    MLAN_OID_PM_CFG_DEEP_SLEEP,
+    MLAN_OID_PM_CFG_SLEEP_PD,
+    MLAN_OID_PM_CFG_PS_CFG,
+    MLAN_OID_PM_CFG_SLEEP_PARAMS,
+
+    /* WMM Configuration Group */
+    MLAN_IOCTL_WMM_CFG = 0x000A0000,
+    MLAN_OID_WMM_CFG_ENABLE,
+    MLAN_OID_WMM_CFG_QOS,
+    MLAN_OID_TID_ELIG_TBL,
+    MLAN_OID_WMM_CFG_ADDTS,
+    MLAN_OID_WMM_CFG_DELTS,
+    MLAN_OID_WMM_CFG_QUEUE_CONFIG,
+    MLAN_OID_WMM_CFG_QUEUE_STATS,
+    MLAN_OID_WMM_CFG_QUEUE_STATUS,
+    MLAN_OID_WMM_CFG_TS_STATUS,
+
+    /* WPS Configuration Group */
+    MLAN_IOCTL_WPS_CFG = 0x000B0000,
+    MLAN_OID_WPS_CFG_SESSION,
+
+    /* 802.11n Configuration Group */
+    MLAN_IOCTL_11N_CFG = 0x000C0000,
+    MLAN_OID_11N_CFG_TX,
+    MLAN_OID_11N_HTCAP_CFG,
+    MLAN_OID_11N_CFG_ADDBA_REJECT,
+    MLAN_OID_11N_CFG_AGGR_PRIO_TBL,
+    MLAN_OID_11N_CFG_ADDBA_PARAM,
+    MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE,
+    MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL,
+
+    /* 802.11d Configuration Group */
+    MLAN_IOCTL_11D_CFG = 0x000D0000,
+    MLAN_OID_11D_CFG_ENABLE,
+
+    /* Register Memory Access Group */
+    MLAN_IOCTL_REG_MEM = 0x000E0000,
+    MLAN_OID_REG_RW,
+    MLAN_OID_EEPROM_RD,
+    MLAN_OID_MEM_RW,
+
+    /* Bluetooth Coalescing Configuration Group */
+    MLAN_IOCTL_BCA_CFG = 0x000F0000,
+    MLAN_OID_BCA_TS,
+
+    /* Miscellaneous Configuration Group */
+    MLAN_IOCTL_MISC_CFG = 0x00200000,
+    MLAN_OID_MISC_GEN_IE,
+    MLAN_OID_MISC_REGION,
+    MLAN_OID_MISC_WARM_RESET,
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+    MLAN_OID_MISC_SDIO_MPA_CTRL,
+#endif
+#ifdef MFG_CMD_SUPPORT
+    MLAN_OID_MISC_MFG_CMD,
+#endif
+    MLAN_OID_MISC_HOST_CMD,
+    MLAN_OID_MISC_LDO,
+    MLAN_OID_MISC_SYS_CLOCK,
+    MLAN_OID_MISC_WWS,
+    MLAN_OID_MISC_VS_IE,
+    MLAN_OID_MISC_INIT_SHUTDOWN,
+};
+
+/** Sub command size */
+#define MLAN_SUB_COMMAND_SIZE	4
+
+/** Enumeration for the action of IOCTL request */
+enum
+{
+    MLAN_ACT_SET = 1,
+    MLAN_ACT_GET,
+    MLAN_ACT_CANCEL
+};
+
+/** Enumeration for generic enable/disable */
+enum
+{
+    MLAN_ACT_DISABLE = 0,
+    MLAN_ACT_ENABLE = 1
+};
+
+/** Enumeration for scan mode */
+enum
+{
+    MLAN_SCAN_MODE_UNCHANGED = 0,
+    MLAN_SCAN_MODE_BSS,
+    MLAN_SCAN_MODE_IBSS,
+    MLAN_SCAN_MODE_ANY
+};
+
+/** Enumeration for scan type */
+enum
+{
+    MLAN_SCAN_TYPE_UNCHANGED = 0,
+    MLAN_SCAN_TYPE_ACTIVE,
+    MLAN_SCAN_TYPE_PASSIVE
+};
+
+/** RSSI scan */
+#define SCAN_RSSI(RSSI)			(0x100 - ((t_u8)(RSSI)))
+
+/** Max passive scan time for each channel in milliseconds */
+#define MRVDRV_MAX_PASSIVE_SCAN_CHAN_TIME   2000
+
+/** Max active scan time for each channel in milliseconds  */
+#define MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME    500
+
+/**
+ *  @brief Sub-structure passed in wlan_ioctl_get_scan_table_entry for each BSS
+ *
+ *  Fixed field information returned for the scan response in the IOCTL
+ *    response.
+ */
+typedef struct _wlan_get_scan_table_fixed
+{
+    /** BSSID of this network */
+    t_u8 bssid[MLAN_MAC_ADDR_LENGTH];
+    /** Channel this beacon/probe response was detected */
+    t_u8 channel;
+    /** RSSI for the received packet */
+    t_u8 rssi;
+    /** TSF value from the firmware at packet reception */
+    t_u64 network_tsf;
+} wlan_get_scan_table_fixed;
+
+/**
+ *  Sructure to retrieve the scan table
+ */
+typedef struct
+{
+    /**
+     *  - Zero based scan entry to start retrieval in command request
+     *  - Number of scans entries returned in command response
+     */
+    t_u32 scan_number;
+    /**
+     * Buffer marker for multiple wlan_ioctl_get_scan_table_entry structures.
+     *   Each struct is padded to the nearest 32 bit boundary.
+     */
+    t_u8 scan_table_entry_buf[1];
+} wlan_ioctl_get_scan_table_info;
+
+/**
+ *  Structure passed in the wlan_ioctl_get_scan_table_info for each
+ *    BSS returned in the WLAN_GET_SCAN_RESP IOCTL
+ */
+typedef struct _wlan_ioctl_get_scan_table_entry
+{
+    /**
+     *  Fixed field length included in the response.
+     *
+     *  Length value is included so future fixed fields can be added to the
+     *   response without breaking backwards compatibility.  Use the length
+     *   to find the offset for the bssInfoLength field, not a sizeof() calc.
+     */
+    t_u32 fixed_field_length;
+
+    /**
+     *  Always present, fixed length data fields for the BSS
+     */
+    wlan_get_scan_table_fixed fixed_fields;
+
+    /**
+     *  Length of the BSS Information (probe resp or beacon) that
+     *    follows starting at bssInfoBuffer
+     */
+    t_u32 bss_info_length;
+
+    /**
+     *  Probe response or beacon scanned for the BSS.
+     *
+     *  Field layout:
+     *   - TSF              8 octets
+     *   - Beacon Interval  2 octets
+     *   - Capability Info  2 octets
+     *
+     *   - IEEE Infomation Elements; variable number & length per 802.11 spec
+     */
+    t_u8 bss_info_buffer[1];
+} wlan_ioctl_get_scan_table_entry;
+
+/** Type definition of mlan_scan_time_params */
+typedef struct _mlan_scan_time_params
+{
+    /** Scan channel time for specific scan */
+    t_u32 specific_scan_time;
+    /** Scan channel time for active scan */
+    t_u32 active_scan_time;
+    /** Scan channel time for passive scan */
+    t_u32 passive_scan_time;
+} mlan_scan_time_params, *pmlan_scan_time_params;
+
+/** Type definition of mlan_user_scan */
+typedef struct _mlan_user_scan
+{
+    /** Length of scan_cfg_buf */
+    t_u32 scan_cfg_len;
+    /** Buffer of scan config */
+    t_u8 scan_cfg_buf[1];
+} mlan_user_scan, *pmlan_user_scan;
+
+/** Type definition of mlan_scan_req */
+typedef struct _mlan_scan_req
+{
+    /** BSS mode for scanning */
+    t_u32 scan_mode;
+    /** Scan type */
+    t_u32 scan_type;
+    /** SSID */
+    mlan_802_11_ssid scan_ssid;
+    /** Scan time parameters */
+    mlan_scan_time_params scan_time;
+    /** Scan config parameters in user scan */
+    mlan_user_scan user_scan;
+} mlan_scan_req, *pmlan_scan_req;
+
+/** Type defnition of mlan_scan_resp */
+typedef struct _mlan_scan_resp
+{
+    /** Number of scan result */
+    t_u32 num_in_scan_table;
+    /** Scan table */
+    t_u8 *pscan_table;
+} mlan_scan_resp, *pmlan_scan_resp;
+
+/** Type definition of mlan_scan_cfg */
+typedef struct _mlan_scan_cfg
+{
+    /** Scan type */
+    t_u32 scan_type;
+    /** BSS mode for scanning */
+    t_u32 scan_mode;
+    /** Scan probe */
+    t_u32 scan_probe;
+    /** Scan time parameters */
+    mlan_scan_time_params scan_time;
+} mlan_scan_cfg, *pmlan_scan_cfg;
+
+/** Type defnition of mlan_ds_scan for MLAN_IOCTL_SCAN */
+typedef struct _mlan_ds_scan
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** Scan request/response */
+    union
+    {
+        /** Scan request */
+        mlan_scan_req scan_req;
+        /** Scan response */
+        mlan_scan_resp scan_resp;
+        /** Scan config parameters in user scan */
+        mlan_user_scan user_scan;
+        /** Scan config parameters */
+        mlan_scan_cfg scan_cfg;
+    } param;
+} mlan_ds_scan, *pmlan_ds_scan;
+
+/*-----------------------------------------------------------------*/
+/** BSS Configuration Group */
+/*-----------------------------------------------------------------*/
+/** Enumeration for BSS mode */
+enum
+{
+    MLAN_BSS_MODE_INFRA = 1,
+    MLAN_BSS_MODE_IBSS,
+    MLAN_BSS_MODE_AUTO
+};
+
+/** Maximum atim window */
+#define MLAN_MAX_ATIM_WINDOW		50
+
+/** Minimum beacon interval */
+#define MLAN_MIN_BEACON_INTERVAL        20
+/** Maximum beacon interval */
+#define MLAN_MAX_BEACON_INTERVAL        1000
+/** Default beacon interval */
+#define MLAN_BEACON_INTERVAL            100
+
+/** Receive all packets */
+#define MLAN_PROMISC_MODE     	1
+/** Receive multicast packets in multicast list */
+#define MLAN_MULTICAST_MODE		2
+/** Receive all multicast packets */
+#define	MLAN_ALL_MULTI_MODE		4
+
+/** Maximum size of multicast list */
+#define MLAN_MAX_MULTICAST_LIST_SIZE	32
+
+/** mlan_multicast_list data structure for MLAN_OID_BSS_MULTICAST_LIST */
+typedef struct _mlan_multicast_list
+{
+    /** Multicast mode */
+    t_u32 mode;
+    /** Number of multicast addresses in the list */
+    t_u32 num_multicast_addr;
+    /** Multicast address list */
+    mlan_802_11_mac_addr mac_list[MLAN_MAX_MULTICAST_LIST_SIZE];
+} mlan_multicast_list, *pmlan_multicast_list;
+
+/** Maximum channel number */
+#define MLAN_MAX_CHANNEL_NUM	128
+
+/** Channel/frequence for MLAN_OID_BSS_CHANNEL */
+typedef struct _chan_freq
+{
+    /** Channel Number */
+    t_u32 channel;
+    /** Frequency of this Channel */
+    t_u32 freq;
+} chan_freq;
+
+/** mlan_chan_list data structure for MLAN_OID_BSS_CHANNEL_LIST */
+typedef struct _mlan_chan_list
+{
+    /** Number of channel */
+    t_u32 num_of_chan;
+    /** Channel-Frequency table */
+    chan_freq cf[MLAN_MAX_CHANNEL_NUM];
+} mlan_chan_list;
+
+/** mlan_ssid_bssid  data structure for MLAN_OID_BSS_START and MLAN_OID_BSS_FIND_BSS */
+typedef struct _mlan_ssid_bssid
+{
+    /** SSID */
+    mlan_802_11_ssid ssid;
+    /** BSSID */
+    mlan_802_11_mac_addr bssid;
+} mlan_ssid_bssid;
+
+/** Type definition of mlan_ds_bss for MLAN_IOCTL_BSS */
+typedef struct _mlan_ds_bss
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** BSS parameter */
+    union
+    {
+        /** SSID-BSSID for MLAN_OID_BSS_START */
+        mlan_ssid_bssid ssid_bssid;
+        /** BSSID for MLAN_OID_BSS_STOP */
+        mlan_802_11_mac_addr bssid;
+        /** BSS mode for MLAN_OID_BSS_MODE */
+        t_u32 bss_mode;
+        /** BSS channel/frequency for MLAN_OID_BSS_CHANNEL */
+        chan_freq bss_chan;
+        /** BSS channel list for MLAN_OID_BSS_CHANNEL_LIST */
+        mlan_chan_list chanlist;
+        /** MAC address for MLAN_OID_BSS_MAC_ADDR */
+        mlan_802_11_mac_addr mac_addr;
+        /** Multicast list for MLAN_OID_BSS_MULTICAST_LIST */
+        mlan_multicast_list multicast_list;
+        /** Beacon interval for MLAN_OID_IBSS_BCN_INTERVAL */
+        t_u32 bcn_interval;
+        /** ATIM window for MLAN_OID_IBSS_ATIM_WINDOW */
+        t_u32 atim_window;
+    } param;
+} mlan_ds_bss, *pmlan_ds_bss;
+
+/** Enumeration for band */
+enum
+{
+    BAND_B = 1,
+    BAND_G = 2,
+    BAND_A = 4,
+    BAND_GN = 8,
+    BAND_AN = 16,
+};
+
+/*-----------------------------------------------------------------*/
+/** Radio Control Group */
+/*-----------------------------------------------------------------*/
+
+/** Type definition of mlan_ds_band_cfg for MLAN_OID_BAND_CFG */
+typedef struct _mlan_ds_band_cfg
+{
+    /** Infra band */
+    t_u32 config_bands;
+    /** Ad-hoc start band */
+    t_u32 adhoc_start_band;
+    /** Ad-hoc start channel */
+    t_u32 adhoc_channel;
+} mlan_ds_band_cfg;
+
+/** Type definition of mlan_ds_radio_cfg for MLAN_IOCTL_RADIO_CFG */
+typedef struct _mlan_ds_radio_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** Radio control parameter */
+    union
+    {
+        /** Radio on/off for MLAN_OID_RADIO_CTRL */
+        t_u32 radio_on_off;
+        /** Band info for MLAN_OID_BAND_CFG */
+        mlan_ds_band_cfg band_cfg;
+        /** Antenna info for MLAN_OID_ANT_CFG */
+        t_u32 antenna;
+    } param;
+} mlan_ds_radio_cfg, *pmlan_ds_radio_cfg;
+
+/*-----------------------------------------------------------------*/
+/** SNMP MIB Group */
+/*-----------------------------------------------------------------*/
+/** Type definition of mlan_ds_snmp_mib for MLAN_IOCTL_SNMP_MIB */
+typedef struct _mlan_ds_snmp_mib
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** SNMP MIB parameter */
+    union
+    {
+        /** RTS threshold for MLAN_OID_SNMP_MIB_RTS_THRESHOLD */
+        t_u32 rts_threshold;
+        /** Fragment threshold for MLAN_OID_SNMP_MIB_FRAG_THRESHOLD */
+        t_u32 frag_threshold;
+        /** Retry count for MLAN_OID_SNMP_MIB_RETRY_COUNT */
+        t_u32 retry_count;
+    } param;
+} mlan_ds_snmp_mib, *pmlan_ds_snmp_mib;
+
+/*-----------------------------------------------------------------*/
+/** Status Information Group */
+/*-----------------------------------------------------------------*/
+/** Enumeration for ad-hoc status */
+enum
+{
+    ADHOC_IDLE,
+    ADHOC_STARTED,
+    ADHOC_JOINED,
+    ADHOC_COALESCED
+};
+
+/** Type definition of mlan_ds_get_stats for MLAN_OID_GET_STATS */
+typedef struct _mlan_ds_get_stats
+{
+    /** Statistics counter */
+    /** Multicast transmitted frame count */
+    t_u32 mcast_tx_frame;
+    /** Failure count */
+    t_u32 failed;
+    /** Retry count */
+    t_u32 retry;
+    /** Multi entry count */
+    t_u32 multi_retry;
+    /** Duplicate frame count */
+    t_u32 frame_dup;
+    /** RTS success count */
+    t_u32 rts_success;
+    /** RTS failure count */
+    t_u32 rts_failure;
+    /** Ack failure count */
+    t_u32 ack_failure;
+    /** Rx fragmentation count */
+    t_u32 rx_frag;
+    /** Multicast Tx frame count */
+    t_u32 mcast_rx_frame;
+    /** FCS error count */
+    t_u32 fcs_error;
+    /** Tx frame count */
+    t_u32 tx_frame;
+    /** WEP ICV error count */
+    t_u32 wep_icv_error[4];
+} mlan_ds_get_stats, *pmlan_ds_get_stats;
+
+/** Mask of last beacon RSSI */
+#define BCN_RSSI_LAST_MASK              0x00000001
+/** Mask of average beacon RSSI */
+#define BCN_RSSI_AVG_MASK               0x00000002
+/** Mask of last data RSSI */
+#define DATA_RSSI_LAST_MASK             0x00000004
+/** Mask of average data RSSI */
+#define DATA_RSSI_AVG_MASK              0x00000008
+/** Mask of last beacon SNR */
+#define BCN_SNR_LAST_MASK               0x00000010
+/** Mask of average beacon SNR */
+#define BCN_SNR_AVG_MASK                0x00000020
+/** Mask of last data SNR */
+#define DATA_SNR_LAST_MASK              0x00000040
+/** Mask of average data SNR */
+#define DATA_SNR_AVG_MASK               0x00000080
+/** Mask of last beacon NF */
+#define BCN_NF_LAST_MASK                0x00000100
+/** Mask of average beacon NF */
+#define BCN_NF_AVG_MASK                 0x00000200
+/** Mask of last data NF */
+#define DATA_NF_LAST_MASK               0x00000400
+/** Mask of average data NF */
+#define DATA_NF_AVG_MASK                0x00000800
+/** Mask of all RSSI_INFO */
+#define ALL_RSSI_INFO_MASK              0x00000fff
+
+/** Type definition of mlan_ds_get_signal for MLAN_OID_GET_SIGNAL */
+typedef struct _mlan_ds_get_signal
+{
+    /** Selector of get operation */
+    /* 
+     * Bit0:  Last Beacon RSSI,  Bit1:  Average Beacon RSSI,
+     * Bit2:  Last Data RSSI,    Bit3:  Average Data RSSI,
+     * Bit4:  Last Beacon SNR,   Bit5:  Average Beacon SNR,
+     * Bit6:  Last Data SNR,     Bit7:  Average Data SNR,
+     * Bit8:  Last Beacon NF,    Bit9:  Average Beacon NF,
+     * Bit10: Last Data NF,      Bit11: Average Data NF
+     */
+    t_u16 selector;
+
+    /** RSSI */
+    /** RSSI of last beacon */
+    t_s16 bcn_rssi_last;
+    /** RSSI of beacon average */
+    t_s16 bcn_rssi_avg;
+    /** RSSI of last data packet */
+    t_s16 data_rssi_last;
+    /** RSSI of data packet average */
+    t_s16 data_rssi_avg;
+
+    /** SNR */
+    /** SNR of last beacon */
+    t_s16 bcn_snr_last;
+    /** SNR of beacon average */
+    t_s16 bcn_snr_avg;
+    /** SNR of last data packet */
+    t_s16 data_snr_last;
+    /** SNR of data packet average */
+    t_s16 data_snr_avg;
+
+    /** NF */
+    /** NF of last beacon */
+    t_s16 bcn_nf_last;
+    /** NF of beacon average */
+    t_s16 bcn_nf_avg;
+    /** NF of last data packet */
+    t_s16 data_nf_last;
+    /** NF of data packet average */
+    t_s16 data_nf_avg;
+} mlan_ds_get_signal, *pmlan_ds_get_signal;
+
+/** mlan_fw_info data structure for MLAN_OID_GET_FW_INFO */
+typedef struct _mlan_fw_info
+{
+    /** Firmware version */
+    t_u32 fw_ver;
+    /** MAC address */
+    mlan_802_11_mac_addr mac_addr;
+} mlan_fw_info, *pmlan_fw_info;
+
+/** Version string buffer length */
+#define MLAN_MAX_VER_STR_LEN    128
+
+/** mlan_ver_ext data structure for MLAN_OID_GET_VER_EXT */
+typedef struct _mlan_ver_ext
+{
+    /** Selected version string */
+    t_u32 version_str_sel;
+    /** Version string */
+    char version_str[MLAN_MAX_VER_STR_LEN];
+} mlan_ver_ext, *pmlan_ver_ext;
+
+/** mlan_bss_info data structure for MLAN_OID_GET_BSS_INFO */
+typedef struct _mlan_bss_info
+{
+    /** BSS mode */
+    t_u32 bss_mode;
+    /** SSID */
+    mlan_802_11_ssid ssid;
+    /** Table index */
+    t_u32 scan_table_idx;
+    /** Channel */
+    t_u32 bss_chan;
+    /** Region code */
+    t_u32 region_code;
+    /** Connection status */
+    t_u32 media_connected;
+    /** Radio on */
+    t_u32 radio_on;
+    /** Max power level */
+    t_u32 max_power_level;
+    /** Min power level */
+    t_u32 min_power_level;
+    /** Adhoc state */
+    t_u32 adhoc_state;
+    /** NF of last beacon */
+    t_s32 bcn_nf_last;
+    /** wep status */
+    t_u32 wep_status;
+     /** Host Sleep configured flag */
+    t_u32 is_hs_configured;
+    /** Deep Sleep flag */
+    t_u32 is_deep_sleep;
+    /** BSSID */
+    mlan_802_11_mac_addr bssid;
+} mlan_bss_info, *pmlan_bss_info;
+
+/** MAXIMUM number of TID */
+#define MAX_NUM_TID     8
+
+/** Max RX Win size */
+#define MAX_RX_WINSIZE 		64
+
+/** rx_reorder_tbl */
+typedef struct
+{
+    /** TID */
+    t_u16 tid;
+    /** TA */
+    t_u8 ta[MLAN_MAC_ADDR_LENGTH];
+    /** Start window */
+    t_u32 start_win;
+    /** Window size */
+    t_u32 win_size;
+    /** buffer status */
+    t_u32 buffer[MAX_RX_WINSIZE];
+} rx_reorder_tbl;
+
+/** tx_ba_stream_tbl */
+typedef struct
+{
+    /** TID */
+    t_u16 tid;
+    /** TA */
+    t_u8 ra[MLAN_MAC_ADDR_LENGTH];
+} tx_ba_stream_tbl;
+
+/** Debug command number */
+#define DBG_CMD_NUM	5
+
+/** mlan_debug_info data structure for MLAN_OID_GET_DEBUG_INFO */
+typedef struct _mlan_debug_info
+{
+    /** Corresponds to IntCounter member of mlan_adapter */
+    t_u32 int_counter;
+    /** Corresponds to packets_out member of mlan_adapter.wmm */
+    t_u32 packets_out[MAX_NUM_TID];
+    /** Corresponds to max_tx_buf_size member of mlan_adapter*/
+    t_u32 max_tx_buf_size;
+     /** Corresponds to tx_buf_size member of mlan_adapter*/
+    t_u32 tx_buf_size;
+    /** Tx table num */
+    t_u32 tx_tbl_num;
+    /** Tx ba stream table */
+    tx_ba_stream_tbl tx_tbl[MLAN_MAX_BASTREAM_SUPPORTED];
+    /** Rx table num */
+    t_u32 rx_tbl_num;
+    /** Rx reorder table*/
+    rx_reorder_tbl rx_tbl[MLAN_MAX_BASTREAM_SUPPORTED];
+    /** Corresponds to ps_mode member of mlan_adapter */
+    t_u16 ps_mode;
+    /** Corresponds to ps_state member of mlan_adapter */
+    t_u32 ps_state;
+    /** Corresponds to is_deep_sleep member of mlan_adapter */
+    t_u8 is_deep_sleep;
+    /** Corresponds to pm_wakeup_card_req member of mlan_adapter */
+    t_u8 pm_wakeup_card_req;
+    /** Corresponds to pm_wakeup_fw_try member of mlan_adapter */
+    t_u32 pm_wakeup_fw_try;
+    /** Corresponds to is_hs_configured member of mlan_adapter */
+    t_u8 is_hs_configured;
+    /** Corresponds to hs_activated member of mlan_adapter */
+    t_u8 hs_activated;
+
+    /** Number of host to card command failures */
+    t_u32 num_cmd_host_to_card_failure;
+    /** Number of host to card sleep confirm failures */
+    t_u32 num_cmd_sleep_cfm_host_to_card_failure;
+    /** Number of host to card Tx failures */
+    t_u32 num_tx_host_to_card_failure;
+    /** Number of deauthentication events */
+    t_u32 num_event_deauth;
+    /** Number of disassosiation events */
+    t_u32 num_event_disassoc;
+    /** Number of link lost events */
+    t_u32 num_event_link_lost;
+    /** Number of deauthentication commands */
+    t_u32 num_cmd_deauth;
+    /** Number of association comamnd successes */
+    t_u32 num_cmd_assoc_success;
+    /** Number of association command failures */
+    t_u32 num_cmd_assoc_failure;
+    /** Number of Tx timeouts */
+    t_u32 num_tx_timeout;
+    /** Number of command timeouts */
+    t_u32 num_cmd_timeout;
+    /** Timeout command ID */
+    t_u16 timeout_cmd_id;
+    /** Timeout command action */
+    t_u16 timeout_cmd_act;
+    /** List of last command IDs */
+    t_u16 last_cmd_id[DBG_CMD_NUM];
+    /** List of last command actions */
+    t_u16 last_cmd_act[DBG_CMD_NUM];
+    /** Last command index */
+    t_u16 last_cmd_index;
+    /** List of last command response IDs */
+    t_u16 last_cmd_resp_id[DBG_CMD_NUM];
+    /** Last command response index */
+    t_u16 last_cmd_resp_index;
+    /** List of last events */
+    t_u16 last_event[DBG_CMD_NUM];
+    /** Last event index */
+    t_u16 last_event_index;
+
+    /** Corresponds to data_sent member of mlan_adapter */
+    t_u8 data_sent;
+    /** Corresponds to cmd_sent member of mlan_adapter */
+    t_u8 cmd_sent;
+    /** SDIO multiple port read bitmap */
+    t_u16 mp_rd_bitmap;
+    /** SDIO multiple port write bitmap */
+    t_u16 mp_wr_bitmap;
+    /** Current available port for read */
+    t_u8 curr_rd_port;
+    /** Current available port for write */
+    t_u8 curr_wr_port;
+    /** Corresponds to cmdresp_received member of mlan_adapter */
+    t_u8 cmd_resp_received;
+    /** Corresponds to event_received member of mlan_adapter */
+    t_u8 event_received;
+} mlan_debug_info, *pmlan_debug_info;
+
+/** Type definition of mlan_ds_get_info for MLAN_IOCTL_GET_INFO */
+typedef struct _mlan_ds_get_info
+{
+    /** Sub-command */
+    t_u32 sub_command;
+
+    /** Status information parameter */
+    union
+    {
+        /** Signal information for MLAN_OID_GET_SIGNAL */
+        mlan_ds_get_signal signal;
+        /** Statistics information for MLAN_OID_GET_STATS */
+        mlan_ds_get_stats stats;
+        /** Firmware information for MLAN_OID_GET_FW_INFO */
+        mlan_fw_info fw_info;
+        /** Extended version information for MLAN_OID_GET_VER_EXT */
+        mlan_ver_ext ver_ext;
+        /** BSS information for MLAN_OID_GET_BSS_INFO */
+        mlan_bss_info bss_info;
+        /** Debug information for MLAN_OID_GET_DEBUG_INFO */
+        mlan_debug_info debug_info;
+    } param;
+} mlan_ds_get_info, *pmlan_ds_get_info;
+
+/*-----------------------------------------------------------------*/
+/** Security Configuration Group */
+/*-----------------------------------------------------------------*/
+/** Enumeration for authentication mode */
+enum
+{
+    MLAN_AUTH_MODE_OPEN = 0x00,
+    MLAN_AUTH_MODE_SHARED = 0x01,
+    MLAN_AUTH_MODE_NETWORKEAP = 0x80,
+    MLAN_AUTH_MODE_AUTO = 0xFF,
+};
+
+/** Enumeration for encryption mode */
+enum
+{
+    MLAN_ENCRYPTION_MODE_NONE = 0,
+    MLAN_ENCRYPTION_MODE_WEP40 = 1,
+    MLAN_ENCRYPTION_MODE_TKIP = 2,
+    MLAN_ENCRYPTION_MODE_CCMP = 3,
+    MLAN_ENCRYPTION_MODE_WEP104 = 4,
+};
+
+/** Enumeration for PSK */
+enum
+{
+    MLAN_PSK_PASSPHRASE = 1,
+    MLAN_PSK_PMK,
+    MLAN_PSK_CLEAR,
+    MLAN_PSK_QUERY,
+};
+
+/** Maximum key length */
+#define MLAN_MAX_KEY_LENGTH           32
+/** Minimum passphrase length */
+#define MLAN_MIN_PASSPHRASE_LENGTH    8
+/** Maximum passphrase length */
+#define MLAN_MAX_PASSPHRASE_LENGTH    63
+/** Maximum PMK length */
+#define MLAN_MAX_PMK_LENGTH           32
+/* A few details needed for WEP (Wireless Equivalent Privacy) */
+/** 104 bits */
+#define MAX_WEP_KEY_SIZE	13
+/** 40 bits RC4 - WEP */
+#define MIN_WEP_KEY_SIZE	5
+#define PN_SIZE			16
+
+/** Type definition of mlan_ds_encrypt_key for MLAN_OID_SEC_CFG_ENCRYPT_KEY */
+typedef struct _mlan_ds_encrypt_key
+{
+    /** Key disable */
+    t_u32 key_disable;
+    /** Key index */
+    t_u32 key_index;
+    /** Current WEP key flag */
+    t_u32 is_current_wep_key;
+    /** Key length */
+    t_u32 key_len;
+    /** Key */
+    t_u8 key_material[MLAN_MAX_KEY_LENGTH];
+    /** mac address */
+    t_u8 mac_addr[MLAN_MAC_ADDR_LENGTH];
+    /** wapi key flag */
+    t_u32 is_wapi_key;
+    /** Initial packet number */
+    t_u8 pn[PN_SIZE];
+} mlan_ds_encrypt_key, *pmlan_ds_encrypt_key;
+
+/** Type definition of mlan_passphrase_t */
+typedef struct _mlan_passphrase_t
+{
+    /** Length of passphrase */
+    t_u32 passphrase_len;
+    /** Passphrase */
+    t_u8 passphrase[MLAN_MAX_PASSPHRASE_LENGTH];
+} mlan_passphrase_t;
+
+/** Type defnition of mlan_pmk_t */
+typedef struct _mlan_pmk_t
+{
+    /** PMK */
+    t_u8 pmk[MLAN_MAX_PMK_LENGTH];
+} mlan_pmk_t;
+
+/** Type definition of mlan_ds_passphrase for MLAN_OID_SEC_CFG_PASSPHRASE */
+typedef struct _mlan_ds_passphrase
+{
+    /** SSID may be used */
+    mlan_802_11_ssid ssid;
+    /** BSSID may be used */
+    mlan_802_11_mac_addr bssid;
+    /** Flag for passphrase or pmk used */
+    t_u16 psk_type;
+    /** Passphrase or PMK */
+    union
+    {
+        /** Passphrase */
+        mlan_passphrase_t passphrase;
+        /** PMK */
+        mlan_pmk_t pmk;
+    } psk;
+} mlan_ds_passphrase, *pmlan_ds_passphrase;
+
+/** Type definition of mlan_ds_esupp_mode for MLAN_OID_SEC_CFG_ESUPP_MODE */
+typedef struct _mlan_ds_ewpa_mode
+{
+    /** RSN mode */
+    t_u32 rsn_mode;
+    /** Active pairwise cipher */
+    t_u32 act_paircipher;
+    /** Active pairwise cipher */
+    t_u32 act_groupcipher;
+} mlan_ds_esupp_mode, *pmlan_ds_esupp_mode;
+
+/** Type definition of mlan_ds_sec_cfg for MLAN_IOCTL_SEC_CFG */
+typedef struct _mlan_ds_sec_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** Security configuration parameter */
+    union
+    {
+        /** Authentication mode for MLAN_OID_SEC_CFG_AUTH_MODE */
+        t_u32 auth_mode;
+        /** Encryption mode for MLAN_OID_SEC_CFG_ENCRYPT_MODE */
+        t_u32 encrypt_mode;
+        /** WPA enabled flag for MLAN_OID_SEC_CFG_WPA_ENABLED */
+        t_u32 wpa_enabled;
+        /** WAPI enabled flag for MLAN_OID_SEC_CFG_WAPI_ENABLED */
+        t_u32 wapi_enabled;
+        /** Encryption key for MLAN_OID_SEC_CFG_ENCRYPT_KEY */
+        mlan_ds_encrypt_key encrypt_key;
+        /** Passphrase for MLAN_OID_SEC_CFG_PASSPHRASE */
+        mlan_ds_passphrase passphrase;
+        /** Embedded supplicant WPA enabled flag for MLAN_OID_SEC_CFG_EWPA_ENABLED */
+        t_u32 ewpa_enabled;
+        /** Embedded supplicant mode for MLAN_OID_SEC_CFG_ESUPP_MODE */
+        mlan_ds_esupp_mode esupp_mode;
+    } param;
+} mlan_ds_sec_cfg, *pmlan_ds_sec_cfg;
+
+/*-----------------------------------------------------------------*/
+/** Rate Configuration Group */
+/*-----------------------------------------------------------------*/
+/** Max number of supported rates */
+#define MLAN_SUPPORTED_RATES	32
+
+/** Enumeration for rate type */
+enum
+{
+    MLAN_RATE_INDEX,
+    MLAN_RATE_VALUE
+};
+
+/** Type definition of mlan_rate_cfg_t for MLAN_OID_RATE_CFG */
+typedef struct _mlan_rate_cfg_t
+{
+    /** Fixed rate: 0, auto rate: 1 */
+    t_u32 is_rate_auto;
+    /** Rate type */
+    t_u32 rate_type;
+    /** Rate index or rate value if fixed rate */
+    t_u32 rate;
+} mlan_rate_cfg_t;
+
+/** Type definition of mlan_data_rate for MLAN_OID_GET_DATA_RATE */
+typedef struct _mlan_data_rate
+{
+    /** Tx data rate */
+    t_u32 tx_data_rate;
+    /** Rx data rate */
+    t_u32 rx_data_rate;
+} mlan_data_rate;
+
+/** Type definition of mlan_ds_rate for MLAN_IOCTL_RATE */
+typedef struct _mlan_ds_rate
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** Rate configuration parameter */
+    union
+    {
+        /** Rate configuration for MLAN_OID_RATE_CFG */
+        mlan_rate_cfg_t rate_cfg;
+        /** Data rate for MLAN_OID_GET_DATA_RATE */
+        mlan_data_rate data_rate;
+        /** Supported rates for MLAN_OID_SUPPORTED_RATES */
+        t_u8 rates[MLAN_SUPPORTED_RATES];
+    } param;
+} mlan_ds_rate, *pmlan_ds_rate;
+
+/*-----------------------------------------------------------------*/
+/** Power Configuration Group */
+/*-----------------------------------------------------------------*/
+
+/** Type definition of mlan_power_cfg_t for MLAN_OID_POWER_CFG */
+typedef struct _mlan_power_cfg_t
+{
+    /** Is power auto */
+    t_u32 is_power_auto;
+    /** Power level */
+    t_u32 power_level;
+} mlan_power_cfg_t;
+
+/** max power table size */
+#define MAX_POWER_TABLE_SIZE 	128
+
+/** The HT BW40 bit in Tx rate index */
+#define TX_RATE_HT_BW40_BIT 	MBIT(7)
+
+/** Type definition of mlan_power_cfg_ext for MLAN_OID_POWER_CFG_EXT */
+typedef struct _mlan_power_cfg_ext
+{
+    /** Length of power_data */
+    t_u32 len;
+    /** Buffer of power configuration data */
+    t_u32 power_data[MAX_POWER_TABLE_SIZE];
+} mlan_power_cfg_ext;
+
+/** Type definition of mlan_ds_power_cfg for MLAN_IOCTL_POWER_CFG */
+typedef struct _mlan_ds_power_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** Power configuration parameter */
+    union
+    {
+        /** Power configuration for MLAN_OID_POWER_CFG */
+        mlan_power_cfg_t power_cfg;
+        /** Extended power configuration for MLAN_OID_POWER_CFG_EXT */
+        mlan_power_cfg_ext power_ext;
+    } param;
+} mlan_ds_power_cfg, *pmlan_ds_power_cfg;
+
+/*-----------------------------------------------------------------*/
+/** Power Management Configuration Group */
+/*-----------------------------------------------------------------*/
+/** Host sleep config conditions : Cancel */
+#define HOST_SLEEP_CFG_CANCEL   0xffffffff
+
+/** Type definition of mlan_ds_hs_cfg for MLAN_OID_PM_CFG_HS_CFG */
+typedef struct _mlan_ds_hs_cfg
+{
+    /** MTRUE to invoke the HostCmd, MFALSE otherwise */
+    t_u32 is_invoke_hostcmd;
+    /** Host sleep config condition */
+    /** Bit0: non-unicast data
+     *  Bit1: unicast data
+     *  Bit2: mac events
+     *  Bit3: magic packet 
+     */
+    t_u32 conditions;
+    /** GPIO */
+    t_u32 gpio;
+    /** Gap in milliseconds */
+    t_u32 gap;
+} mlan_ds_hs_cfg, *pmlan_ds_hs_cfg;
+
+/** Enable deep sleep mode */
+#define DEEP_SLEEP_ON  1
+/** Disable deep sleep mode */
+#define DEEP_SLEEP_OFF 0
+
+/** Default idle time for auto deep sleep */
+#define DEEP_SLEEP_ILDE_TIME	100
+
+typedef struct _mlan_ds_auto_ds
+{
+    /** auto ds mode, 0 - disable, 1 - enable */
+    t_u16 auto_ds;
+    /** auto ds idle time */
+    t_u16 idletime;
+} mlan_ds_auto_ds;
+
+/** Type definition of mlan_ds_inactivity_to for MLAN_OID_PM_CFG_INACTIVITY_TO */
+typedef struct _mlan_ds_inactivity_to
+{
+    /** Timeout unit in microsecond, 0 means 1000us (1ms) */
+    t_u32 timeout_unit;
+    /** Inactivity timeout for unicast data */
+    t_u32 unicast_timeout;
+    /** Inactivity timeout for multicast data */
+    t_u32 mcast_timeout;
+    /** Timeout for additional Rx traffic after Null PM1 packet exchange */
+    t_u32 ps_entry_timeout;
+} mlan_ds_inactivity_to, *pmlan_ds_inactivity_to;
+
+/** Minimum sleep period */
+#define MIN_SLEEP_PERIOD    10
+/** Maximum sleep period */
+#define MAX_SLEEP_PERIOD    60
+/** Special setting for UPSD certification tests */
+#define SLEEP_PERIOD_RESERVED_FF    0xFF
+
+/** PS null interval disable */
+#define PS_NULL_DISABLE         (-1)
+
+/** Minimum multiple DTIM */
+#define MIN_MULTIPLE_DTIM       0
+/** Maximum multiple DTIM */
+#define MAX_MULTIPLE_DTIM       5
+/** Ignore multiple DTIM */
+#define IGNORE_MULTIPLE_DTIM    65534
+
+/** Minimum listen interval */
+#define MIN_LISTEN_INTERVAL     0
+
+/** Minimum adhoc awake period */
+#define MIN_ADHOC_AWAKE_PD      0
+/** Maximum adhoc awake period */
+#define MAX_ADHOC_AWAKE_PD      31
+/** Special adhoc awake period */
+#define SPECIAL_ADHOC_AWAKE_PD  255
+
+/** Minimum beacon miss timeout */
+#define MIN_BCN_MISS_TO         0
+/** Maximum beacon miss timeout */
+#define MAX_BCN_MISS_TO         50
+/** Disable beacon miss timeout */
+#define DISABLE_BCN_MISS_TO     65535
+
+/** Minimum delay to PS */
+#define MIN_DELAY_TO_PS         0
+/** Maximum delay to PS */
+#define MAX_DELAY_TO_PS         65535
+/* Delay to PS unchanged */
+#define DELAY_TO_PS_UNCHANGED   (-1)
+
+/** PS mode: Unchanged */
+#define PS_MODE_UNCHANGED       0
+/** PS mode: Auto */
+#define PS_MODE_AUTO            1
+/** PS mode: Poll */
+#define PS_MODE_POLL            2
+/** PS mode: Null */
+#define PS_MODE_NULL            3
+
+/** Type definition of mlan_ds_ps_cfg for MLAN_OID_PM_CFG_PS_CFG */
+typedef struct _mlan_ds_ps_cfg
+{
+    /** PS null interval in seconds */
+    t_u32 ps_null_interval;
+    /** Multiple DTIM interval */
+    t_u32 multiple_dtim_interval;
+    /** Listen interval */
+    t_u32 listen_interval;
+    /** Adhoc awake period */
+    t_u32 adhoc_awake_period;
+    /** Beacon miss timeout */
+    t_u32 bcn_miss_timeout;
+    /** Delay to PS */
+    t_s32 delay_to_ps;
+    /** PS mode */ 

+      t_u32 ps_mode;
+} mlan_ds_ps_cfg, *pmlan_ds_ps_cfg;
+
+/** Type definition of mlan_ds_sleep_params for MLAN_OID_PM_CFG_SLEEP_PARAMS */
+typedef struct _mlan_ds_sleep_params
+{
+    /** Error */
+    t_u32 error;
+    /** Offset */
+    t_u32 offset;
+    /** Stable time */
+    t_u32 stable_time;
+    /** Calibration control */
+    t_u32 cal_control;
+    /** External sleep clock */
+    t_u32 ext_sleep_clk;
+    /** Reserved */
+    t_u32 reserved;
+} mlan_ds_sleep_params, *pmlan_ds_sleep_params;
+
+/** Type definition of mlan_ds_pm_cfg for MLAN_IOCTL_PM_CFG */
+typedef struct _mlan_ds_pm_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** Power management parameter */
+    union
+    {
+        /** Power saving mode for MLAN_OID_PM_CFG_IEEE_PS */
+        t_u32 ps_mode;
+        /** Host Sleep configuration for MLAN_OID_PM_CFG_HS_CFG */
+        mlan_ds_hs_cfg hs_cfg;
+        /** Deep sleep mode for MLAN_OID_PM_CFG_DEEP_SLEEP */
+        mlan_ds_auto_ds auto_deep_sleep;
+        /** Inactivity timeout for MLAN_OID_PM_CFG_INACTIVITY_TO */
+        mlan_ds_inactivity_to inactivity_to;
+        /** Sleep period for MLAN_OID_PM_CFG_SLEEP_PD */
+        t_u32 sleep_period;
+        /** PS configuration parameters for MLAN_OID_PM_CFG_PS_CFG */
+        mlan_ds_ps_cfg ps_cfg;
+        /** PS configuration parameters for MLAN_OID_PM_CFG_SLEEP_PARAMS */
+        mlan_ds_sleep_params sleep_params;
+    } param;
+} mlan_ds_pm_cfg, *pmlan_ds_pm_cfg;
+
+/*-----------------------------------------------------------------*/
+/** WMM Configuration Group */
+/*-----------------------------------------------------------------*/
+
+/** WMM TSpec size */
+#define MLAN_WMM_TSPEC_SIZE             63
+/** WMM Add TS extra IE bytes */
+#define MLAN_WMM_ADDTS_EXTRA_IE_BYTES   256
+/** WMM statistics for packets hist bins */
+#define MLAN_WMM_STATS_PKTS_HIST_BINS   7
+/** Maximum number of AC QOS queues available */
+#define MLAN_WMM_MAX_AC_QUEUES          4
+
+/**
+ *  @brief IOCTL structure to send an ADDTS request and retrieve the response.
+ *
+ *  IOCTL structure from the application layer relayed to firmware to 
+ *    instigate an ADDTS management frame with an appropriate TSPEC IE as well
+ *    as any additional IEs appended in the ADDTS Action frame.
+ *
+ *  @sa woal_wmm_addts_req_ioctl
+ */
+typedef struct
+{
+    mlan_cmd_result_e cmd_result;                           /**< Firmware execution result */
+    t_u32 timeout_ms;                                       /**< Timeout value in milliseconds */
+    t_u8 ieee_status_code;                                  /**< IEEE status code */
+    t_u8 tspec_data[MLAN_WMM_TSPEC_SIZE];                   /**< TSPEC to send in the ADDTS */
+    t_u8 addts_extra_ie_buf[MLAN_WMM_ADDTS_EXTRA_IE_BYTES]; /**< ADDTS extra IE buffer */
+} wlan_ioctl_wmm_addts_req_t;
+
+/**
+ *  @brief IOCTL structure to send a DELTS request.
+ *
+ *  IOCTL structure from the application layer relayed to firmware to 
+ *    instigate an DELTS management frame with an appropriate TSPEC IE.
+ *
+ *  @sa woal_wmm_delts_req_ioctl
+ */
+typedef struct
+{
+    mlan_cmd_result_e cmd_result;           /**< Firmware execution result */
+    t_u8 ieee_reason_code;                  /**< IEEE reason code sent, unused for WMM */
+    t_u8 tspec_data[MLAN_WMM_TSPEC_SIZE];   /**< TSPEC to send in the DELTS */
+} wlan_ioctl_wmm_delts_req_t;
+
+/**
+ *  @brief IOCTL structure to configure a specific AC Queue's parameters
+ *
+ *  IOCTL structure from the application layer relayed to firmware to 
+ *    get, set, or default the WMM AC queue parameters.
+ *
+ *  - msdu_lifetime_expiry is ignored if set to 0 on a set command
+ *
+ *  @sa woal_wmm_queue_config_ioctl
+ */
+typedef struct
+{
+    mlan_wmm_queue_config_action_e action;    /**< Set, Get, or Default */
+    mlan_wmm_ac_e access_category;            /**< WMM_AC_BK(0) to WMM_AC_VO(3) */
+    t_u16 msdu_lifetime_expiry;               /**< lifetime expiry in TUs */
+    t_u8 supported_rates[10];                 /**< Not supported yet */
+} wlan_ioctl_wmm_queue_config_t;
+
+/**
+ *  @brief IOCTL structure to start, stop, and get statistics for a WMM AC
+ *
+ *  IOCTL structure from the application layer relayed to firmware to
+ *    start or stop statistical collection for a given AC.  Also used to
+ *    retrieve and clear the collected stats on a given AC.
+ *
+ *  @sa woal_wmm_queue_stats_ioctl
+ */
+typedef struct
+{
+    /** Action of Queue Config : Start, Stop, or Get */
+    mlan_wmm_queue_stats_action_e action;
+    /** WMM Access Category: WMM_AC_BK(0) to WMM_AC_VO(3) */
+    mlan_wmm_ac_e access_category;
+    /** Number of successful packets transmitted */
+    t_u16 pkt_count;
+    /** Packets lost; not included in pkt_count */
+    t_u16 pkt_loss;
+    /** Average Queue delay in microseconds */
+    t_u32 avg_queue_delay;
+    /** Average Transmission delay in microseconds */
+    t_u32 avg_tx_delay;
+    /** Calculated used time in units of 32 microseconds */
+    t_u16 used_time;
+    /** Calculated policed time in units of 32 microseconds */
+    t_u16 policed_time;
+    /** Queue Delay Histogram; number of packets per queue delay range
+     *
+     *  [0] -  0ms <= delay < 5ms
+     *  [1] -  5ms <= delay < 10ms
+     *  [2] - 10ms <= delay < 20ms
+     *  [3] - 20ms <= delay < 30ms
+     *  [4] - 30ms <= delay < 40ms
+     *  [5] - 40ms <= delay < 50ms
+     *  [6] - 50ms <= delay < msduLifetime (TUs)
+     */
+    t_u16 delay_histogram[MLAN_WMM_STATS_PKTS_HIST_BINS];
+} wlan_ioctl_wmm_queue_stats_t,
+/** Type definition of mlan_ds_wmm_queue_stats for MLAN_OID_WMM_CFG_QUEUE_STATS */
+  mlan_ds_wmm_queue_stats, *pmlan_ds_wmm_queue_stats;
+
+/** 
+ *  @brief IOCTL sub structure for a specific WMM AC Status
+ */
+typedef struct
+{
+    /** WMM Acm */
+    t_u8 wmm_acm;
+    /** Flow required flag */
+    t_u8 flow_required;
+    /** Flow created flag */
+    t_u8 flow_created;
+    /** Disabled flag */
+    t_u8 disabled;
+} wlan_ioctl_wmm_queue_status_ac_t;
+
+/**
+ *  @brief IOCTL structure to retrieve the WMM AC Queue status
+ *
+ *  IOCTL structure from the application layer to retrieve:
+ *     - ACM bit setting for the AC
+ *     - Firmware status (flow required, flow created, flow disabled)
+ *
+ *  @sa woal_wmm_queue_status_ioctl
+ */
+typedef struct
+{
+    /** WMM AC queue status */
+    wlan_ioctl_wmm_queue_status_ac_t ac_status[MLAN_WMM_MAX_AC_QUEUES];
+} wlan_ioctl_wmm_queue_status_t,
+/** Type definition of mlan_ds_wmm_queue_status for MLAN_OID_WMM_CFG_QUEUE_STATUS */
+  mlan_ds_wmm_queue_status, *pmlan_ds_wmm_queue_status;
+
+/**
+ *  @brief IOCTL structure for a Traffic stream status.
+ *
+ */
+typedef struct
+{
+    /** TSID: Range: 0->7 */
+    t_u8 tid;
+    /** TSID specified is valid */
+    t_u8 valid;
+    /** AC TSID is active on */
+    t_u8 access_category;
+    /** UP specified for the TSID */
+    t_u8 user_priority;
+    /** Power save mode for TSID: 0 (legacy), 1 (UAPSD) */
+    t_u8 psb;
+    /** Upstream(0), Downlink(1), Bidirectional(3) */
+    t_u8 flow_dir;
+    /** Medium time granted for the TSID */
+    t_u16 medium_time;
+} wlan_ioctl_wmm_ts_status_t,
+/** Type definition of mlan_ds_wmm_ts_status for MLAN_OID_WMM_CFG_TS_STATUS */
+  mlan_ds_wmm_ts_status, *pmlan_ds_wmm_ts_status;
+
+/** Type definition of mlan_ds_wmm_addts for MLAN_OID_WMM_CFG_ADDTS */
+typedef struct _mlan_ds_wmm_addts
+{
+    /** Result of ADDTS request */
+    mlan_cmd_result_e result;
+    /** Timeout value in milliseconds */
+    t_u32 timeout;
+    /** IEEE status code */
+    t_u32 status_code;
+    /** Dialog token */
+    t_u8 dialog_tok;
+    /** TSPEC data length */
+    t_u8 tspec_data_len;
+    /** TSPEC to send in the ADDTS */
+    t_u8 tspec_data[MLAN_WMM_TSPEC_SIZE];
+    /** ADDTS extra IE buffer */
+    t_u8 extra_ie_buf[MLAN_WMM_ADDTS_EXTRA_IE_BYTES];
+} mlan_ds_wmm_addts, *pmlan_ds_wmm_addts;
+
+/** Type definition of mlan_ds_wmm_delts for MLAN_OID_WMM_CFG_DELTS */
+typedef struct _mlan_ds_wmm_delts
+{
+    /** Result of DELTS request */
+    mlan_cmd_result_e result;
+    /** IEEE status code */
+    t_u32 status_code;
+    /** TSPEC data length */
+    t_u8 tspec_data_len;
+    /** TSPEC to send in the DELTS */
+    t_u8 tspec_data[MLAN_WMM_TSPEC_SIZE];
+} mlan_ds_wmm_delts, *pmlan_ds_wmm_delts;
+
+/** Type definition of mlan_ds_wmm_queue_config for MLAN_OID_WMM_CFG_QUEUE_CONFIG */
+typedef struct _mlan_ds_wmm_queue_config
+{
+    /** Action of Queue Config : Set, Get, or Default */
+    mlan_wmm_queue_config_action_e action;
+    /** WMM Access Category: WMM_AC_BK(0) to WMM_AC_VO(3) */
+    mlan_wmm_ac_e access_category;
+    /** Lifetime expiry in TUs */
+    t_u16 msdu_lifetime_expiry;
+    /** Reserve for future use */
+    t_u8 reserved[10];
+} mlan_ds_wmm_queue_config, *pmlan_ds_wmm_queue_config;
+
+/** Type definition of mlan_ds_wmm_cfg for MLAN_IOCTL_WMM_CFG */
+typedef struct _mlan_ds_wmm_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** WMM configuration parameter */
+    union
+    {
+        /** WMM enable for MLAN_OID_WMM_CFG_ENABLE */
+        t_u32 wmm_enable;
+        /** QoS configuration for MLAN_OID_WMM_CFG_QOS */
+        t_u8 qos_cfg;
+        /** Set/get tid multi-port eligibility table for MLAN_OID_TID_ELIG_TBL */
+        t_u32 tid_tbl[MAX_NUM_TID];
+        /** WMM add TS for MLAN_OID_WMM_CFG_ADDTS */
+        mlan_ds_wmm_addts addts;
+        /** WMM delete TS for MLAN_OID_WMM_CFG_DELTS */
+        mlan_ds_wmm_delts delts;
+        /** WMM queue configuration for MLAN_OID_WMM_CFG_QUEUE_CONFIG */
+        mlan_ds_wmm_queue_config q_cfg;
+        /** WMM queue status for MLAN_OID_WMM_CFG_QUEUE_STATS */
+        mlan_ds_wmm_queue_stats q_stats;
+        /** WMM queue status for MLAN_OID_WMM_CFG_QUEUE_STATUS */
+        mlan_ds_wmm_queue_status q_status;
+        /** WMM TS status for MLAN_OID_WMM_CFG_TS_STATUS */
+        mlan_ds_wmm_ts_status ts_status;
+    } param;
+} mlan_ds_wmm_cfg, *pmlan_ds_wmm_cfg;
+
+/*-----------------------------------------------------------------*/
+/** WPS Configuration Group */
+/*-----------------------------------------------------------------*/
+/** Enumeration for WPS session */
+enum
+{
+    MLAN_WPS_CFG_SESSION_START = 1,
+    MLAN_WPS_CFG_SESSION_END = 0
+};
+
+/** Type definition of mlan_ds_wps_cfg for MLAN_IOCTL_WPS_CFG */
+typedef struct _mlan_ds_wps_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** WPS configuration parameter */
+    union
+    {
+        /** WPS session for MLAN_OID_WPS_CFG_SESSION */
+        t_u32 wps_session;
+    } param;
+} mlan_ds_wps_cfg, *pmlan_ds_wps_cfg;
+
+/*-----------------------------------------------------------------*/
+/** 802.11n Configuration Group */
+/*-----------------------------------------------------------------*/
+/** Type definition of mlan_ds_11n_addba_param for MLAN_OID_11N_CFG_ADDBA_PARAM */
+typedef struct _mlan_ds_11n_addba_param
+{
+    /** Timeout */
+    t_u32 timeout;
+    /** Buffer size for ADDBA request */
+    t_u32 txwinsize;
+    /** Buffer size for ADDBA response */
+    t_u32 rxwinsize;
+} mlan_ds_11n_addba_param, *pmlan_ds_11n_addba_param;
+
+/** Type definition of mlan_ds_11n_tx_cfg for MLAN_OID_11N_CFG_TX */
+typedef struct _mlan_ds_11n_tx_cfg
+{
+    /** HTTxCap */
+    t_u16 httxcap;
+    /** HTTxInfo */
+    t_u16 httxinfo;
+} mlan_ds_11n_tx_cfg, *pmlan_ds_11n_tx_cfg;
+
+/** Type definition of mlan_ds_11n_amsdu_aggr_ctrl for 
+ * MLAN_OID_11N_AMSDU_AGGR_CTRL*/
+typedef struct _mlan_ds_11n_amsdu_aggr_ctrl
+{
+    /** Enable/Disable */
+    t_u16 enable;
+    /** Current AMSDU size valid */
+    t_u16 curr_buf_size;
+} mlan_ds_11n_amsdu_aggr_ctrl, *pmlan_ds_11n_amsdu_aggr_ctrl;
+
+/** Type definition of mlan_ds_11n_aggr_prio_tbl for MLAN_OID_11N_CFG_AGGR_PRIO_TBL */
+typedef struct _mlan_ds_11n_aggr_prio_tbl
+{
+    /** ampdu priority table */
+    t_u8 ampdu[MAX_NUM_TID];
+    /** amsdu priority table */
+    t_u8 amsdu[MAX_NUM_TID];
+} mlan_ds_11n_aggr_prio_tbl, *pmlan_ds_11n_aggr_prio_tbl;
+
+/** Type definition of mlan_ds_11n_cfg for MLAN_IOCTL_11N_CFG */
+typedef struct _mlan_ds_11n_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** 802.11n configuration parameter */
+    union
+    {
+        /** Tx param for 11n for MLAN_OID_11N_CFG_TX */
+        mlan_ds_11n_tx_cfg tx_cfg;
+        /** Aggr priority table for MLAN_OID_11N_CFG_AGGR_PRIO_TBL */
+        mlan_ds_11n_aggr_prio_tbl aggr_prio_tbl;
+        /** Add BA param for MLAN_OID_11N_CFG_ADDBA_PARAM */
+        mlan_ds_11n_addba_param addba_param;
+        /** Add BA Reject paramters for MLAN_OID_11N_CFG_ADDBA_REJECT */
+        t_u8 addba_reject[MAX_NUM_TID];
+        /** Tx buf size for MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE */
+        t_u32 tx_buf_size;
+        /** HT cap info configuration for MLAN_OID_11N_HTCAP_CFG */
+        t_u32 htcap_cfg;
+        /** Tx param for 11n for MLAN_OID_11N_AMSDU_AGGR_CTRL */
+        mlan_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
+    } param;
+} mlan_ds_11n_cfg, *pmlan_ds_11n_cfg;
+
+/*-----------------------------------------------------------------*/
+/** 802.11d Configuration Group */
+/*-----------------------------------------------------------------*/
+/** Type definition of mlan_ds_11d_cfg for MLAN_IOCTL_11D_CFG */
+typedef struct _mlan_ds_11d_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** 802.11d configuration parameter */
+    union
+    {
+        /** Enable for MLAN_OID_11D_CFG_ENABLE */
+        t_u32 enable_11d;
+    } param;
+} mlan_ds_11d_cfg, *pmlan_ds_11d_cfg;
+
+/*-----------------------------------------------------------------*/
+/** Register Memory Access Group */
+/*-----------------------------------------------------------------*/
+/** Enumeration for register type */
+enum
+{
+    MLAN_REG_MAC = 1,
+    MLAN_REG_BBP,
+    MLAN_REG_RF,
+    MLAN_REG_PMIC,
+    MLAN_REG_CAU,
+};
+
+/** Type definition of mlan_ds_reg_rw for MLAN_OID_REG_RW */
+typedef struct _mlan_ds_reg_rw
+{
+    /** Register type */
+    t_u32 type;
+    /** Offset */
+    t_u32 offset;
+    /** Value */
+    t_u32 value;
+} mlan_ds_reg_rw;
+
+/** Maximum EEPROM data */
+#define MAX_EEPROM_DATA 256
+
+/** Type definition of mlan_ds_read_eeprom for MLAN_OID_EEPROM_RD */
+typedef struct _mlan_ds_read_eeprom
+{
+    /** Multiples of 4 */
+    t_u16 offset;
+    /** Number of bytes */
+    t_u16 byte_count;
+    /** Value */
+    t_u8 value[MAX_EEPROM_DATA];
+} mlan_ds_read_eeprom;
+
+/** Type definition of mlan_ds_mem_rw for MLAN_OID_MEM_RW */
+typedef struct _mlan_ds_mem_rw
+{
+    /** Address */
+    t_u32 addr;
+    /** Value */
+    t_u32 value;
+} mlan_ds_mem_rw;
+
+/** Type definition of mlan_ds_reg_mem for MLAN_IOCTL_REG_MEM */
+typedef struct _mlan_ds_reg_mem
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** Register memory access parameter */
+    union
+    {
+        /** Register access for MLAN_OID_REG_RW */
+        mlan_ds_reg_rw reg_rw;
+        /** EEPROM access for MLAN_OID_EEPROM_RD */
+        mlan_ds_read_eeprom rd_eeprom;
+        /** Memory access for MLAN_OID_MEM_RW */
+        mlan_ds_mem_rw mem_rw;
+    } param;
+} mlan_ds_reg_mem, *pmlan_ds_reg_mem;
+
+/*-----------------------------------------------------------------*/
+/** BCA Configuration Group */
+/*-----------------------------------------------------------------*/
+/** BCA Traffic type low */
+#define TRAFFIC_TYPE_LOW        0x0
+/** BCA Traffic type high */
+#define TRAFFIC_TYPE_HIGH       0x1
+/** BCA Traffic type medium */
+#define TRAFFIC_TYPE_MEDIUM     0x02
+/** BCA Traffic type medium high */
+#define TRAFFIC_TYPE_MEDIUMHIGH 0x03
+/** BCA Reset Traffic type */
+#define TRAFFIC_TYPE_RESET      0xffff
+/** BCA Minimum Timeshare interval value */
+#define MIN_TIMESHARE_INTERVAL  20
+/** BCA Maximum Timeshare interval value */
+#define MAX_TIMESHARE_INTERVAL  60000
+
+/** Type definition of mlan_ds_bca_ts for MLAN_OID_BCA_TS */
+typedef struct _mlan_ds_bca_ts
+{
+    /** Type: WLAN, BT */
+    t_u32 traffic_type;
+    /** Interval: 20msec - 60000msec */
+    t_u32 timeshare_interval;
+    /** PTA arbiter time in msec */
+    t_u32 bt_time;
+} mlan_ds_bca_ts;
+
+/** Type definition of mlan_ds_bca_cfg for MLAN_IOCTL_BCA_CFG */
+typedef struct _mlan_ds_bca_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** BCA parameters */
+    union
+    {
+        /** BCS time share for MLAN_OID_BCA_TS */
+        mlan_ds_bca_ts bca_ts;
+    } param;
+} mlan_ds_bca_cfg, *pmlan_ds_bca_cfg;
+
+/*-----------------------------------------------------------------*/
+/** Miscellaneous Configuration Group */
+/*-----------------------------------------------------------------*/
+
+/** CMD buffer size */
+#define MLAN_SIZE_OF_CMD_BUFFER 2048
+
+/** LDO Internal */
+#define LDO_INTERNAL            0
+/** LDO External */
+#define LDO_EXTERNAL            1
+
+/** Enumeration for IE type */
+enum
+{
+    MLAN_IE_TYPE_GEN_IE = 0,
+    MLAN_IE_TYPE_ARP_FILTER,
+};
+
+/** Type definition of mlan_ds_misc_gen_ie for MLAN_OID_MISC_GEN_IE */
+typedef struct _mlan_ds_misc_gen_ie
+{
+    /** IE type */
+    t_u32 type;
+    /** IE length */
+    t_u32 len;
+    /** IE buffer */
+    t_u8 ie_data[MAX_IE_SIZE];
+} mlan_ds_misc_gen_ie;
+
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+/** Type definition of mlan_ds_misc_sdio_mpa_ctrl for MLAN_OID_MISC_SDIO_MPA_CTRL */
+typedef struct _mlan_ds_misc_sdio_mpa_ctrl
+{
+    /** SDIO MP-A TX enable/disable */
+    t_u16 tx_enable;
+    /** SDIO MP-A RX enable/disable */
+    t_u16 rx_enable;
+    /** SDIO MP-A TX buf size */
+    t_u16 tx_buf_size;
+    /** SDIO MP-A RX buf size */
+    t_u16 rx_buf_size;
+    /** SDIO MP-A TX Max Ports */
+    t_u16 tx_max_ports;
+    /** SDIO MP-A RX Max Ports */
+    t_u16 rx_max_ports;
+} mlan_ds_misc_sdio_mpa_ctrl;
+#endif
+
+/** Type definition of mlan_ds_misc_cmd for MLAN_OID_MISC_HOST_CMD */
+typedef struct _mlan_ds_misc_cmd
+{
+    /** Command length */
+    t_u32 len;
+    /** Command buffer */
+    t_u8 cmd[MLAN_SIZE_OF_CMD_BUFFER];
+} mlan_ds_misc_cmd;
+
+/** Maximum number of system clocks */
+#define MLAN_MAX_CLK_NUM     	16
+
+/** Clock type : Configurable */
+#define MLAN_CLK_CONFIGURABLE	0
+/** Clock type : Supported */
+#define MLAN_CLK_SUPPORTED   	1
+
+/** Type definition of mlan_ds_misc_sys_clock for MLAN_OID_MISC_SYS_CLOCK */
+typedef struct _mlan_ds_misc_sys_clock
+{
+    /** Current system clock */
+    t_u16 cur_sys_clk;
+    /** Clock type */
+    t_u16 sys_clk_type;
+    /** Number of clocks */
+    t_u16 sys_clk_num;
+    /** System clocks */
+    t_u16 sys_clk[MLAN_MAX_CLK_NUM];
+} mlan_ds_misc_sys_clock;
+
+/** Maximum length of Vendor specific IE */
+#define MLAN_MAX_VSIE_LEN       (256)
+/** Maximum number of Vendor specific IE */
+#define MLAN_MAX_VSIE_NUM       (8)
+/** VSIE bit mask for scan */
+#define MLAN_VSIE_MASK_SCAN     0x01
+/** VSIE bit mask for associate */
+#define MLAN_VSIE_MASK_ASSOC    0x02
+/** VSIE bit mask for adhoc */
+#define MLAN_VSIE_MASK_ADHOC    0x04
+
+/** Type definition of mlan_ds_misc_vs_ie for MLAN_OID_MISC_VS_IE */
+typedef struct _mlan_ds_misc_vs_ie
+{
+    /** Position in the vendor specific IE array */
+    t_u32 id;
+    /** Bit 0-2: scan/assoc/ad-hoc */
+    t_u32 mask;
+    /** Information element */
+    t_u8 ie[MLAN_MAX_VSIE_LEN];
+} mlan_ds_misc_vs_ie;
+
+/** Enumeration for function init/shutdown */
+enum
+{
+    MLAN_FUNC_INIT = 1,
+    MLAN_FUNC_SHUTDOWN,
+};
+
+/** Type definition of mlan_ds_misc_cfg for MLAN_IOCTL_MISC_CFG */
+typedef struct _mlan_ds_misc_cfg
+{
+    /** Sub-command */
+    t_u32 sub_command;
+    /** Miscellaneous configuration parameter */
+    union
+    {
+        /** Generic IE for MLAN_OID_MISC_GEN_IE */
+        mlan_ds_misc_gen_ie gen_ie;
+        /** Region code for MLAN_OID_MISC_REGION */
+        t_u32 region_code;
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+        /** SDIO MP-A Ctrl command for MLAN_OID_MISC_SDIO_MPA_CTRL */
+        mlan_ds_misc_sdio_mpa_ctrl mpa_ctrl;
+#endif
+#ifdef MFG_CMD_SUPPORT
+        /** Mfg command for MLAN_OID_MISC_MFG_CMD */
+        mlan_ds_misc_cmd mfgcmd;
+#endif
+        /** Hostcmd for MLAN_OID_MISC_HOST_CMD */
+        mlan_ds_misc_cmd hostcmd;
+        /** LDO configuration for MLAN_OID_MISC_LDO */
+        t_u16 ldo_cfg;
+        /** System clock for MLAN_OID_MISC_SYS_CLOCK */
+        mlan_ds_misc_sys_clock sys_clock;
+        /** WWS set/get for MLAN_OID_MISC_WWS */
+        t_u32 wws_cfg;
+        /** Get/add/delete VSIE for MLAN_OID_MISC_VS_IE */
+        mlan_ds_misc_vs_ie vsie;
+        /** Function init/shutdown for MLAN_OID_MISC_INIT_SHUTDOWN */
+        t_u32 func_init_shutdown;
+    } param;
+} mlan_ds_misc_cfg, *pmlan_ds_misc_cfg;
+
+#endif /* !_MLAN_IOCTL_H_ */
diff --git a/wlan_src/mlan/mlan_join.c b/wlan_src/mlan/mlan_join.c
new file mode 100755
index 0000000..bd503a9
--- /dev/null
+++ b/wlan_src/mlan/mlan_join.c
@@ -0,0 +1,1740 @@
+/** @file mlan_join.c
+ *
+ *  @brief Functions implementing wlan infrastructure and adhoc join routines
+ *
+ *  IOCTL handlers as well as command preparation and response routines
+ *  for sending adhoc start, adhoc join, and association commands
+ *  to the firmware.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ *
+ *  @sa mlan_join.h
+ */
+
+/******************************************************
+Change log:
+    10/30/2008: initial version
+******************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_11h.h"
+
+/********************************************************
+                Local Constants
+********************************************************/
+
+/********************************************************
+                Local Variables
+********************************************************/
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+/**
+ *  @brief Append a generic IE as a pass through TLV to a TLV buffer.
+ *
+ *  This function is called from the network join command prep. routine. 
+ *    If the IE buffer has been setup by the application, this routine appends
+ *    the buffer as a pass through TLV type to the request.
+ *
+ *  @param priv     A pointer to mlan_private structure
+ *  @param ppbuffer pointer to command buffer pointer
+ *
+ *  @return         bytes added to the buffer
+ */
+static int
+wlan_cmd_append_generic_ie(mlan_private * priv, t_u8 ** ppbuffer)
+{
+    int ret_len = 0;
+    MrvlIEtypesHeader_t ie_header;
+
+    /* Null Checks */
+    if (!ppbuffer)
+        return 0;
+    if (!(*ppbuffer))
+        return 0;
+
+    /* 
+     * If there is a generic ie buffer setup, append it to the return
+     *   parameter buffer pointer.
+     */
+    if (priv->gen_ie_buf_len) {
+        PRINTM(MINFO, "append generic %d to %p\n", priv->gen_ie_buf_len,
+               *ppbuffer);
+
+        /* Wrap the generic IE buffer with a pass through TLV type */
+        ie_header.type = wlan_cpu_to_le16(TLV_TYPE_PASSTHROUGH);
+        ie_header.len = wlan_cpu_to_le16(priv->gen_ie_buf_len);
+        memcpy(*ppbuffer, &ie_header, sizeof(ie_header));
+
+        /* Increment the return size and the return buffer pointer param */
+        *ppbuffer += sizeof(ie_header);
+        ret_len += sizeof(ie_header);
+
+        /* Copy the generic IE buffer to the output buffer, advance pointer */
+        memcpy(*ppbuffer, priv->gen_ie_buf, priv->gen_ie_buf_len);
+
+        /* Increment the return size and the return buffer pointer param */
+        *ppbuffer += priv->gen_ie_buf_len;
+        ret_len += priv->gen_ie_buf_len;
+
+        /* Reset the generic IE buffer */
+        priv->gen_ie_buf_len = 0;
+    }
+
+    /* return the length appended to the buffer */
+    return ret_len;
+}
+
+/**
+  *  @brief Append TSF tracking info from the scan table for the target AP
+  *  
+  *  This function is called from the network join command prep. routine. 
+  *     The TSF table TSF sent to the firmware contains two TSF values:
+  *        - the TSF of the target AP from its previous beacon/probe response
+  *        - the TSF timestamp of our local MAC at the time we observed the
+  *          beacon/probe response.
+  *  
+  *     The firmware uses the timestamp values to set an initial TSF value
+  *        in the MAC for the new association after a reassociation attempt.
+  *  
+  *    @param pmpriv     A pointer to mlan_private structure
+  *    @param ppbuffer   A pointer to command buffer pointer
+  *    @param pbss_desc  A pointer to the BSS Descriptor from the scan table of
+  *                      the AP we are trying to join
+  *  
+  *    @return         bytes added to the buffer
+  */
+static int
+wlan_cmd_append_tsf_tlv(mlan_private * pmriv, t_u8 ** ppbuffer,
+                        BSSDescriptor_t * pbss_desc)
+{
+    MrvlIEtypes_TsfTimestamp_t tsf_tlv;
+    t_u64 tsf_val;
+
+    /* Null Checks */
+    if (ppbuffer == 0)
+        return 0;
+    if (*ppbuffer == 0)
+        return 0;
+
+    memset(&tsf_tlv, 0x00, sizeof(MrvlIEtypes_TsfTimestamp_t));
+
+    tsf_tlv.header.type = wlan_cpu_to_le16(TLV_TYPE_TSFTIMESTAMP);
+    tsf_tlv.header.len = wlan_cpu_to_le16(2 * sizeof(tsf_val));
+
+    memcpy(*ppbuffer, &tsf_tlv, sizeof(tsf_tlv.header));
+    *ppbuffer += sizeof(tsf_tlv.header);
+
+    /* TSF timestamp from the firmware TSF when the bcn/prb rsp was received */
+    tsf_val = wlan_cpu_to_le64(pbss_desc->network_tsf);
+    memcpy(*ppbuffer, &tsf_val, sizeof(tsf_val));
+    *ppbuffer += sizeof(tsf_val);
+
+    memcpy(&tsf_val, pbss_desc->time_stamp, sizeof(tsf_val));
+
+    PRINTM(MINFO, "ASSOC: TSF offset calc: %016llx - %016llx\n",
+           tsf_val, pbss_desc->network_tsf);
+
+    memcpy(*ppbuffer, &tsf_val, sizeof(tsf_val));
+    *ppbuffer += sizeof(tsf_val);
+
+    return (sizeof(tsf_tlv.header) + (2 * sizeof(tsf_val)));
+}
+
+/**
+ *  @brief This function finds out the common rates between rate1 and rate2.
+ *
+ *  It will fill common rates in rate1 as output if found.
+ *
+ *  NOTE: Setting the MSB of the basic rates needs to be taken
+ *   care of, either before or after calling this function
+ *
+ *  @param pmpriv      A pointer to mlan_private structure
+ *  @param rate1       the buffer which keeps input and output
+ *  @param rate1_size  the size of rate1 buffer
+ *  @param rate2       the buffer which keeps rate2
+ *  @param rate2_size  the size of rate2 buffer.
+ *
+ *  @return            MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_get_common_rates(IN mlan_private * pmpriv,
+                      IN t_u8 * rate1,
+                      IN t_u32 rate1_size, IN t_u8 * rate2, IN t_u32 rate2_size)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmpriv->adapter->callbacks;
+    t_u8 *ptr = rate1;
+    t_u8 *tmp = MNULL;
+    t_u32 i, j;
+
+    ENTER();
+
+    ret = pcb->moal_malloc(rate1_size, &tmp);
+    if (ret != MLAN_STATUS_SUCCESS || !tmp) {
+        PRINTM(MERROR, "Failed to allocate buffer\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    memcpy(tmp, rate1, rate1_size);
+    memset(rate1, 0, rate1_size);
+
+    for (i = 0; rate2[i] && i < rate2_size; i++) {
+        for (j = 0; tmp[j] && j < rate1_size; j++) {
+            /* Check common rate, excluding the bit for basic rate */
+            if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) {
+                *rate1++ = tmp[j];
+                break;
+            }
+        }
+    }
+
+    HEXDUMP("rate1 (AP) Rates", tmp, rate1_size);
+    HEXDUMP("rate2 (Card) Rates", rate2, rate2_size);
+    HEXDUMP("Common Rates", ptr, rate1 - ptr);
+    PRINTM(MINFO, "Tx DataRate is set to 0x%X\n", pmpriv->data_rate);
+
+    if (!pmpriv->is_data_rate_auto) {
+        while (*ptr) {
+            if ((*ptr & 0x7f) == pmpriv->data_rate) {
+                ret = MLAN_STATUS_SUCCESS;
+                goto done;
+            }
+            ptr++;
+        }
+        PRINTM(MMSG, "Previously set fixed data rate %#x is not "
+               "compatible with the network\n", pmpriv->data_rate);
+
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    ret = MLAN_STATUS_SUCCESS;
+  done:
+    if (tmp)
+        pcb->moal_mfree(tmp);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Create the intersection of the rates supported by a target BSS and
+ *         our pmadapter settings for use in an assoc/join command.
+ *
+ *  @param pmpriv           A pointer to mlan_private structure
+ *  @param pbss_desc        BSS Descriptor whose rates are used in the setup
+ *  @param pout_rates       Output: Octet array of rates common between the BSS
+ *                          and the pmadapter supported rates settings
+ *  @param pout_rates_size  Output: Number of rates/octets set in pout_rates
+ *
+ *  @return                 MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_setup_rates_from_bssdesc(IN mlan_private * pmpriv,
+                              IN BSSDescriptor_t * pbss_desc,
+                              OUT t_u8 * pout_rates,
+                              OUT t_u32 * pout_rates_size)
+{
+    t_u8 card_rates[WLAN_SUPPORTED_RATES];
+    t_u32 card_rates_size = 0;
+    ENTER();
+    /* Copy AP supported rates */
+    memcpy(pout_rates, pbss_desc->supported_rates, WLAN_SUPPORTED_RATES);
+    /* Get the STA supported rates */
+    card_rates_size = wlan_get_active_data_rates(pmpriv, card_rates);
+    /* Get the common rates between AP and STA supported rates */
+    if (wlan_get_common_rates(pmpriv, pout_rates, WLAN_SUPPORTED_RATES,
+                              card_rates, card_rates_size)) {
+        *pout_rates_size = 0;
+        PRINTM(MERROR, "wlan_get_common_rates failed\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    *pout_rates_size =
+        MIN(wlan_strlen((char *) pout_rates), WLAN_SUPPORTED_RATES);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Update the scan entry TSF timestamps to reflect a new association
+ *
+ *  @param pmpriv        A pointer to mlan_private structure
+ *  @param pnew_bss_desc A pointer to the newly associated AP's scan table entry
+ *
+ *  @return              N/A
+ */
+static t_void
+wlan_update_tsf_timestamps(IN mlan_private * pmpriv,
+                           IN BSSDescriptor_t * pnew_bss_desc)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    t_u32 table_idx;
+    t_u64 new_tsf_base;
+    t_s64 tsf_delta;
+
+    ENTER();
+
+    memcpy(&new_tsf_base, pnew_bss_desc->time_stamp, sizeof(new_tsf_base));
+
+    tsf_delta = new_tsf_base - pnew_bss_desc->network_tsf;
+
+    PRINTM(MINFO, "TSF: Update TSF timestamps, 0x%016llx -> 0x%016llx\n",
+           pnew_bss_desc->network_tsf, new_tsf_base);
+
+    for (table_idx = 0; table_idx < pmadapter->num_in_scan_table; table_idx++) {
+        pmadapter->pscan_table[table_idx].network_tsf += tsf_delta;
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Append a wapi IE 
+ *
+ *  This function is called from the network join command prep. routine. 
+ *    If the IE buffer has been setup by the application, this routine appends
+ *    the buffer as a wapi TLV type to the request.
+ *
+ *  @param priv     A pointer to mlan_private structure
+ *  @param ppBuffer pointer to command buffer pointer
+ *
+ *  @return         bytes added to the buffer
+ */
+static int
+wlan_cmd_append_wapi_ie(mlan_private * priv, t_u8 ** ppBuffer)
+{
+    int retLen = 0;
+    MrvlIEtypesHeader_t ie_header;
+
+    /* Null Checks */
+    if (ppBuffer == 0)
+        return 0;
+    if (*ppBuffer == 0)
+        return 0;
+
+    /* 
+     * If there is a wapi ie buffer setup, append it to the return
+     *   parameter buffer pointer.
+     */
+    if (priv->wapi_ie_len) {
+        PRINTM(MCMND, "append wapi ie %d to %p\n", priv->wapi_ie_len,
+               *ppBuffer);
+
+        /* Wrap the generic IE buffer with a pass through TLV type */
+        ie_header.type = wlan_cpu_to_le16(TLV_TYPE_WAPI_IE);
+        ie_header.len = wlan_cpu_to_le16(priv->wapi_ie_len);
+        memcpy(*ppBuffer, &ie_header, sizeof(ie_header));
+
+        /* Increment the return size and the return buffer pointer param */
+        *ppBuffer += sizeof(ie_header);
+        retLen += sizeof(ie_header);
+
+        /* Copy the wapi IE buffer to the output buffer, advance pointer */
+        memcpy(*ppBuffer, priv->wapi_ie, priv->wapi_ie_len);
+
+        /* Increment the return size and the return buffer pointer param */
+        *ppBuffer += priv->wapi_ie_len;
+        retLen += priv->wapi_ie_len;
+
+    }
+    /* return the length appended to the buffer */
+    return retLen;
+}
+
+/********************************************************
+                Global Functions
+********************************************************/
+/**
+ *  @brief This function prepares command of association.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf    A pointer cast of BSSDescriptor_t from the 
+ *                        scan table to assoc
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_802_11_associate(IN mlan_private * pmpriv,
+                          IN HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    HostCmd_DS_802_11_ASSOCIATE *passo = &cmd->params.associate;
+    BSSDescriptor_t *pbss_desc;
+    MrvlIEtypes_SsIdParamSet_t *pssid_tlv;
+    MrvlIEtypes_PhyParamSet_t *pphy_tlv;
+    MrvlIEtypes_SsParamSet_t *pss_tlv;
+    MrvlIEtypes_RatesParamSet_t *prates_tlv;
+    MrvlIEtypes_AuthType_t *pauth_tlv;
+    MrvlIEtypes_RsnParamSet_t *prsn_ie_tlv;
+    MrvlIEtypes_ChanListParamSet_t *pchan_tlv;
+    WLAN_802_11_RATES rates;
+    t_u32 rates_size;
+    t_u16 tmp_cap;
+    t_u8 *pos;
+
+    ENTER();
+
+    pbss_desc = (BSSDescriptor_t *) pdata_buf;
+    pos = (t_u8 *) passo;
+
+    wlan_cfg_tx_buf(pmpriv, pbss_desc);
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE);
+
+    /* Save so we know which BSS Desc to use in the response handler */
+    pmpriv->pattempted_bss_desc = pbss_desc;
+
+    memcpy(passo->peer_sta_addr,
+           pbss_desc->mac_address, sizeof(passo->peer_sta_addr));
+    pos += sizeof(passo->peer_sta_addr);
+
+    /* Set the listen interval */
+    passo->listen_interval = wlan_cpu_to_le16(pmpriv->listen_interval);
+    /* Set the beacon period */
+    passo->beacon_period = wlan_cpu_to_le16(pbss_desc->beacon_period);
+
+    pos += sizeof(passo->cap_info);
+    pos += sizeof(passo->listen_interval);
+    pos += sizeof(passo->beacon_period);
+    pos += sizeof(passo->dtim_period);
+
+    pssid_tlv = (MrvlIEtypes_SsIdParamSet_t *) pos;
+    pssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID);
+    pssid_tlv->header.len = (t_u16) pbss_desc->ssid.ssid_len;
+    memcpy(pssid_tlv->ssid, pbss_desc->ssid.ssid, pssid_tlv->header.len);
+    pos += sizeof(pssid_tlv->header) + pssid_tlv->header.len;
+    pssid_tlv->header.len = wlan_cpu_to_le16(pssid_tlv->header.len);
+
+    pphy_tlv = (MrvlIEtypes_PhyParamSet_t *) pos;
+    pphy_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_PHY_DS);
+    pphy_tlv->header.len = sizeof(pphy_tlv->fh_ds.ds_param_set);
+    memcpy(&pphy_tlv->fh_ds.ds_param_set,
+           &pbss_desc->phy_param_set.ds_param_set.current_chan,
+           sizeof(pphy_tlv->fh_ds.ds_param_set));
+    pos += sizeof(pphy_tlv->header) + pphy_tlv->header.len;
+    pphy_tlv->header.len = wlan_cpu_to_le16(pphy_tlv->header.len);
+
+    pss_tlv = (MrvlIEtypes_SsParamSet_t *) pos;
+    pss_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_CF);
+    pss_tlv->header.len = sizeof(pss_tlv->cf_ibss.cf_param_set);
+    pos += sizeof(pss_tlv->header) + pss_tlv->header.len;
+    pss_tlv->header.len = wlan_cpu_to_le16(pss_tlv->header.len);
+
+    /* Get the common rates supported between the driver and the BSS Desc */
+    if (wlan_setup_rates_from_bssdesc(pmpriv, pbss_desc, rates, &rates_size)) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Save the data rates into Current BSS state structure */
+    pmpriv->curr_bss_params.num_of_rates = rates_size;
+    memcpy(&pmpriv->curr_bss_params.data_rates, rates, rates_size);
+
+    /* Setup the Rates TLV in the association command */
+    prates_tlv = (MrvlIEtypes_RatesParamSet_t *) pos;
+    prates_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_RATES);
+    prates_tlv->header.len = wlan_cpu_to_le16((t_u16) rates_size);
+    memcpy(prates_tlv->rates, rates, rates_size);
+    pos += sizeof(prates_tlv->header) + rates_size;
+    PRINTM(MINFO, "ASSOC_CMD: Rates size = %d\n", rates_size);
+
+    /* Add the Authentication type to be used for Auth frames if needed */
+    if (pmpriv->sec_info.authentication_mode != MLAN_AUTH_MODE_AUTO) {
+        pauth_tlv = (MrvlIEtypes_AuthType_t *) pos;
+        pauth_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_AUTH_TYPE);
+        pauth_tlv->header.len = sizeof(pauth_tlv->auth_type);
+        if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)
+            pauth_tlv->auth_type =
+                wlan_cpu_to_le16((t_u16) pmpriv->sec_info.authentication_mode);
+        else
+            pauth_tlv->auth_type = wlan_cpu_to_le16(MLAN_AUTH_MODE_OPEN);
+        pos += sizeof(pauth_tlv->header) + pauth_tlv->header.len;
+        pauth_tlv->header.len = wlan_cpu_to_le16(pauth_tlv->header.len);
+    }
+
+    if (IS_SUPPORT_MULTI_BANDS(pmpriv->adapter)
+        && !(ISSUPP_11NENABLED(pmpriv->adapter->fw_cap_info)
+             && (pmpriv->adapter->config_bands & BAND_GN
+                 || pmpriv->adapter->config_bands & BAND_AN)
+             && (pbss_desc->pht_cap)
+        )
+        ) {
+        /* Append a channel TLV for the channel the attempted AP was found on */
+        pchan_tlv = (MrvlIEtypes_ChanListParamSet_t *) pos;
+        pchan_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
+        pchan_tlv->header.len = wlan_cpu_to_le16(sizeof(ChanScanParamSet_t));
+
+        memset(pchan_tlv->chan_scan_param, 0x00, sizeof(ChanScanParamSet_t));
+        pchan_tlv->chan_scan_param[0].chan_number =
+            (pbss_desc->phy_param_set.ds_param_set.current_chan);
+        PRINTM(MINFO, "Assoc: TLV Chan = %d\n",
+               pchan_tlv->chan_scan_param[0].chan_number);
+
+        pchan_tlv->chan_scan_param[0].radio_type =
+            wlan_band_to_radio_type((t_u8) pbss_desc->bss_band);
+
+        PRINTM(MINFO, "Assoc: TLV Band = %d\n",
+               pchan_tlv->chan_scan_param[0].radio_type);
+        pos += sizeof(pchan_tlv->header) + sizeof(ChanScanParamSet_t);
+    }
+    if (!pmpriv->wps.session_enable) {
+        if ((pmpriv->sec_info.wpa_enabled || pmpriv->sec_info.wpa2_enabled)) {
+            prsn_ie_tlv = (MrvlIEtypes_RsnParamSet_t *) pos;
+            prsn_ie_tlv->header.type = (t_u16) pmpriv->wpa_ie[0];       /* WPA_IE 
+                                                                           or
+                                                                           WPA2_IE 
+                                                                         */
+            prsn_ie_tlv->header.type = prsn_ie_tlv->header.type & 0x00FF;
+            prsn_ie_tlv->header.type =
+                wlan_cpu_to_le16(prsn_ie_tlv->header.type);
+            prsn_ie_tlv->header.len = (t_u16) pmpriv->wpa_ie[1];
+            prsn_ie_tlv->header.len = prsn_ie_tlv->header.len & 0x00FF;
+            if (prsn_ie_tlv->header.len <= (sizeof(pmpriv->wpa_ie) - 2))
+                memcpy(prsn_ie_tlv->rsn_ie, &pmpriv->wpa_ie[2],
+                       prsn_ie_tlv->header.len);
+            else {
+                ret = MLAN_STATUS_FAILURE;
+                goto done;
+            }
+            HEXDUMP("ASSOC_CMD: RSN IE", (t_u8 *) prsn_ie_tlv,
+                    sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len);
+            pos += sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+            prsn_ie_tlv->header.len = wlan_cpu_to_le16(prsn_ie_tlv->header.len);
+        } else if (pmpriv->sec_info.ewpa_enabled) {
+            prsn_ie_tlv = (MrvlIEtypes_RsnParamSet_t *) pos;
+            if (pbss_desc->pwpa_ie) {
+                prsn_ie_tlv->header.type =
+                    (t_u16) (*(pbss_desc->pwpa_ie)).vend_hdr.element_id;
+                prsn_ie_tlv->header.type = prsn_ie_tlv->header.type & 0x00FF;
+                prsn_ie_tlv->header.type =
+                    wlan_cpu_to_le16(prsn_ie_tlv->header.type);
+                prsn_ie_tlv->header.len =
+                    (t_u16) (*(pbss_desc->pwpa_ie)).vend_hdr.len;
+                prsn_ie_tlv->header.len = prsn_ie_tlv->header.len & 0x00FF;
+                if (prsn_ie_tlv->header.len <= (sizeof(pmpriv->wpa_ie))) {
+                    memcpy(prsn_ie_tlv->rsn_ie,
+                           &((*(pbss_desc->pwpa_ie)).vend_hdr.oui[0]),
+                           prsn_ie_tlv->header.len);
+                } else {
+                    ret = MLAN_STATUS_FAILURE;
+                    goto done;
+                }
+
+                HEXDUMP("ASSOC_CMD: RSN IE", (t_u8 *) prsn_ie_tlv,
+                        sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len);
+                pos += sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+                prsn_ie_tlv->header.len =
+                    wlan_cpu_to_le16(prsn_ie_tlv->header.len);
+            }
+            if (pbss_desc->prsn_ie) {
+                prsn_ie_tlv = (MrvlIEtypes_RsnParamSet_t *) pos;
+                prsn_ie_tlv->header.type =
+                    (t_u16) (*(pbss_desc->prsn_ie)).ieee_hdr.element_id;
+                prsn_ie_tlv->header.type = prsn_ie_tlv->header.type & 0x00FF;
+                prsn_ie_tlv->header.type =
+                    wlan_cpu_to_le16(prsn_ie_tlv->header.type);
+                prsn_ie_tlv->header.len =
+                    (t_u16) (*(pbss_desc->prsn_ie)).ieee_hdr.len;
+                prsn_ie_tlv->header.len = prsn_ie_tlv->header.len & 0x00FF;
+                if (prsn_ie_tlv->header.len <= (sizeof(pmpriv->wpa_ie))) {
+                    memcpy(prsn_ie_tlv->rsn_ie,
+                           &((*(pbss_desc->prsn_ie)).data[0])
+                           , prsn_ie_tlv->header.len);
+                } else {
+                    ret = MLAN_STATUS_FAILURE;
+                    goto done;
+                }
+
+                HEXDUMP("ASSOC_CMD: RSN IE", (t_u8 *) prsn_ie_tlv,
+                        sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len);
+                pos += sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+                prsn_ie_tlv->header.len =
+                    wlan_cpu_to_le16(prsn_ie_tlv->header.len);
+            }
+        }
+    }
+
+    if (ISSUPP_11NENABLED(pmpriv->adapter->fw_cap_info)
+        && (pmpriv->adapter->config_bands & BAND_GN
+            || pmpriv->adapter->config_bands & BAND_AN))
+        wlan_cmd_append_11n_tlv(pmpriv, pbss_desc, &pos);
+
+    /** Append vendor specific IE TLV */
+    wlan_cmd_append_vsie_tlv(pmpriv, MLAN_VSIE_MASK_ASSOC, &pos);
+
+    wlan_wmm_process_association_req(pmpriv, &pos, &pbss_desc->wmm_ie,
+                                     pbss_desc->pht_cap);
+    if (pmpriv->sec_info.wapi_enabled && pmpriv->wapi_ie_len) {
+        wlan_cmd_append_wapi_ie(pmpriv, &pos);
+    }
+
+    wlan_cmd_append_generic_ie(pmpriv, &pos);
+
+    wlan_cmd_append_tsf_tlv(pmpriv, &pos, pbss_desc);
+
+    if (wlan_11d_create_dnld_countryinfo(pmpriv, (t_u8) pbss_desc->bss_band)) {
+        PRINTM(MERROR, "Dnld_countryinfo_11d failed\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    if (wlan_11d_parse_dnld_countryinfo(pmpriv, pmpriv->pattempted_bss_desc)) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* 
+     * Call 11h join API after capability bits are set so adhoc/infra 11h
+     * behavior can be properly triggered.  pos modified if data is appended
+     */
+    wlan_11h_process_join(pmpriv, &pos, &passo->cap_info,
+                          pbss_desc->phy_param_set.ds_param_set.current_chan,
+                          &pbss_desc->wlan_11h_bss_info);
+
+    cmd->size = wlan_cpu_to_le16((t_u16) (pos - (t_u8 *) passo) + S_DS_GEN);
+
+    /* Set the Capability info at last */
+    memcpy(&tmp_cap, &pbss_desc->cap_info, sizeof(passo->cap_info));
+    tmp_cap &= CAPINFO_MASK;
+    PRINTM(MINFO, "ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
+           tmp_cap, CAPINFO_MASK);
+    tmp_cap = wlan_cpu_to_le16(tmp_cap);
+    memcpy(&passo->cap_info, &tmp_cap, sizeof(passo->cap_info));
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Association firmware command response handler
+ *
+ *   The response buffer for the association command has the following
+ *      memory layout.
+ *
+ *   For cases where an association response was not received (indicated
+ *      by the CapInfo and AId field):
+ *
+ *     .------------------------------------------------------------.
+ *     |  Header(4 * sizeof(t_u16)):  Standard command response hdr |
+ *     .------------------------------------------------------------.
+ *     |  cap_info/Error Return(t_u16):                             |
+ *     |           0xFFFF(-1): Internal error                       |
+ *     |           0xFFFE(-2): Authentication unhandled message     |
+ *     |           0xFFFD(-3): Authentication refused               |
+ *     |           0xFFFC(-4): Timeout waiting for AP response      |
+ *     .------------------------------------------------------------.
+ *     |  status_code(t_u16):                                       |
+ *     |        If cap_info is -1:                                  |
+ *     |           An internal firmware failure prevented the       |
+ *     |           command from being processed.  The status_code   |
+ *     |           will be set to 1.                                |
+ *     |                                                            |
+ *     |        If cap_info is -2:                                  |
+ *     |           An authentication frame was received but was     |
+ *     |           not handled by the firmware.  IEEE Status        |
+ *     |           code for the failure is returned.                |
+ *     |                                                            |
+ *     |        If cap_info is -3:                                  |
+ *     |           An authentication frame was received and the     |
+ *     |           status_code is the IEEE Status reported in the   |
+ *     |           response.                                        |
+ *     |                                                            |
+ *     |        If cap_info is -4:                                  |
+ *     |           (1) Association response timeout                 |
+ *     |           (2) Authentication response timeout              |
+ *     .------------------------------------------------------------.
+ *     |  a_id(t_u16): 0xFFFF                                       |
+ *     .------------------------------------------------------------.
+ *
+ *
+ *   For cases where an association response was received, the IEEE 
+ *     standard association response frame is returned:
+ *
+ *     .------------------------------------------------------------.
+ *     |  Header(4 * sizeof(t_u16)):  Standard command response hdr |
+ *     .------------------------------------------------------------.
+ *     |  cap_info(t_u16): IEEE Capability                          |
+ *     .------------------------------------------------------------.
+ *     |  status_code(t_u16): IEEE Status Code                      |
+ *     .------------------------------------------------------------.
+ *     |  a_id(t_u16): IEEE Association ID                          |
+ *     .------------------------------------------------------------.
+ *     |  IEEE IEs(variable): Any received IEs comprising the       |
+ *     |                      remaining portion of a received       |
+ *     |                      association response frame.           |
+ *     .------------------------------------------------------------.
+ *
+ *  For simplistic handling, the status_code field can be used to determine
+ *    an association success (0) or failure (non-zero).
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_ret_802_11_associate(IN mlan_private * pmpriv,
+                          IN HostCmd_DS_COMMAND * resp, IN t_void * pioctl_buf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ioctl_req *pioctl_req = (mlan_ioctl_req *) pioctl_buf;
+    IEEEtypes_AssocRsp_t *passoc_rsp;
+    BSSDescriptor_t *pbss_desc;
+    t_u8 enable_data = MTRUE;
+    t_u8 event_buf[100];
+    mlan_event *pevent = (mlan_event *) event_buf;
+
+    ENTER();
+
+    passoc_rsp = (IEEEtypes_AssocRsp_t *) & resp->params;
+    passoc_rsp->status_code = wlan_le16_to_cpu(passoc_rsp->status_code);
+
+    HEXDUMP("ASSOC_RESP:", (t_u8 *) & resp->params, (resp->size - S_DS_GEN));
+
+    pmpriv->assoc_rsp_size = MIN(resp->size - S_DS_GEN,
+                                 sizeof(pmpriv->assoc_rsp_buf));
+
+    memcpy(pmpriv->assoc_rsp_buf, &resp->params, pmpriv->assoc_rsp_size);
+
+    if (passoc_rsp->status_code) {
+        pmpriv->adapter->dbg.num_cmd_assoc_failure++;
+        PRINTM(MERROR, "ASSOC_RESP: Association Failed, "
+               "status code = %d, error = 0x%x, a_id = 0x%x\n",
+               wlan_le16_to_cpu(passoc_rsp->status_code),
+               wlan_le16_to_cpu(*(t_u16 *) & passoc_rsp->capability),
+               wlan_le16_to_cpu(passoc_rsp->a_id));
+
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Send a Media Connected event, according to the Spec */
+    pmpriv->media_connected = MTRUE;
+
+    /* Set the attempted BSSID Index to current */
+    pbss_desc = pmpriv->pattempted_bss_desc;
+
+    PRINTM(MINFO, "ASSOC_RESP: %s\n", pbss_desc->ssid.ssid);
+
+    /* Make a copy of current BSSID descriptor */
+    memcpy(&pmpriv->curr_bss_params.bss_descriptor,
+           pbss_desc, sizeof(BSSDescriptor_t));
+
+    /* Update curr_bss_params */
+    pmpriv->curr_bss_params.bss_descriptor.channel
+        = pbss_desc->phy_param_set.ds_param_set.current_chan;
+
+    pmpriv->curr_bss_params.band = (t_u8) pbss_desc->bss_band;
+
+    /* 
+     * Adjust the timestamps in the scan table to be relative to the newly
+     * associated AP's TSF
+     */
+    wlan_update_tsf_timestamps(pmpriv, pbss_desc);
+
+    if (pbss_desc->wmm_ie.vend_hdr.element_id == WMM_IE)
+        pmpriv->curr_bss_params.wmm_enabled = MTRUE;
+    else
+        pmpriv->curr_bss_params.wmm_enabled = MFALSE;
+
+    if ((pmpriv->wmm_required
+         || (pbss_desc->pht_cap &&
+             (pbss_desc->pht_cap->ieee_hdr.element_id == HT_CAPABILITY))
+        ) && pmpriv->curr_bss_params.wmm_enabled)
+        pmpriv->wmm_enabled = MTRUE;
+    else
+        pmpriv->wmm_enabled = MFALSE;
+
+    pmpriv->curr_bss_params.wmm_uapsd_enabled = MFALSE;
+
+    if (pmpriv->wmm_enabled == MTRUE)
+        pmpriv->curr_bss_params.wmm_uapsd_enabled
+            = pbss_desc->wmm_ie.qos_info.qos_uapsd;
+
+    PRINTM(MINFO, "ASSOC_RESP: curr_pkt_filter is 0x%x\n",
+           pmpriv->curr_pkt_filter);
+    if (pmpriv->sec_info.wpa_enabled || pmpriv->sec_info.wpa2_enabled)
+        pmpriv->wpa_is_gtk_set = MFALSE;
+
+    if (pmpriv->wmm_enabled)
+        /* Don't re-enable carrier until we get the WMM_GET_STATUS event */
+        enable_data = MFALSE;
+    else
+        /* Since WMM is not enabled, setup the queues with the defaults */
+        wlan_wmm_setup_queues(pmpriv);
+
+    if (enable_data) {
+        PRINTM(MINFO, "Post association, re-enabling data flow\n");
+    }
+
+    ret =
+        wlan_11d_parse_dnld_countryinfo(pmpriv,
+                                        &pmpriv->curr_bss_params.
+                                        bss_descriptor);
+
+    /* Reset SNR/NF/RSSI values */
+    pmpriv->data_rssi_last = 0;
+    pmpriv->data_nf_last = 0;
+    pmpriv->data_rssi_avg = 0;
+    pmpriv->data_nf_avg = 0;
+    pmpriv->bcn_rssi_last = 0;
+    pmpriv->bcn_nf_last = 0;
+    pmpriv->bcn_rssi_avg = 0;
+    pmpriv->bcn_nf_avg = 0;
+    pmpriv->rxpd_rate = 0;
+    pmpriv->rxpd_htinfo = 0;
+
+    wlan_save_curr_bcn(pmpriv);
+
+    pmpriv->adapter->dbg.num_cmd_assoc_success++;
+
+    PRINTM(MINFO, "ASSOC_RESP: Associated\n");
+    pevent->bss_num = pmpriv->bss_num;
+    pevent->event_id = MLAN_EVENT_ID_DRV_CONNECTED;
+    pevent->event_len = MLAN_MAC_ADDR_LENGTH;
+    memcpy((t_u8 *) pevent->event_buf,
+           (t_u8 *) pmpriv->curr_bss_params.bss_descriptor.mac_address,
+           MLAN_MAC_ADDR_LENGTH);
+
+    /* Add the ra_list here for infra mode as there will be only 1 ra always */
+    wlan_ralist_add(pmpriv, pmpriv->curr_bss_params.bss_descriptor.mac_address);
+
+    wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_CONNECTED, pevent);
+
+    /* Send OBSS scan param to the application if available */
+    wlan_2040_coex_event(pmpriv);
+
+  done:
+    /* Need to indicate IOCTL complete */
+    if (pioctl_req != MNULL) {
+        if (ret != MLAN_STATUS_SUCCESS) {
+            if (passoc_rsp->status_code)
+                pioctl_req->status_code =
+                    wlan_le16_to_cpu(passoc_rsp->status_code);
+            else
+                pioctl_req->status_code = MLAN_ERROR_ASSOC_FAIL;
+        } else {
+            pioctl_req->status_code = MLAN_ERROR_NO_ERROR;
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function prepares command of ad_hoc_start.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf    A pointer cast of mlan_802_11_ssid structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_802_11_ad_hoc_start(IN mlan_private * pmpriv,
+                             IN HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    HostCmd_DS_802_11_AD_HOC_START *padhoc_start = &cmd->params.adhoc_start;
+    BSSDescriptor_t *pbss_desc;
+    t_u32 cmd_append_size = 0;
+    t_u32 i;
+    t_u16 tmp_cap;
+    MrvlIEtypes_ChanListParamSet_t *pchan_tlv;
+
+    MrvlIEtypes_RsnParamSet_t *prsn_ie_tlv;
+    MrvlIETypes_HTCap_t *pht_cap;
+    MrvlIETypes_HTInfo_t *pht_info;
+    /* wpa ie for WPA_NONE AES */
+    const t_u8 wpa_ie[24] = { 0xdd, 0x16, 0x00, 0x50, 0xf2, 0x01, 0x01, 0x00,
+        0x00, 0x50, 0xf2, 0x04, 0x01, 0x00, 0x00, 0x50,
+        0xf2, 0x00, 0x01, 0x00, 0x00, 0x50, 0xf2, 0x00
+    };
+    t_u8 *pos = (t_u8 *) padhoc_start + sizeof(HostCmd_DS_802_11_AD_HOC_START);
+
+    ENTER();
+
+    if (!pmadapter) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_START);
+
+    pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
+    pmpriv->pattempted_bss_desc = pbss_desc;
+
+    /* 
+     * Fill in the parameters for 2 data structures:
+     *   1. HostCmd_DS_802_11_AD_HOC_START command
+     *   2. pbss_desc
+     * Driver will fill up SSID, bss_mode,IBSS param, Physical Param,
+     * probe delay, and Cap info.
+     * Firmware will fill up beacon period, Basic rates
+     * and operational rates.
+     */
+
+    memset(padhoc_start->ssid, 0, MLAN_MAX_SSID_LENGTH);
+
+    memcpy(padhoc_start->ssid,
+           ((mlan_802_11_ssid *) pdata_buf)->ssid,
+           ((mlan_802_11_ssid *) pdata_buf)->ssid_len);
+
+    PRINTM(MINFO, "ADHOC_S_CMD: SSID = %s\n", padhoc_start->ssid);
+
+    memset(pbss_desc->ssid.ssid, 0, MLAN_MAX_SSID_LENGTH);
+    memcpy(pbss_desc->ssid.ssid,
+           ((mlan_802_11_ssid *) pdata_buf)->ssid,
+           ((mlan_802_11_ssid *) pdata_buf)->ssid_len);
+
+    pbss_desc->ssid.ssid_len = ((mlan_802_11_ssid *) pdata_buf)->ssid_len;
+
+    /* Set the BSS mode */
+    padhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS;
+    pbss_desc->bss_mode = MLAN_BSS_MODE_IBSS;
+    padhoc_start->beacon_period = wlan_cpu_to_le16(pmpriv->beacon_period);
+    pbss_desc->beacon_period = pmpriv->beacon_period;
+
+    /* Set Physical param set */
+/** Parameter IE Id */
+#define DS_PARA_IE_ID   3
+/** Parameter IE length */
+#define DS_PARA_IE_LEN  1
+
+    padhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
+    padhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
+
+    if (!wlan_get_cfp_by_band_and_channel
+        (pmadapter, pmadapter->adhoc_start_band, (t_u16) pmpriv->adhoc_channel,
+         pmadapter->region_channel)) {
+
+        chan_freq_power_t *cfp;
+        cfp =
+            wlan_get_cfp_by_band_and_channel(pmadapter,
+                                             pmadapter->adhoc_start_band,
+                                             FIRST_VALID_CHANNEL,
+                                             pmadapter->region_channel);
+        if (cfp)
+            pmpriv->adhoc_channel = (t_u8) cfp->channel;
+    }
+
+    ASSERT(pmpriv->adhoc_channel);
+
+    PRINTM(MINFO, "ADHOC_S_CMD: Creating ADHOC on Channel %d\n",
+           pmpriv->adhoc_channel);
+
+    pmpriv->curr_bss_params.bss_descriptor.channel = pmpriv->adhoc_channel;
+    pmpriv->curr_bss_params.band = pmadapter->adhoc_start_band;
+
+    pbss_desc->channel = pmpriv->adhoc_channel;
+    padhoc_start->phy_param_set.ds_param_set.current_chan =
+        pmpriv->adhoc_channel;
+
+    memcpy(&pbss_desc->phy_param_set,
+           &padhoc_start->phy_param_set, sizeof(IEEEtypes_PhyParamSet_t));
+
+    pbss_desc->network_type_use = Wlan802_11DS;
+
+    /* Set IBSS param set */
+/** IBSS parameter IE Id */
+#define IBSS_PARA_IE_ID   6
+/** IBSS parameter IE length */
+#define IBSS_PARA_IE_LEN  2
+
+    padhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
+    padhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
+    padhoc_start->ss_param_set.ibss_param_set.atim_window
+        = wlan_cpu_to_le16(pmpriv->atim_window);
+    pbss_desc->atim_window = pmpriv->atim_window;
+    memcpy(&pbss_desc->ss_param_set,
+           &padhoc_start->ss_param_set, sizeof(IEEEtypes_SsParamSet_t));
+
+    /* Set Capability info */
+    padhoc_start->cap.ess = 0;
+    padhoc_start->cap.ibss = 1;
+    pbss_desc->cap_info.ibss = 1;
+
+    /* Set up privacy in pbss_desc */
+    if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled
+        || pmpriv->adhoc_aes_enabled
+        || pmpriv->sec_info.wpa_enabled || pmpriv->sec_info.ewpa_enabled) {
+/** Ad-Hoc capability privacy on */
+#define AD_HOC_CAP_PRIVACY_ON   1
+        PRINTM(MINFO, "ADHOC_S_CMD: wep_status set, Privacy to WEP\n");
+        pbss_desc->privacy = Wlan802_11PrivFilter8021xWEP;
+        padhoc_start->cap.privacy = AD_HOC_CAP_PRIVACY_ON;
+    } else {
+        PRINTM(MWARN, "ADHOC_S_CMD: wep_status NOT set, Setting "
+               "Privacy to ACCEPT ALL\n");
+        pbss_desc->privacy = Wlan802_11PrivFilterAcceptAll;
+    }
+
+    memset(padhoc_start->DataRate, 0, sizeof(padhoc_start->DataRate));
+    wlan_get_active_data_rates(pmpriv, padhoc_start->DataRate);
+    if ((pmadapter->adhoc_start_band & BAND_G) &&
+        (pmpriv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_MAC_CONTROL,
+                               HostCmd_ACT_GEN_SET,
+                               0, MNULL, &pmpriv->curr_pkt_filter);
+
+        if (ret) {
+            PRINTM(MERROR, "ADHOC_S_CMD: G Protection config failed\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+    }
+    /* Find the last non zero */
+    for (i = 0; i < sizeof(padhoc_start->DataRate) && padhoc_start->DataRate[i];
+         i++);
+
+    pmpriv->curr_bss_params.num_of_rates = i;
+
+    /* Copy the ad-hoc creating rates into Current BSS rate structure */
+    memcpy(&pmpriv->curr_bss_params.data_rates,
+           &padhoc_start->DataRate, pmpriv->curr_bss_params.num_of_rates);
+
+    PRINTM(MINFO, "ADHOC_S_CMD: Rates=%02x %02x %02x %02x \n",
+           padhoc_start->DataRate[0], padhoc_start->DataRate[1],
+           padhoc_start->DataRate[2], padhoc_start->DataRate[3]);
+
+    PRINTM(MINFO, "ADHOC_S_CMD: AD HOC Start command is ready\n");
+
+    if (IS_SUPPORT_MULTI_BANDS(pmadapter)) {
+        /* Append a channel TLV */
+        pchan_tlv = (MrvlIEtypes_ChanListParamSet_t *) pos;
+        pchan_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
+        pchan_tlv->header.len = wlan_cpu_to_le16(sizeof(ChanScanParamSet_t));
+
+        memset(pchan_tlv->chan_scan_param, 0x00, sizeof(ChanScanParamSet_t));
+        pchan_tlv->chan_scan_param[0].chan_number =
+            (t_u8) pmpriv->curr_bss_params.bss_descriptor.channel;
+
+        PRINTM(MINFO, "ADHOC_S_CMD: TLV Chan = %d\n",
+               pchan_tlv->chan_scan_param[0].chan_number);
+
+        pchan_tlv->chan_scan_param[0].radio_type
+            = wlan_band_to_radio_type(pmpriv->curr_bss_params.band);
+
+        PRINTM(MINFO, "ADHOC_S_CMD: TLV Band = %d\n",
+               pchan_tlv->chan_scan_param[0].radio_type);
+        pos += sizeof(pchan_tlv->header) + sizeof(ChanScanParamSet_t);
+        cmd_append_size +=
+            sizeof(pchan_tlv->header) + sizeof(ChanScanParamSet_t);
+    }
+
+    /** Append vendor specific IE TLV */
+    cmd_append_size +=
+        wlan_cmd_append_vsie_tlv(pmpriv, MLAN_VSIE_MASK_ADHOC, &pos);
+
+    if (wlan_11d_create_dnld_countryinfo(pmpriv, pmpriv->curr_bss_params.band)) {
+        PRINTM(MERROR, "ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* 
+     * Call 11h start API to add any 11h flags/elements as TLV parameters
+     */
+    cmd_append_size += wlan_11h_process_start(pmpriv, &pos, &padhoc_start->cap,
+                                              pmpriv->adhoc_channel,
+                                              &pbss_desc->wlan_11h_bss_info);
+
+    if (pmpriv->sec_info.ewpa_enabled) {
+        memcpy(pmpriv->wpa_ie, wpa_ie, sizeof(wpa_ie));
+        pmpriv->wpa_ie_len = sizeof(wpa_ie);
+    }
+
+    if (pmpriv->sec_info.wpa_enabled || pmpriv->sec_info.ewpa_enabled) {
+        prsn_ie_tlv = (MrvlIEtypes_RsnParamSet_t *) pos;
+        prsn_ie_tlv->header.type = (t_u16) pmpriv->wpa_ie[0];   /* WPA_IE or
+                                                                   WPA2_IE */
+        prsn_ie_tlv->header.type = prsn_ie_tlv->header.type & 0x00FF;
+        prsn_ie_tlv->header.type = wlan_cpu_to_le16(prsn_ie_tlv->header.type);
+        prsn_ie_tlv->header.len = (t_u16) pmpriv->wpa_ie[1];
+        prsn_ie_tlv->header.len = prsn_ie_tlv->header.len & 0x00FF;
+        if (prsn_ie_tlv->header.len <= (sizeof(pmpriv->wpa_ie) - 2))
+            memcpy(prsn_ie_tlv->rsn_ie, &pmpriv->wpa_ie[2],
+                   prsn_ie_tlv->header.len);
+        else {
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+
+        DBG_HEXDUMP(MCMD_D, "ADHOC_S_CMD: RSN IE", (t_u8 *) prsn_ie_tlv,
+                    sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len);
+        pos += sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+        cmd_append_size +=
+            sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+        prsn_ie_tlv->header.len = wlan_cpu_to_le16(prsn_ie_tlv->header.len);
+    }
+
+    if (pmadapter->adhoc_11n_enabled == MTRUE) {
+        {
+            pht_cap = (MrvlIETypes_HTCap_t *) pos;
+            memset(pht_cap, 0, sizeof(MrvlIETypes_HTCap_t));
+            pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY);
+            pht_cap->header.len = sizeof(HTCap_t);
+            SETHT_SUPPCHANWIDTH(pht_cap->ht_cap.ht_cap_info);
+            SETHT_GREENFIELD(pht_cap->ht_cap.ht_cap_info);
+            SETHT_SHORTGI20(pht_cap->ht_cap.ht_cap_info);
+            SETHT_SHORTGI40(pht_cap->ht_cap.ht_cap_info);
+            SETHT_MAXAMSDU(pht_cap->ht_cap.ht_cap_info);
+            SETHT_DSSSCCK40(pht_cap->ht_cap.ht_cap_info);
+            pht_cap->ht_cap.ampdu_param = MAX_RX_AMPDU_SIZE_64K;
+            pht_cap->ht_cap.supported_mcs_set[0] = 0xff;
+            HEXDUMP("ADHOC_START: HT_CAPABILITIES IE", (t_u8 *) pht_cap,
+                    sizeof(MrvlIETypes_HTCap_t));
+            pos += sizeof(MrvlIETypes_HTCap_t);
+            cmd_append_size += sizeof(MrvlIETypes_HTCap_t);
+            pht_cap->header.len = wlan_cpu_to_le16(pht_cap->header.len);
+        }
+        {
+            pht_info = (MrvlIETypes_HTInfo_t *) pos;
+            memset(pht_info, 0, sizeof(MrvlIETypes_HTInfo_t));
+            pht_info->header.type = wlan_cpu_to_le16(HT_OPERATION);
+            pht_info->header.len = sizeof(HTInfo_t);
+            pht_info->ht_info.pri_chan =
+                (t_u8) pmpriv->curr_bss_params.bss_descriptor.channel;
+            if (pmadapter->chan_offset) {
+                pht_info->ht_info.field2 = pmadapter->chan_offset;
+                SET_CHANWIDTH40(pht_info->ht_info.field2);
+            }
+            pht_info->ht_info.field3 = NON_GREENFIELD_STAS;
+            pht_info->ht_info.basic_mcs_set[0] = 0xff;
+            HEXDUMP("ADHOC_START: HT_INFORMATION IE", (t_u8 *) pht_info,
+                    sizeof(MrvlIETypes_HTInfo_t));
+            pos += sizeof(MrvlIETypes_HTInfo_t);
+            cmd_append_size += sizeof(MrvlIETypes_HTInfo_t);
+            pht_info->header.len = wlan_cpu_to_le16(pht_info->header.len);
+        }
+    }
+
+    cmd->size =
+        (t_u16) wlan_cpu_to_le16((t_u16) (sizeof(HostCmd_DS_802_11_AD_HOC_START)
+                                          + S_DS_GEN + cmd_append_size));
+
+    memcpy(&tmp_cap, &padhoc_start->cap, sizeof(t_u16));
+    tmp_cap = wlan_cpu_to_le16(tmp_cap);
+    memcpy(&padhoc_start->cap, &tmp_cap, sizeof(t_u16));
+
+    ret = MLAN_STATUS_SUCCESS;
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function prepares command of ad_hoc_join.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf    Void cast of BSSDescriptor_t from the 
+ *                        scan table to join
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_802_11_ad_hoc_join(IN mlan_private * pmpriv,
+                            IN HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    HostCmd_DS_802_11_AD_HOC_JOIN *padhoc_join = &cmd->params.adhoc_join;
+    BSSDescriptor_t *pbss_desc = (BSSDescriptor_t *) pdata_buf;
+    MrvlIEtypes_ChanListParamSet_t *pchan_tlv;
+    MrvlIEtypes_RsnParamSet_t *prsn_ie_tlv;
+    t_u32 cmd_append_size = 0;
+    t_u16 tmp_cap;
+    t_u32 i, rates_size = 0;
+    t_u16 curr_pkt_filter;
+    t_u8 *pos = (t_u8 *) padhoc_join + sizeof(HostCmd_DS_802_11_AD_HOC_JOIN);
+
+    ENTER();
+
+/** Use G protection */
+#define USE_G_PROTECTION        0x02
+    if (pbss_desc->erp_flags & USE_G_PROTECTION) {
+        curr_pkt_filter =
+            pmpriv->curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
+
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_MAC_CONTROL,
+                               HostCmd_ACT_GEN_SET, 0, MNULL, &curr_pkt_filter);
+        if (ret) {
+            PRINTM(MERROR, "ADHOC_J_CMD: G Protection config failed\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+    }
+
+    pmpriv->pattempted_bss_desc = pbss_desc;
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_JOIN);
+
+    padhoc_join->bss_descriptor.bss_mode = HostCmd_BSS_MODE_IBSS;
+
+    padhoc_join->bss_descriptor.beacon_period
+        = wlan_cpu_to_le16(pbss_desc->beacon_period);
+
+    memcpy(&padhoc_join->bss_descriptor.bssid,
+           &pbss_desc->mac_address, MLAN_MAC_ADDR_LENGTH);
+
+    memcpy(&padhoc_join->bss_descriptor.ssid,
+           &pbss_desc->ssid.ssid, pbss_desc->ssid.ssid_len);
+
+    memcpy(&padhoc_join->bss_descriptor.phy_param_set,
+           &pbss_desc->phy_param_set, sizeof(IEEEtypes_PhyParamSet_t));
+
+    memcpy(&padhoc_join->bss_descriptor.ss_param_set,
+           &pbss_desc->ss_param_set, sizeof(IEEEtypes_SsParamSet_t));
+
+    memcpy(&tmp_cap, &pbss_desc->cap_info, sizeof(IEEEtypes_CapInfo_t));
+
+    tmp_cap &= CAPINFO_MASK;
+
+    PRINTM(MINFO, "ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
+           tmp_cap, CAPINFO_MASK);
+    memcpy(&padhoc_join->bss_descriptor.cap, &tmp_cap,
+           sizeof(IEEEtypes_CapInfo_t));
+
+    /* Information on BSSID descriptor passed to FW */
+    PRINTM(MINFO,
+           "ADHOC_J_CMD: BSSID = %02x-%02x-%02x-%02x-%02x-%02x, SSID = %s\n",
+           padhoc_join->bss_descriptor.bssid[0],
+           padhoc_join->bss_descriptor.bssid[1],
+           padhoc_join->bss_descriptor.bssid[2],
+           padhoc_join->bss_descriptor.bssid[3],
+           padhoc_join->bss_descriptor.bssid[4],
+           padhoc_join->bss_descriptor.bssid[5],
+           padhoc_join->bss_descriptor.ssid);
+
+    for (i = 0; pbss_desc->supported_rates[i] && i < WLAN_SUPPORTED_RATES; i++);
+    rates_size = i;
+
+    /* Copy Data Rates from the Rates recorded in scan response */
+    memset(padhoc_join->bss_descriptor.data_rates, 0,
+           sizeof(padhoc_join->bss_descriptor.data_rates));
+    memcpy(padhoc_join->bss_descriptor.data_rates, pbss_desc->supported_rates,
+           rates_size);
+
+    HEXDUMP("Adapted Rates:", padhoc_join->bss_descriptor.data_rates,
+            rates_size);
+
+    /* Copy the adhoc join rates into Current BSS state structure */
+    pmpriv->curr_bss_params.num_of_rates = rates_size;
+    memcpy(&pmpriv->curr_bss_params.data_rates, pbss_desc->supported_rates,
+           rates_size);
+
+    /* Copy the channel information */
+    pmpriv->curr_bss_params.bss_descriptor.channel = pbss_desc->channel;
+    pmpriv->curr_bss_params.band = (t_u8) pbss_desc->bss_band;
+
+    if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled
+        || pmpriv->adhoc_aes_enabled
+        || pmpriv->sec_info.wpa_enabled || pmpriv->sec_info.ewpa_enabled)
+        padhoc_join->bss_descriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON;
+
+    if (IS_SUPPORT_MULTI_BANDS(pmpriv->adapter)) {
+        /* Append a channel TLV */
+        pchan_tlv = (MrvlIEtypes_ChanListParamSet_t *) pos;
+        pchan_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
+        pchan_tlv->header.len = wlan_cpu_to_le16(sizeof(ChanScanParamSet_t));
+
+        memset(pchan_tlv->chan_scan_param, 0x00, sizeof(ChanScanParamSet_t));
+        pchan_tlv->chan_scan_param[0].chan_number =
+            (pbss_desc->phy_param_set.ds_param_set.current_chan);
+        PRINTM(MINFO, "ADHOC_J_CMD: TLV Chan = %d\n",
+               pchan_tlv->chan_scan_param[0].chan_number);
+
+        pchan_tlv->chan_scan_param[0].radio_type
+            = wlan_band_to_radio_type((t_u8) pbss_desc->bss_band);
+
+        PRINTM(MINFO, "ADHOC_J_CMD: TLV Band = %d\n",
+               pchan_tlv->chan_scan_param[0].radio_type);
+        pos += sizeof(pchan_tlv->header) + sizeof(ChanScanParamSet_t);
+        cmd_append_size +=
+            sizeof(pchan_tlv->header) + sizeof(ChanScanParamSet_t);
+    }
+
+    if (wlan_11d_create_dnld_countryinfo(pmpriv, (t_u8) pbss_desc->bss_band)) {
+        PRINTM(MERROR, "Dnld_countryinfo_11d failed\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    if (wlan_11d_parse_dnld_countryinfo(pmpriv, pmpriv->pattempted_bss_desc)) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* 
+     * Call 11h join API after capability bits are set so
+     *   adhoc/infra 11h behavior can be properly triggered.
+     *   pos modified if data is appended
+     */
+    cmd_append_size += wlan_11h_process_join(pmpriv, &pos,
+                                             &padhoc_join->bss_descriptor.cap,
+                                             pbss_desc->channel,
+                                             &pbss_desc->wlan_11h_bss_info);
+
+    if (pmpriv->sec_info.wpa_enabled) {
+        prsn_ie_tlv = (MrvlIEtypes_RsnParamSet_t *) pos;
+        prsn_ie_tlv->header.type = (t_u16) pmpriv->wpa_ie[0];   /* WPA_IE or
+                                                                   WPA2_IE */
+        prsn_ie_tlv->header.type = prsn_ie_tlv->header.type & 0x00FF;
+        prsn_ie_tlv->header.type = wlan_cpu_to_le16(prsn_ie_tlv->header.type);
+        prsn_ie_tlv->header.len = (t_u16) pmpriv->wpa_ie[1];
+        prsn_ie_tlv->header.len = prsn_ie_tlv->header.len & 0x00FF;
+        if (prsn_ie_tlv->header.len <= (sizeof(pmpriv->wpa_ie) - 2))
+            memcpy(prsn_ie_tlv->rsn_ie, &pmpriv->wpa_ie[2],
+                   prsn_ie_tlv->header.len);
+        else {
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+
+        HEXDUMP("ADHOC_JOIN: RSN IE", (t_u8 *) prsn_ie_tlv,
+                sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len);
+        pos += sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+        cmd_append_size +=
+            sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+        prsn_ie_tlv->header.len = wlan_cpu_to_le16(prsn_ie_tlv->header.len);
+    } else if (pmpriv->sec_info.ewpa_enabled) {
+        prsn_ie_tlv = (MrvlIEtypes_RsnParamSet_t *) pos;
+        if (pbss_desc->pwpa_ie) {
+            prsn_ie_tlv->header.type =
+                (t_u16) (*(pbss_desc->pwpa_ie)).vend_hdr.element_id;
+            prsn_ie_tlv->header.type = prsn_ie_tlv->header.type & 0x00FF;
+            prsn_ie_tlv->header.type =
+                wlan_cpu_to_le16(prsn_ie_tlv->header.type);
+            prsn_ie_tlv->header.len =
+                (t_u16) (*(pbss_desc->pwpa_ie)).vend_hdr.len;
+            prsn_ie_tlv->header.len = prsn_ie_tlv->header.len & 0x00FF;
+            if (prsn_ie_tlv->header.len <= (sizeof(pmpriv->wpa_ie))) {
+                memcpy(prsn_ie_tlv->rsn_ie,
+                       &((*(pbss_desc->pwpa_ie)).vend_hdr.oui[0]),
+                       prsn_ie_tlv->header.len);
+            } else {
+                ret = MLAN_STATUS_FAILURE;
+                goto done;
+            }
+
+            HEXDUMP("ADHOC_JOIN: RSN IE", (t_u8 *) prsn_ie_tlv,
+                    sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len);
+            pos += sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+            cmd_append_size +=
+                sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+            prsn_ie_tlv->header.len = wlan_cpu_to_le16(prsn_ie_tlv->header.len);
+        }
+        if (pbss_desc->prsn_ie) {
+            prsn_ie_tlv = (MrvlIEtypes_RsnParamSet_t *) pos;
+            prsn_ie_tlv->header.type =
+                (t_u16) (*(pbss_desc->prsn_ie)).ieee_hdr.element_id;
+            prsn_ie_tlv->header.type = prsn_ie_tlv->header.type & 0x00FF;
+            prsn_ie_tlv->header.type =
+                wlan_cpu_to_le16(prsn_ie_tlv->header.type);
+            prsn_ie_tlv->header.len =
+                (t_u16) (*(pbss_desc->prsn_ie)).ieee_hdr.len;
+            prsn_ie_tlv->header.len = prsn_ie_tlv->header.len & 0x00FF;
+            if (prsn_ie_tlv->header.len <= (sizeof(pmpriv->wpa_ie))) {
+                memcpy(prsn_ie_tlv->rsn_ie, &((*(pbss_desc->prsn_ie)).data[0])
+                       , prsn_ie_tlv->header.len);
+            } else {
+                ret = MLAN_STATUS_FAILURE;
+                goto done;
+            }
+
+            HEXDUMP("ADHOC_JOIN: RSN IE", (t_u8 *) prsn_ie_tlv,
+                    sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len);
+            pos += sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+            cmd_append_size +=
+                sizeof(prsn_ie_tlv->header) + prsn_ie_tlv->header.len;
+            prsn_ie_tlv->header.len = wlan_cpu_to_le16(prsn_ie_tlv->header.len);
+        }
+    }
+
+    if (ISSUPP_11NENABLED(pmpriv->adapter->fw_cap_info))
+        cmd_append_size += wlan_cmd_append_11n_tlv(pmpriv, pbss_desc, &pos);
+
+    /** Append vendor specific IE TLV */
+    cmd_append_size +=
+        wlan_cmd_append_vsie_tlv(pmpriv, MLAN_VSIE_MASK_ADHOC, &pos);
+
+    cmd->size =
+        (t_u16) wlan_cpu_to_le16((t_u16) (sizeof(HostCmd_DS_802_11_AD_HOC_JOIN)
+                                          + S_DS_GEN + cmd_append_size));
+
+    memcpy(&tmp_cap, &padhoc_join->bss_descriptor.cap,
+           sizeof(IEEEtypes_CapInfo_t));
+    tmp_cap = wlan_cpu_to_le16(tmp_cap);
+
+    memcpy(&padhoc_join->bss_descriptor.cap,
+           &tmp_cap, sizeof(IEEEtypes_CapInfo_t));
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function handles the command response of ad_hoc_start and
+ *  		ad_hoc_join
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_ret_802_11_ad_hoc(IN mlan_private * pmpriv,
+                       IN HostCmd_DS_COMMAND * resp, IN t_void * pioctl_buf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ioctl_req *pioctl_req = (mlan_ioctl_req *) pioctl_buf;
+    HostCmd_DS_802_11_AD_HOC_RESULT *padhoc_result;
+    BSSDescriptor_t *pbss_desc;
+    t_u16 command = resp->command;
+    t_u16 result = resp->result;
+    t_u8 event_buf[100];
+    mlan_event *pevent = (mlan_event *) event_buf;
+
+    ENTER();
+
+    padhoc_result = &resp->params.adhoc_result;
+
+    pbss_desc = pmpriv->pattempted_bss_desc;
+
+    /* 
+     * Join result code 0 --> SUCCESS
+     */
+    if (result) {
+        PRINTM(MERROR, "ADHOC_RESP Failed\n");
+        if (pmpriv->media_connected == MTRUE)
+            wlan_reset_connect_state(pmpriv);
+
+        memset(&pmpriv->curr_bss_params.bss_descriptor,
+               0x00, sizeof(BSSDescriptor_t));
+
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Send a Media Connected event, according to the Spec */
+    pmpriv->media_connected = MTRUE;
+
+    if (command == HostCmd_CMD_802_11_AD_HOC_START) {
+        PRINTM(MINFO, "ADHOC_S_RESP  %s\n", pbss_desc->ssid.ssid);
+
+        /* Update the created network descriptor with the new BSSID */
+        memcpy(pbss_desc->mac_address,
+               padhoc_result->bssid, MLAN_MAC_ADDR_LENGTH);
+
+        pmpriv->adhoc_state = ADHOC_STARTED;
+    } else {
+        /* 
+         * Now the join cmd should be successful.
+         * If BSSID has changed use SSID to compare instead of BSSID
+         */
+        PRINTM(MINFO, "ADHOC_J_RESP  %s\n", pbss_desc->ssid.ssid);
+
+        /* 
+         * Make a copy of current BSSID descriptor, only needed for join since
+         * the current descriptor is already being used for adhoc start
+         */
+        memcpy(&pmpriv->curr_bss_params.bss_descriptor,
+               pbss_desc, sizeof(BSSDescriptor_t));
+
+        pmpriv->adhoc_state = ADHOC_JOINED;
+    }
+
+    PRINTM(MINFO, "ADHOC_RESP: Channel = %d\n", pmpriv->adhoc_channel);
+    PRINTM(MINFO, "ADHOC_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
+           pmpriv->curr_bss_params.bss_descriptor.mac_address[0],
+           pmpriv->curr_bss_params.bss_descriptor.mac_address[1],
+           pmpriv->curr_bss_params.bss_descriptor.mac_address[2],
+           pmpriv->curr_bss_params.bss_descriptor.mac_address[3],
+           pmpriv->curr_bss_params.bss_descriptor.mac_address[4],
+           pmpriv->curr_bss_params.bss_descriptor.mac_address[5]);
+
+    pevent->bss_num = pmpriv->bss_num;
+    pevent->event_id = MLAN_EVENT_ID_DRV_CONNECTED;
+    pevent->event_len = MLAN_MAC_ADDR_LENGTH;
+    memcpy((t_u8 *) pevent->event_buf,
+           (t_u8 *) pmpriv->curr_bss_params.bss_descriptor.mac_address,
+           MLAN_MAC_ADDR_LENGTH);
+    wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_CONNECTED, pevent);
+    wlan_save_curr_bcn(pmpriv);
+
+  done:
+    /* Need to indicate IOCTL complete */
+    if (pioctl_req != MNULL) {
+        if (ret != MLAN_STATUS_SUCCESS) {
+            pioctl_req->status_code = MLAN_ERROR_ASSOC_FAIL;
+        } else {
+            pioctl_req->status_code = MLAN_ERROR_NO_ERROR;
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Associated to a specific BSS discovered in a scan
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pioctl_buf   A pointer to MLAN IOCTl Request buffer
+ *  @param pbss_desc     A pointer to the BSS descriptor to associate with.
+ *
+ *  @return             MLAN_STATUS_SUCCESS or < 0 if error
+ */
+mlan_status
+wlan_associate(IN mlan_private * pmpriv,
+               IN t_void * pioctl_buf, IN BSSDescriptor_t * pbss_desc)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u8 current_bssid[MLAN_MAC_ADDR_LENGTH];
+
+    ENTER();
+
+    /* Return error if the pmadapter or table entry is not marked as infra */
+    if ((pmpriv->bss_mode != MLAN_BSS_MODE_INFRA) ||
+        (pbss_desc->bss_mode != MLAN_BSS_MODE_INFRA)) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    memcpy(&current_bssid,
+           &pmpriv->curr_bss_params.bss_descriptor.mac_address,
+           sizeof(current_bssid));
+
+    /* Clear any past association response stored for application retrieval */
+    pmpriv->assoc_rsp_size = 0;
+
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_ASSOCIATE,
+                           HostCmd_ACT_GEN_SET, 0, pioctl_buf, pbss_desc);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Start an Adhoc Network
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pioctl_buf   A pointer to MLAN IOCTl Request buffer
+ *  @param padhoc_ssid  The ssid of the Adhoc Network
+ *
+ *  @return             MLAN_STATUS_SUCCESS--success, MLAN_STATUS_FAILURE--fail
+ */
+mlan_status
+wlan_adhoc_start(IN mlan_private * pmpriv,
+                 IN t_void * pioctl_buf, IN mlan_802_11_ssid * padhoc_ssid)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    if ((pmpriv->adhoc_auto_sel)
+        && ((pmadapter->adhoc_start_band & BAND_A)
+            || (pmadapter->adhoc_start_band & BAND_AN)
+        )
+        ) {
+        pmpriv->adhoc_channel = wlan_11h_get_adhoc_start_channel(pmpriv);
+
+        /* 
+         * Check if the region and channel requires a channel availability
+         * check.
+         */
+        if (wlan_11h_radar_detect_required(pmpriv, pmpriv->adhoc_channel)) {
+            /* 
+             * Radar detection is required for this channel, make sure
+             * 11h is activated in the firmware
+             */
+            wlan_11h_activate(pmpriv, MTRUE);
+
+            /* Check for radar on the channel */
+            if (wlan_11h_radar_detected(pmpriv, pmpriv->adhoc_channel)) {
+                LEAVE();
+                return MLAN_STATUS_FAILURE;
+            }
+        }
+    }
+
+    PRINTM(MINFO, "Adhoc Channel = %d\n", pmpriv->adhoc_channel);
+    PRINTM(MINFO, "curr_bss_params.channel = %d\n",
+           pmpriv->curr_bss_params.bss_descriptor.channel);
+    PRINTM(MINFO, "curr_bss_params.band = %d\n", pmpriv->curr_bss_params.band);
+
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_AD_HOC_START,
+                           HostCmd_ACT_GEN_SET, 0, pioctl_buf, padhoc_ssid);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Join an adhoc network found in a previous scan
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pioctl_buf   A pointer to MLAN IOCTl Request buffer
+ *  @param pbss_desc     A pointer to the BSS descriptor found in a previous scan
+ *                      to attempt to join
+ *
+ *  @return             MLAN_STATUS_SUCCESS--success, MLAN_STATUS_FAILURE--fail
+ */
+mlan_status
+wlan_adhoc_join(IN mlan_private * pmpriv,
+                IN t_void * pioctl_buf, IN BSSDescriptor_t * pbss_desc)
+{
+    pmlan_adapter pmadapter = pmpriv->adapter;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    PRINTM(MINFO, "wlan_adhoc_join: CurBss.ssid =%s\n",
+           pmpriv->curr_bss_params.bss_descriptor.ssid.ssid);
+    PRINTM(MINFO, "wlan_adhoc_join: CurBss.ssid_len =%u\n",
+           pmpriv->curr_bss_params.bss_descriptor.ssid.ssid_len);
+    PRINTM(MINFO, "wlan_adhoc_join: ssid =%s\n", pbss_desc->ssid.ssid);
+    PRINTM(MINFO, "wlan_adhoc_join: ssid len =%u\n", pbss_desc->ssid.ssid_len);
+
+    /* Check if the requested SSID is already joined */
+    if (pmpriv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
+        !wlan_ssid_cmp(pmadapter, &pbss_desc->ssid,
+                       &pmpriv->curr_bss_params.bss_descriptor.ssid) &&
+        (pmpriv->curr_bss_params.bss_descriptor.bss_mode ==
+         MLAN_BSS_MODE_IBSS)) {
+
+        PRINTM(MINFO,
+               "ADHOC_J_CMD: New ad-hoc SSID is the same as current, "
+               "not attempting to re-join");
+
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    PRINTM(MINFO, "curr_bss_params.channel = %d\n",
+           pmpriv->curr_bss_params.bss_descriptor.channel);
+    PRINTM(MINFO, "curr_bss_params.band = %c\n", pmpriv->curr_bss_params.band);
+
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_AD_HOC_JOIN,
+                           HostCmd_ACT_GEN_SET, 0, pioctl_buf, pbss_desc);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Send Deauthentication Request or Stop the AdHoc network depending on mode
+ *
+ *  @param pmpriv    A pointer to mlan_private structure
+ *  @param pioctl_req A pointer to mlan_ioctl_req structure
+ *  @param mac       A pointer to mlan_802_11_mac_addr structure
+ *
+ *  @return          MLAN_STATUS_SUCCESS--success, MLAN_STATUS_FAILURE--fail
+ */
+mlan_status
+wlan_disconnect(IN mlan_private * pmpriv,
+                IN mlan_ioctl_req * pioctl_req, IN mlan_802_11_mac_addr * mac)
+{
+    mlan_802_11_mac_addr mac_address;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
+
+    ENTER();
+
+    if (pmpriv->media_connected == MTRUE) {
+        if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) {
+            if (mac) {
+                if (!memcmp(mac, zero_mac, sizeof(zero_mac)))
+                    memcpy((t_u8 *) & mac_address,
+                           (t_u8 *) & pmpriv->curr_bss_params.bss_descriptor.
+                           mac_address, MLAN_MAC_ADDR_LENGTH);
+                else {
+                    memcpy((t_u8 *) & mac_address,
+                           (t_u8 *) mac, MLAN_MAC_ADDR_LENGTH);
+                }
+            } else {
+                memcpy((t_u8 *) & mac_address,
+                       (t_u8 *) & pmpriv->curr_bss_params.bss_descriptor.
+                       mac_address, MLAN_MAC_ADDR_LENGTH);
+            }
+
+            ret = wlan_prepare_cmd(pmpriv,
+                                   HostCmd_CMD_802_11_DEAUTHENTICATE,
+                                   HostCmd_ACT_GEN_SET,
+                                   0, (t_void *) pioctl_req, &mac_address);
+
+            if (ret == MLAN_STATUS_SUCCESS && pioctl_req)
+                ret = MLAN_STATUS_PENDING;
+
+        } else if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) {
+            ret = wlan_prepare_cmd(pmpriv,
+                                   HostCmd_CMD_802_11_AD_HOC_STOP,
+                                   HostCmd_ACT_GEN_SET,
+                                   0, (t_void *) pioctl_req, MNULL);
+
+            if (ret == MLAN_STATUS_SUCCESS && pioctl_req)
+                ret = MLAN_STATUS_PENDING;
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Convert band to radio type used in channel TLV
+ *
+ *  @param band		Band enumeration to convert to a channel TLV radio type
+ *
+ *  @return		Radio type designator for use in a channel TLV
+ */
+t_u8
+wlan_band_to_radio_type(IN t_u8 band)
+{
+    t_u8 ret_radio_type;
+
+    ENTER();
+
+    switch (band) {
+    case BAND_A:
+        ret_radio_type = HostCmd_SCAN_RADIO_TYPE_A;
+        break;
+    case BAND_B:
+    case BAND_G:
+    case BAND_B | BAND_G:
+    default:
+        ret_radio_type = HostCmd_SCAN_RADIO_TYPE_BG;
+        break;
+    }
+
+    LEAVE();
+    return ret_radio_type;
+}
diff --git a/wlan_src/mlan/mlan_join.h b/wlan_src/mlan/mlan_join.h
new file mode 100755
index 0000000..4e934d9
--- /dev/null
+++ b/wlan_src/mlan/mlan_join.h
@@ -0,0 +1,33 @@
+/** @file mlan_join.h
+ *
+ *  @brief This file defines the interface for the WLAN infrastructure
+ *  and adhoc join routines.
+ *
+ *  Driver interface functions and type declarations for the join module
+ *  implemented in mlan_join.c.  Process all start/join requests for
+ *  both adhoc and infrastructure networks
+ *    
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ *
+ *  @sa mlan_join.c
+ */
+
+/******************************************************
+Change log:
+    10/13/2008: initial version
+******************************************************/
+
+#ifndef _MLAN_JOIN_H_
+#define _MLAN_JOIN_H_
+
+/** Size of buffer allocated to store the association response from firmware */
+#define MRVDRV_ASSOC_RSP_BUF_SIZE  500
+
+/** Size of buffer allocated to store IEs passed to firmware in the assoc req */
+#define MRVDRV_GENIE_BUF_SIZE      256
+
+/** Size of buffer allocated to store TLVs passed to firmware in the assoc req */
+#define MRVDRV_ASSOC_TLV_BUF_SIZE  256
+
+#endif /* _MLAN_JOIN_H_ */
diff --git a/wlan_src/mlan/mlan_main.h b/wlan_src/mlan/mlan_main.h
new file mode 100755
index 0000000..60a0aba
--- /dev/null
+++ b/wlan_src/mlan/mlan_main.h
@@ -0,0 +1,1835 @@
+/** @file mlan_main.h
+ *
+ *  @brief This file defines the private and adapter data
+ *  structures and declares global function prototypes used
+ *  in MLAN module.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    10/13/2008: initial version
+******************************************************/
+
+#ifndef _MLAN_MAIN_H_
+#define _MLAN_MAIN_H_
+
+#ifdef DEBUG_LEVEL1
+/** Log debug message */
+#ifdef __GNUC__
+#define PRINTM(level, pformat, args...) \
+do {                                    \
+    extern mlan_adapter    *g_pmadapter;    \
+    if (g_pmadapter->callbacks.moal_print)  \
+        g_pmadapter->callbacks.moal_print(level, pformat, ## args); \
+} while (0)
+#else
+#define PRINTM(level, pformat, ...) \
+do {                                    \
+    extern mlan_adapter    *g_pmadapter;    \
+    if (g_pmadapter->callbacks.moal_print)  \
+        g_pmadapter->callbacks.moal_print(level, pformat, __VA_ARGS__); \
+} while (0)
+#endif /* __GNUC__ */
+
+/** Max hex dump data length */
+#define MAX_DATA_DUMP_LEN	48
+
+/** Debug hexdump for level-1 debugging */
+#define DBG_HEXDUMP(level,x,y,z)   \
+do {                \
+    extern mlan_adapter    *g_pmadapter;    \
+    if (g_pmadapter->callbacks.moal_print)  \
+        g_pmadapter->callbacks.moal_print(MHEX_DUMP | level, x, y, z); \
+} while (0)
+#else
+/** Log debug message */
+#define PRINTM(level, pformat, args...) do {} while (0)
+
+/** Debug hexdump for level-1 debugging */
+#define DBG_HEXDUMP(level,x,y,z) do {} while (0)
+#endif /* DEBUG_LEVEL1 */
+
+#ifdef DEBUG_LEVEL2
+/** Log entry point for debugging */
+#define ENTER()     \
+do {                \
+        PRINTM(MENTRY, "Enter: %s\n", __FUNCTION__);   \
+} while (0)
+
+/** Log exit point for debugging */
+#define LEAVE()     \
+do {                \
+        PRINTM(MENTRY, "Leave: %s\n", __FUNCTION__);   \
+} while (0)
+
+/** Hexdump for level-2 debugging */
+#define HEXDUMP(x,y,z)   \
+do {                \
+    extern mlan_adapter    *g_pmadapter;    \
+    if (g_pmadapter->callbacks.moal_print)  \
+        g_pmadapter->callbacks.moal_print(MHEX_DUMP | MINFO, x, y, z); \
+} while (0)
+#else
+/** Log entry point for debugging */
+#define ENTER() do {} while (0)
+
+/** Log exit point for debugging */
+#define LEAVE() do {} while (0)
+
+/** Hexdump for debugging */
+#define HEXDUMP(x,y,z) do {} while (0)
+#endif /* DEBUG_LEVEL2 */
+
+/** Find minimum */
+#ifndef MIN
+#define MIN(a,b)		((a) < (b) ? (a) : (b))
+#endif
+
+/** Find maximum */
+#ifndef MAX
+#define MAX(a,b)		((a) > (b) ? (a) : (b))
+#endif
+
+extern struct _mlan_adapter *g_pmadapter;
+#ifdef memset
+#undef memset
+#endif
+/** Memset routine */
+#define memset(s, c, len) \
+  g_pmadapter->callbacks.moal_memset(s, c, len)
+
+#ifdef memmove
+#undef memmove
+#endif
+/** Memmove routine */
+#define memmove(dest, src, len) \
+  g_pmadapter->callbacks.moal_memmove(dest, src, len)
+
+#ifdef memcpy
+#undef memcpy
+#endif
+/** Memcpy routine */
+#define memcpy(to, from, len) \
+  g_pmadapter->callbacks.moal_memcpy(to, from, len)
+
+#ifdef memcmp
+#undef memcmp
+#endif
+/** Memcmp routine */
+#define memcmp(s1, s2, len) \
+  g_pmadapter->callbacks.moal_memcmp(s1, s2, len)
+
+/** Find number of elements */
+#ifndef NELEMENTS
+#define NELEMENTS(x)    (sizeof(x)/sizeof(x[0]))
+#endif
+
+/** SWAP: swap t_u8 */
+#define SWAP_U8(a,b)	{t_u8 t; t=a; a=b; b=t;}
+
+/** SWAP: swap t_u8 */
+#define SWAP_U16(a,b)	{t_u16 t; t=a; a=b; b=t;}
+
+/** MLAN MNULL pointer */
+#define MNULL                           (0)
+
+/** 16 bits byte swap */
+#define swap_byte_16(x) \
+((t_u16)((((t_u16)(x) & 0x00ffU) << 8) | \
+         (((t_u16)(x) & 0xff00U) >> 8)))
+
+/** 32 bits byte swap */
+#define swap_byte_32(x) \
+((t_u32)((((t_u32)(x) & 0x000000ffUL) << 24) | \
+         (((t_u32)(x) & 0x0000ff00UL) <<  8) | \
+         (((t_u32)(x) & 0x00ff0000UL) >>  8) | \
+         (((t_u32)(x) & 0xff000000UL) >> 24)))
+
+/** 64 bits byte swap */
+#define swap_byte_64(x) \
+((t_u64)((t_u64)(((t_u64)(x) & 0x00000000000000ffULL) << 56) | \
+         (t_u64)(((t_u64)(x) & 0x000000000000ff00ULL) << 40) | \
+         (t_u64)(((t_u64)(x) & 0x0000000000ff0000ULL) << 24) | \
+         (t_u64)(((t_u64)(x) & 0x00000000ff000000ULL) <<  8) | \
+         (t_u64)(((t_u64)(x) & 0x000000ff00000000ULL) >>  8) | \
+         (t_u64)(((t_u64)(x) & 0x0000ff0000000000ULL) >> 24) | \
+         (t_u64)(((t_u64)(x) & 0x00ff000000000000ULL) >> 40) | \
+         (t_u64)(((t_u64)(x) & 0xff00000000000000ULL) >> 56) ))
+
+#ifdef BIG_ENDIAN
+/** Convert n/w to host */
+#define mlan_ntohs(x)  x
+/** Convert host to n/w */
+#define mlan_htons(x)  x
+/** Convert from 16 bit little endian format to CPU format */
+#define wlan_le16_to_cpu(x) swap_byte_16(x)
+/** Convert from 32 bit little endian format to CPU format */
+#define wlan_le32_to_cpu(x) swap_byte_32(x)
+/** Convert from 64 bit little endian format to CPU format */
+#define wlan_le64_to_cpu(x) swap_byte_64(x)
+/** Convert to 16 bit little endian format from CPU format */
+#define wlan_cpu_to_le16(x) swap_byte_16(x)
+/** Convert to 32 bit little endian format from CPU format */
+#define wlan_cpu_to_le32(x) swap_byte_32(x)
+/** Convert to 64 bit little endian format from CPU format */
+#define wlan_cpu_to_le64(x) swap_byte_64(x)
+#else
+/** Convert n/w to host */
+#define mlan_ntohs(x) swap_byte_16(x)
+/** Convert host to n/w */
+#define mlan_htons(x) swap_byte_16(x)
+/** Do nothing */
+#define wlan_le16_to_cpu(x) x
+/** Do nothing */
+#define wlan_le32_to_cpu(x) x
+/** Do nothing */
+#define wlan_le64_to_cpu(x) x
+/** Do nothing */
+#define wlan_cpu_to_le16(x) x
+/** Do nothing */
+#define wlan_cpu_to_le32(x) x
+/** Do nothing */
+#define wlan_cpu_to_le64(x) x
+#endif /* BIG_ENDIAN */
+
+/** Convert TxPD to little endian format from CPU format */
+#define endian_convert_TxPD(x);                                         \
+    {                                                                   \
+        (x)->tx_pkt_length = wlan_cpu_to_le16((x)->tx_pkt_length);      \
+        (x)->tx_pkt_offset = wlan_cpu_to_le16((x)->tx_pkt_offset);      \
+        (x)->tx_pkt_type   = wlan_cpu_to_le16((x)->tx_pkt_type);        \
+        (x)->tx_control    = wlan_cpu_to_le32((x)->tx_control);         \
+    }
+
+/** Convert RxPD from little endian format to CPU format */
+#define endian_convert_RxPD(x);                                         \
+    {                                                                   \
+        (x)->rx_pkt_length = wlan_le16_to_cpu((x)->rx_pkt_length);      \
+        (x)->rx_pkt_offset = wlan_le16_to_cpu((x)->rx_pkt_offset);      \
+        (x)->rx_pkt_type   = wlan_le16_to_cpu((x)->rx_pkt_type);        \
+        (x)->seq_num       = wlan_le16_to_cpu((x)->seq_num);            \
+    }
+
+/** Assertion */
+#ifndef ASSERT
+#define ASSERT(cond)                    \
+do {                                    \
+    if (!(cond))                        \
+        return MLAN_STATUS_FAILURE;     \
+} while(0)
+#endif /* !ASSERT */
+
+/** Header alignment */
+#define HEADER_ALIGNMENT                8
+
+/** Upload size */
+#define WLAN_UPLD_SIZE                  (2312)
+
+/** Maximum event buffer size */
+#define MAX_EVENT_SIZE                  1024
+
+/** Maximum buffer size for ARP filter */
+#define ARP_FILTER_MAX_BUF_SIZE     	68
+
+/** 10 seconds */
+#define MRVDRV_TIMER_10S                10000
+/** 5 seconds */
+#define MRVDRV_TIMER_5S                 5000
+/** 1 second */
+#define MRVDRV_TIMER_1S                 1000
+
+/** Maximum size of multicast list */
+#define MRVDRV_MAX_MULTICAST_LIST_SIZE  32
+/** Maximum size of channel */
+#define MRVDRV_MAX_CHANNEL_SIZE         14
+/** Maximum length of SSID */
+#define MRVDRV_MAX_SSID_LENGTH          32
+/** WEP list macros & data structures */
+/** Size of key buffer in bytes */
+#define MRVL_KEY_BUFFER_SIZE_IN_BYTE    16
+/** Maximum length of WPA key */
+#define MRVL_MAX_KEY_WPA_KEY_LENGTH     32
+
+/** Default listen interval */
+#define MLAN_DEFAULT_LISTEN_INTERVAL    10
+
+/** Maximum number of region codes */
+#define MRVDRV_MAX_REGION_CODE          7
+
+/** Default factor for calculating beacon average */
+#define DEFAULT_BCN_AVG_FACTOR          8
+/** Default factor for calculating data average */
+#define DEFAULT_DATA_AVG_FACTOR         8
+
+/** The first valid channel for use */
+#define FIRST_VALID_CHANNEL          0xff
+/** Default Ad-Hoc channel */
+#define DEFAULT_AD_HOC_CHANNEL       6
+/** Default Ad-Hoc channel A */
+#define DEFAULT_AD_HOC_CHANNEL_A     36
+
+/** Power Save definitions */
+/** Ignore multiple DTIM */
+#define MRVDRV_IGNORE_MULTIPLE_DTIM             0xfffe
+/** Minimum multiple DTIM */
+#define MRVDRV_MIN_MULTIPLE_DTIM                1
+/** Maximum multiple DTIM */
+#define MRVDRV_MAX_MULTIPLE_DTIM                5
+/** Default multiple DTIM */
+#define MRVDRV_DEFAULT_MULTIPLE_DTIM            1
+
+/** Number of WEP keys */
+#define MRVL_NUM_WEP_KEY                (4)
+
+/** Default beacon missing timeout */
+#define DEFAULT_BCN_MISS_TIMEOUT            5
+
+/**
+ *  Maximum buffer space for beacons retrieved from scan responses
+ *    4000 has successfully stored up to 40 beacons
+ *    6000 has successfully stored the max scan results (max 64)
+ */
+#define MAX_SCAN_BEACON_BUFFER          6000
+
+/**
+ * @brief Buffer pad space for newly allocated beacons/probe responses
+ *
+ * Beacons are typically 6 bytes longer than an equivalent probe response.
+ *  For each scan response stored, allocate an extra byte pad at the end to
+ *  allow easy expansion to store a beacon in the same memory a probe response
+ *  previously contained
+ */
+#define SCAN_BEACON_ENTRY_PAD          6
+
+/** Scan time specified in the channel TLV for each channel for passive scans */
+#define MRVDRV_PASSIVE_SCAN_CHAN_TIME       200
+
+/** Scan time specified in the channel TLV for each channel for active scans */
+#define MRVDRV_ACTIVE_SCAN_CHAN_TIME        200
+
+/** Scan time specified in the channel TLV for each channel for specific scans */
+#define MRVDRV_SPECIFIC_SCAN_CHAN_TIME      110
+
+/**
+ * Max total scan time in milliseconds
+ * The total scan time should be less than scan command timeout value (10s)
+ */
+#define MRVDRV_MAX_TOTAL_SCAN_TIME     (MRVDRV_TIMER_10S - MRVDRV_TIMER_1S)
+
+/** Offset for GTK as it has version to skip past for GTK */
+#define RSN_GTK_OUI_OFFSET 2
+
+/** If OUI is not found */
+#define MLAN_OUI_NOT_PRESENT 0
+/** If OUI is found */
+#define MLAN_OUI_PRESENT 1
+
+/** RF antenna select 1 */
+#define RF_ANTENNA_1		0x1
+/** RF antenna auto select */
+#define RF_ANTENNA_AUTO		0xFFFF
+
+/** Is cmd_resp, event or data packet received? */
+#define IS_CARD_RX_RCVD(adapter) (adapter->cmd_resp_received || \
+                                  adapter->event_received || \
+                                  adapter->data_received)
+
+/** Type command */
+#define MLAN_TYPE_CMD			1
+/** Type data */
+#define MLAN_TYPE_DATA			0
+/** Type event */
+#define MLAN_TYPE_EVENT			3
+
+/** Maximum numbfer of registers to read for multiple port */
+#define MAX_MP_REGS			40
+/** Maximum port */
+#define MAX_PORT			16
+
+/** Multi port aggregation packet limit */
+#define SDIO_MP_AGGR_DEF_PKT_LIMIT       (8)
+
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+/** Multi port TX aggregation buffer size */
+#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE        (4096)      /* 4K */
+#endif /* SDIO_MULTI_PORT_TX_AGGR */
+
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+/** Multi port RX aggregation buffer size */
+#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE        (4096)      /* 4K */
+#endif /* SDIO_MULTI_PORT_RX_AGGR */
+
+/** Debug command number */
+#define DBG_CMD_NUM	5
+
+/** Max bitmap rate size */
+#define MAX_BITMAP_RATES_SIZE 10
+
+/** Info for debug purpose */
+typedef struct _wlan_dbg
+{
+    /** Number of host to card command failures */
+    t_u32 num_cmd_host_to_card_failure;
+    /** Number of host to card sleep confirm failures */
+    t_u32 num_cmd_sleep_cfm_host_to_card_failure;
+    /** Number of host to card Tx failures */
+    t_u32 num_tx_host_to_card_failure;
+    /** Number of deauthentication events */
+    t_u32 num_event_deauth;
+    /** Number of disassosiation events */
+    t_u32 num_event_disassoc;
+    /** Number of link lost events */
+    t_u32 num_event_link_lost;
+    /** Number of deauthentication commands */
+    t_u32 num_cmd_deauth;
+    /** Number of association comamnd successes */
+    t_u32 num_cmd_assoc_success;
+    /** Number of association command failures */
+    t_u32 num_cmd_assoc_failure;
+    /** Number of Tx timeouts */
+    t_u32 num_tx_timeout;
+    /** Number of command timeouts */
+    t_u32 num_cmd_timeout;
+    /** Timeout command ID */
+    t_u16 timeout_cmd_id;
+    /** Timeout command action */
+    t_u16 timeout_cmd_act;
+    /** List of last command IDs */
+    t_u16 last_cmd_id[DBG_CMD_NUM];
+    /** List of last command actions */
+    t_u16 last_cmd_act[DBG_CMD_NUM];
+    /** Last command index */
+    t_u16 last_cmd_index;
+    /** List of last command response IDs */
+    t_u16 last_cmd_resp_id[DBG_CMD_NUM];
+    /** Last command response index */
+    t_u16 last_cmd_resp_index;
+    /** List of last events */
+    t_u16 last_event[DBG_CMD_NUM];
+    /** Last event index */
+    t_u16 last_event_index;
+} wlan_dbg;
+
+/** Hardware status codes */
+typedef enum _WLAN_HARDWARE_STATUS
+{
+    WlanHardwareStatusReady,
+    WlanHardwareStatusInitializing,
+    WlanHardwareStatusInitdone,
+    WlanHardwareStatusReset,
+    WlanHardwareStatusClosing,
+    WlanHardwareStatusNotReady
+} WLAN_HARDWARE_STATUS;
+
+/** WLAN_802_11_POWER_MODE */
+typedef enum _WLAN_802_11_POWER_MODE
+{
+    Wlan802_11PowerModeCAM,
+    Wlan802_11PowerModePSP
+} WLAN_802_11_POWER_MODE;
+
+/** tx param */
+typedef struct _mlan_tx_param
+{
+    /** next packet length */
+    t_u32 next_pkt_len;
+} mlan_tx_param;
+
+/** PS_STATE */
+typedef enum _PS_STATE
+{
+    PS_STATE_AWAKE,
+    PS_STATE_PRE_SLEEP,
+    PS_STATE_SLEEP_CFM,
+    PS_STATE_SLEEP
+} PS_STATE;
+
+/** Minimum flush timer for win size of 1 is 50 ms */
+#define MIN_FLUSH_TIMER_MS 50
+/** Tx BA stream table */
+typedef struct _TxBAStreamTbl TxBAStreamTbl;
+
+/** Add BA parameter data structure */
+typedef struct
+{
+    /** Window size for initiator */
+    t_u32 tx_win_size;
+    /** Window size for receiver */
+    t_u32 rx_win_size;
+    /** Block ack timeout */
+    t_u32 timeout;
+} add_ba_param_t;
+
+/** Tx aggregation data structure */
+typedef struct _txAggr_t
+{
+    /** AMPDU user */
+    t_u8 ampdu_user;
+    /** AMPDU AP */
+    t_u8 ampdu_ap;
+    /** AMSDU */
+    t_u8 amsdu;
+} tx_aggr_t;
+
+/** RA list table */
+typedef struct _raListTbl raListTbl;
+
+/** RA list table */
+struct _raListTbl
+{
+    /** Pointer to previous node */
+    raListTbl *pprev;
+    /** Pointer to next node */
+    raListTbl *pnext;
+    /** Buffer list head */
+    mlan_list_head buf_head;
+    /** RA list buffer */
+    t_u8 ra[MLAN_MAC_ADDR_LENGTH];
+
+    /** total size of packets in RA list */
+    t_u32 total_pkts_size;
+        /** is 11n enabled */
+    t_u32 is_11n_enabled;
+};
+
+/** TID table */
+typedef struct _tidTbl
+{
+    /** RA list head */
+    mlan_list_head ra_list;
+    /** Current RA list */
+    raListTbl *ra_list_curr;
+} tid_tbl_t;
+
+/** Highest priority setting for a packet (uses voice AC) */
+#define WMM_HIGHEST_PRIORITY  7
+/** HIGHEST priority TID  */
+#define HIGH_PRIO_TID   7
+/** LEAST priority TID    */
+#define LOW_PRIO_TID    0
+
+/** Struct of WMM DESC */
+typedef struct _wmm_desc
+{
+    /** TID table */
+    tid_tbl_t tid_tbl_ptr[MAX_NUM_TID];
+    /** Packets out */
+    t_u32 packets_out[MAX_NUM_TID];
+    /** Spin lock to protect ra_list */
+    t_void *ra_list_spinlock;
+
+    /** AC status */
+    WmmAcStatus_t ac_status[MAX_AC_QUEUES];
+    /** AC downgraded values */
+    mlan_wmm_ac_e ac_down_graded_vals[MAX_AC_QUEUES];
+
+    /** Max driver packet delay sent to the firmware for expiry eval */
+    t_u32 drv_pkt_delay_max;
+
+    /** WMM queue priority table */
+    t_u8 queue_priority[MAX_AC_QUEUES];
+    /** User priority packet transmission control */
+    t_u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1];       /* UP: 0 to 7 */
+
+} wmm_desc_t;
+
+/** Security structure */
+typedef struct _wlan_802_11_security_t
+{
+    /** WPA enabled flag */
+    t_u8 wpa_enabled;
+    /** E-Supplicant enabled flag */
+    t_u8 ewpa_enabled;
+    /** WPA2 enabled flag */
+    t_u8 wpa2_enabled;
+    /** WAPI enabled flag */
+    t_u8 wapi_enabled;
+    /** WAPI key on flag */
+    t_u8 wapi_key_on;
+    /** WEP status */
+    WLAN_802_11_WEP_STATUS wep_status;
+    /** Authentication mode */
+    t_u32 authentication_mode;
+    /** Encryption mode */
+    t_u32 encryption_mode;
+} wlan_802_11_security_t;
+
+/** Current Basic Service Set State Structure */
+typedef struct
+{
+    /** BSS descriptor */
+    BSSDescriptor_t bss_descriptor;
+    /** WMM enable? */
+    t_u8 wmm_enabled;
+    /** Uapsd enable?*/
+    t_u8 wmm_uapsd_enabled;
+    /** Band */
+    t_u8 band;
+    /** Number of rates supported */
+    t_u32 num_of_rates;
+    /** Supported rates*/
+    t_u8 data_rates[WLAN_SUPPORTED_RATES];
+} current_bss_params_t;
+
+/** Sleep_params */
+typedef struct _sleep_params_t
+{
+    /** Sleep parameter error */
+    t_u16 sp_error;
+    /** Sleep parameter offset */
+    t_u16 sp_offset;
+    /** Sleep parameter stable time */
+    t_u16 sp_stable_time;
+    /** Sleep parameter calibration control */
+    t_u8 sp_cal_control;
+    /** Sleep parameter external sleep clock */
+    t_u8 sp_ext_sleep_clk;
+    /** Sleep parameter reserved */
+    t_u16 sp_reserved;
+} sleep_params_t;
+
+/** Sleep_period */
+typedef struct sleep_period_t
+{
+    /** Sleep period */
+    t_u16 period;
+    /** Reserved */
+    t_u16 reserved;
+} sleep_period_t;
+
+/** mrvl_wep_key_t */
+typedef struct _mrvl_wep_key_t
+{
+    /** Length */
+    t_u32 length;
+    /** WEP key index */
+    t_u32 key_index;
+    /** WEP key length */
+    t_u32 key_length;
+    /** WEP keys */
+    t_u8 key_material[MRVL_KEY_BUFFER_SIZE_IN_BYTE];
+} mrvl_wep_key_t;
+
+/** Maximum number of region channel */
+#define MAX_REGION_CHANNEL_NUM  2
+
+/** Chan-Freq-TxPower mapping table*/
+typedef struct _chan_freq_power_t
+{
+    /** Channel Number */
+    t_u16 channel;
+    /** Frequency of this Channel */
+    t_u32 freq;
+    /** Max allowed Tx power level */
+    t_u16 max_tx_power;
+    /** TRUE:channel unsupported;  FLASE:supported */
+    t_u8 unsupported;
+} chan_freq_power_t;
+
+/** Region-band mapping table */
+typedef struct _region_chan_t
+{
+    /** TRUE if this entry is valid */
+    t_u8 valid;
+    /** Region code for US, Japan ... */
+    t_u8 region;
+    /** Band B/G/A, used for BAND_CONFIG cmd */
+    t_u8 band;
+    /** Actual No. of elements in the array below */
+    t_u8 num_cfp;
+    /** chan-freq-txpower mapping table */
+    chan_freq_power_t *pcfp;
+} region_chan_t;
+
+/** State of 11d */
+typedef enum
+{
+    DISABLE_11D = 0,
+    ENABLE_11D = 1,
+} state_11d_t;
+
+/** Domain regulatory information */
+typedef struct _wlan_802_11d_domain_reg
+{
+    /** Country Code */
+    t_u8 country_code[COUNTRY_CODE_LEN];
+    /** No. of subband */
+    t_u8 no_of_sub_band;
+    /** Subband data */
+    IEEEtypes_SubbandSet_t sub_band[MRVDRV_MAX_SUBBAND_802_11D];
+} wlan_802_11d_domain_reg_t;
+
+/** Data for state machine */
+typedef struct _wlan_802_11d_state
+{
+    /** True for enabling 11D */
+    state_11d_t enable_11d;
+    /** True for user enabling 11D */
+    state_11d_t user_enable_11d;
+} wlan_802_11d_state_t;
+
+/** Vendor specific configuration IE */
+typedef struct _vendor_spec_cfg_ie
+{
+    /** Bit 0-2: scan/assoc/ad-hoc */
+    t_u16 mask;
+    /** Optional, 0/1: gen_ie/vs_ie */
+    t_u16 flag;
+    /** Information element */
+    t_u8 ie[MLAN_MAX_VSIE_LEN];
+} vendor_spec_cfg_ie;
+
+/** Data structure for WPS information */
+typedef struct
+{
+    /** Session enable flag */
+    t_u8 session_enable;
+} wps_t;
+
+/** mlan_operations data structure */
+typedef struct _mlan_operations
+{
+    /** cmd init handler */
+    mlan_status(*init_cmd) (IN t_void * priv, IN t_u8 first_sta);
+    /** ioctl handler */
+    mlan_status(*ioctl) (t_void * adapter, pmlan_ioctl_req pioctl_req);
+    /** cmd handler */
+    mlan_status(*prepare_cmd) (IN t_void * priv,
+                               IN t_u16 cmd_no,
+                               IN t_u16 cmd_action,
+                               IN t_u32 cmd_oid,
+                               IN t_void * pioctl_buf,
+                               IN t_void * pdata_buf, IN t_void * pcmd_buf);
+    /** cmdresp handler */
+    mlan_status(*process_cmdresp) (IN t_void * priv,
+                                   IN t_u16 cmdresp_no,
+                                   IN t_void * pcmd_buf, IN t_void * pioctl);
+    /** rx handler */
+    mlan_status(*process_rx_packet) (IN t_void * adapter,
+                                     IN pmlan_buffer pmbuf);
+    /** event handler */
+    mlan_status(*process_event) (IN t_void * priv);
+    /** txpd handler */
+    t_void *(*process_txpd) (IN t_void * priv, IN pmlan_buffer pmbuf);
+    /** bss_type */
+    t_u8 bss_type;
+} mlan_operations;
+
+/** Private structure for MLAN */
+typedef struct _mlan_private
+{
+    /** Pointer to mlan_adapter */
+    struct _mlan_adapter *adapter;
+    /** BSS number */
+    t_u8 bss_num;
+    /** BSS type */
+    t_u8 bss_type;
+    /** BSS Priority */
+    t_u8 bss_priority;
+    /** Frame type */
+    t_u8 frame_type;
+    /** MAC address information */
+    t_u8 curr_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Media connection status */
+    t_u8 media_connected;
+
+    /** Current packet filter */
+    t_u16 curr_pkt_filter;
+    /** Infrastructure mode */
+    t_u32 bss_mode;
+
+    /** Tx packet control */
+    t_u32 pkt_tx_ctrl;
+    /** Gen NULL pkg */
+    t_u16 gen_null_pkg;
+
+    /** Tx power level */
+    t_u16 tx_power_level;
+    /** Maximum Tx power level */
+    t_u8 max_tx_power_level;
+    /** Minimum Tx power level */
+    t_u8 min_tx_power_level;
+    /** Tx rate */
+    t_u8 tx_rate;
+    /** tx ht_info */
+    t_u8 tx_htinfo;
+    /** rxpd_htinfo */
+    t_u8 rxpd_htinfo;
+    /** Rx PD rate */
+    t_u8 rxpd_rate;
+    /** Rate bitmap */
+    t_u16 rate_bitmap;
+    /** Bitmap rates */
+    t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
+    /** Data rate */
+    t_u32 data_rate;
+    /** Automatic data rate flag */
+    t_u8 is_data_rate_auto;
+    /** Factor for calculating beacon average */
+    t_u16 bcn_avg_factor;
+    /** Factor for calculating data average */
+    t_u16 data_avg_factor;
+    /** Last data RSSI */
+    t_s16 data_rssi_last;
+    /** Last data Noise Floor */
+    t_s16 data_nf_last;
+    /** Average data RSSI */
+    t_s16 data_rssi_avg;
+    /** Averag data Noise Floor */
+    t_s16 data_nf_avg;
+    /** Last beacon RSSI */
+    t_s16 bcn_rssi_last;
+    /** Last beacon Noise Floor */
+    t_s16 bcn_nf_last;
+    /** Average beacon RSSI */
+    t_s16 bcn_rssi_avg;
+    /** Average beacon Noise Floor */
+    t_s16 bcn_nf_avg;
+
+    /** Attempted BSS descriptor */
+    BSSDescriptor_t *pattempted_bss_desc;
+    /** Prevous SSID */
+    mlan_802_11_ssid prev_ssid;
+    /** Previous BSSID */
+    t_u8 prev_bssid[MLAN_MAC_ADDR_LENGTH];
+
+    /** Current SSID/BSSID related parameters*/
+    current_bss_params_t curr_bss_params;
+
+    /** Beacon period */
+    t_u16 beacon_period;
+    /** Listen interval */
+    t_u16 listen_interval;
+    /** ATIM window */
+    t_u16 atim_window;
+
+    /** AdHoc channel */
+    t_u8 adhoc_channel;
+    /** AdHoc link sensed flag */
+    t_u8 adhoc_is_link_sensed;
+    /** AdHoc G rate */
+    t_u8 adhoc_state;
+    /** AdHoc autoselect */
+    t_u8 adhoc_auto_sel;
+
+    /** Security related */
+    /** Encryption parameter */
+    wlan_802_11_security_t sec_info;
+    /** WEP keys */
+    mrvl_wep_key_t wep_key[MRVL_NUM_WEP_KEY];
+    /** Current WEP key index */
+    t_u16 wep_key_curr_index;
+    /** Encryption Key*/
+    t_u8 wpa_ie[256];
+    /** WPA IE length */
+    t_u8 wpa_ie_len;
+    /** GTK set flag */
+    t_u8 wpa_is_gtk_set;
+    /** AES key material */
+    HostCmd_DS_802_11_KEY_MATERIAL aes_key;
+    /** WAPI IE */
+    t_u8 wapi_ie[256];
+    /** WAPI IE length */
+    t_u8 wapi_ie_len;
+
+    /** Advanced Encryption Standard */
+    t_u8 adhoc_aes_enabled;
+
+    /** WMM required */
+    t_u8 wmm_required;
+    /** WMM enabled */
+    t_u8 wmm_enabled;
+    /** WMM qos info */
+    t_u8 wmm_qosinfo;
+    /** WMM related variable*/
+    wmm_desc_t wmm;
+
+    /** Pointer to the Transmit BA stream table*/
+    mlan_list_head tx_ba_stream_tbl_ptr;
+    /** Pointer to the priorities for AMSDU/AMPDU table*/
+    tx_aggr_t aggr_prio_tbl[MAX_NUM_TID];
+    /** Pointer to the priorities for AMSDU/AMPDU table*/
+    t_u8 addba_reject[MAX_NUM_TID];
+    /** Struct to store ADDBA parameters */
+    add_ba_param_t add_ba_param;
+    /** Pointer to the Receive Reordering table*/
+    mlan_list_head rx_reorder_tbl_ptr;
+    /** Lock for Rx packets */
+    t_void *rx_pkt_lock;
+
+    /** Buffer to store the association response for application retrieval */
+    t_u8 assoc_rsp_buf[MRVDRV_ASSOC_RSP_BUF_SIZE];
+    /** Length of the data stored in assoc_rsp_buf */
+    t_u32 assoc_rsp_size;
+
+    /** Generice IEEE IEs passed from the application to be inserted into the
+     *    association request to firmware 
+     */
+    t_u8 gen_ie_buf[MRVDRV_GENIE_BUF_SIZE];
+    /** Length of the data stored in gen_ie_buf */
+    t_u8 gen_ie_buf_len;
+    /** Vendor specific configuration IEs */
+    vendor_spec_cfg_ie vs_ie[MLAN_MAX_VSIE_NUM];
+
+    /** Buffer for TLVs passed from the application to be inserted into the
+     *    association request to firmware 
+     */
+    t_u8 mrvl_assoc_tlv_buf[MRVDRV_ASSOC_TLV_BUF_SIZE];
+    /** Length of the data stored in mrvl_assoc_tlv_buf */
+    t_u8 mrvl_assoc_tlv_buf_len;
+    t_u8 *pcurr_bcn_buf;
+    t_u32 curr_bcn_size;
+    t_void *curr_bcn_buf_lock;
+
+    /** WPS */
+    wps_t wps;
+    /** function table */
+    mlan_operations ops;
+
+} mlan_private, *pmlan_private;
+
+/** BA stream status */
+typedef enum
+{
+    BA_STREAM_NOT_SETUP = 0,
+    BA_STREAM_SETUP_INPROGRESS,
+    BA_STREAM_SETUP_COMPLETE
+} baStatus_e;
+
+/** Tx BA stream table */
+struct _TxBAStreamTbl
+{
+    /** TxBAStreamTbl previous node */
+    TxBAStreamTbl *pprev;
+    /** TxBAStreamTbl next node */
+    TxBAStreamTbl *pnext;
+    /** TID */
+    int tid;
+    /** RA */
+    t_u8 ra[MLAN_MAC_ADDR_LENGTH];
+    /** BA stream status */
+    baStatus_e ba_status;
+};
+
+/** RX reorder table */
+typedef struct _RxReorderTbl RxReorderTbl;
+
+typedef struct
+{
+    /** Timer for flushing */
+    t_void *timer;
+    /** Timer set flag */
+    t_u8 timer_is_set;
+    /** RxReorderTbl ptr */
+    RxReorderTbl *ptr;
+    /** Priv pointer */
+    mlan_private *priv;
+} reorder_tmr_cnxt_t;
+
+/** RX reorder table */
+struct _RxReorderTbl
+{
+    /** RxReorderTbl previous node */
+    RxReorderTbl *pprev;
+    /** RxReorderTbl next node */
+    RxReorderTbl *pnext;
+    /** TID */
+    int tid;
+    /** TA */
+    t_u8 ta[MLAN_MAC_ADDR_LENGTH];
+    /** Start window */
+    int start_win;
+    /** Window size */
+    int win_size;
+    /** Pointer to pointer to RxReorderTbl */
+    t_void **rx_reorder_ptr;
+    /** Timer context */
+    reorder_tmr_cnxt_t timer_context;
+};
+
+/** BSS priority node */
+typedef struct _mlan_bssprio_node mlan_bssprio_node;
+
+/** BSS priority node */
+struct _mlan_bssprio_node
+{
+    /** Pointer to previous node */
+    mlan_bssprio_node *pprev;
+    /** Pointer to next node */
+    mlan_bssprio_node *pnext;
+    /** Pointer to priv */
+    pmlan_private priv;
+};
+
+/** BSS priority table */
+typedef struct _mlan_bssprio_tbl mlan_bssprio_tbl;
+
+/** BSS priority table */
+struct _mlan_bssprio_tbl
+{
+    /** BSS priority list head */
+    mlan_list_head bssprio_head;
+    /** Current priority node */
+    mlan_bssprio_node *bssprio_cur;
+};
+
+/** cmd_ctrl_node */
+typedef struct _cmd_ctrl_node cmd_ctrl_node;
+
+/** _cmd_ctrl_node */
+struct _cmd_ctrl_node
+{
+    /** Pointer to previous node */
+    cmd_ctrl_node *pprev;
+    /** Pointer to next node */
+    cmd_ctrl_node *pnext;
+    /** Pointer to priv */
+    pmlan_private priv;
+    /** Command OID for sub-command use */
+    t_u32 cmd_oid;
+    /** Command flag */
+    t_u32 cmd_flag;
+    /** Pointer to mlan_buffer */
+    mlan_buffer *cmdbuf;
+    /** Pointer to mlan_buffer */
+    mlan_buffer *respbuf;
+    /** Command parameter */
+    t_void *pdata_buf;
+    /** Pointer to mlan_ioctl_req if command is from IOCTL */
+    t_void *pioctl_buf;
+    /** pre_allocated mlan_buffer for cmd */
+    mlan_buffer *pmbuf;
+};
+
+/** 802.11h State information kept in the 'mlan_adapter' of the driver */
+typedef struct
+{
+    t_u32 is_11h_enabled;   /**< Enables/disables 11h in the driver (adhoc start) */
+    t_u32 is_11h_active;    /**< Indicates whether 11h is active in the firmware */
+    t_u32 tx_disabled;      /**< Set when driver receives a STOP TX event from fw */
+
+    /** Minimum TX Power capability sent to FW for 11h use and fw power control */
+    t_s8 min_tx_power_capability;
+
+    /** Maximum TX Power capability sent to FW for 11h use and fw power control */
+    t_s8 max_tx_power_capability;
+
+    /** User provisioned local power constraint sent in association requests */
+    t_s8 usr_def_power_constraint;
+
+    /** Quiet IE */
+    IEEEtypes_Quiet_t quiet_ie;
+
+} wlan_11h_state_t;
+
+/**
+ * @brief Driver measurement state held in 'mlan_adapter' structure
+ *  
+ *  Used to record a measurement request that the driver is pending on 
+ *    the result (received measurement report).
+ */
+typedef struct
+{
+    /**
+     * Dialog token of a pending measurement request/report.  Used to
+     *   block execution while waiting for the specific dialog token
+     */
+    t_u8 meas_rpt_pend_on;
+
+    /**
+     * Measurement report received from the firmware that we were pending on
+     */
+    HostCmd_DS_MEASUREMENT_REPORT meas_rpt_returned;
+
+} wlan_meas_state_t;
+
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+/** data structure for SDIO MPA TX */
+typedef struct _sdio_mpa_tx
+{
+        /** allocated buf for tx aggreation */
+    t_u8 *head_ptr;
+        /** multiport tx aggregation buffer pointer */
+    t_u8 *buf;
+        /** multiport tx aggregation buffer length */
+    t_u32 buf_len;
+        /** multiport tx aggregation packet count */
+    t_u32 pkt_cnt;
+        /** multiport tx aggregation ports */
+    t_u16 ports;
+        /** multiport tx aggregation starting port */
+    t_u16 start_port;
+        /** multiport tx aggregation enable/disable flag */
+    t_u8 enabled;
+        /** multiport tx aggregation buffer size */
+    t_u32 buf_size;
+        /** multiport tx aggregation pkt aggr limit */
+    t_u32 pkt_aggr_limit;
+} sdio_mpa_tx;
+#endif
+
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+/** data structure for SDIO MPA RX */
+typedef struct _sdio_mpa_rx
+{
+        /** allocated buf for rx aggreation */
+    t_u8 *head_ptr;
+        /** multiport rx aggregation buffer pointer */
+    t_u8 *buf;
+        /** multiport rx aggregation buffer length */
+    t_u32 buf_len;
+        /** multiport rx aggregation packet count */
+    t_u32 pkt_cnt;
+        /** multiport rx aggregation ports */
+    t_u16 ports;
+        /** multiport rx aggregation starting port */
+    t_u16 start_port;
+
+        /** multiport rx aggregation mbuf array */
+    pmlan_buffer mbuf_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
+        /** multiport rx aggregation pkt len array */
+    t_u32 len_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
+
+        /** multiport rx aggregation enable/disable flag */
+    t_u8 enabled;
+        /** multiport rx aggregation buffer size */
+    t_u32 buf_size;
+        /** multiport rx aggregation pkt aggr limit */
+    t_u32 pkt_aggr_limit;
+} sdio_mpa_rx;
+#endif /* SDIO_MULTI_PORT_RX_AGGR */
+
+/** Adapter data structure for MLAN */
+typedef struct _mlan_adapter
+{
+    /** MOAL handle structure */
+    t_void *pmoal_handle;
+    /** Private pointer */
+    pmlan_private priv[MLAN_MAX_BSS_NUM];
+    /** Priority table for bss */
+    mlan_bssprio_tbl bssprio_tbl[MLAN_MAX_BSS_NUM];
+    /** Callback table */
+    mlan_callbacks callbacks;
+    /** mlan_lock for init/shutdown */
+    t_void *pmlan_lock;
+    /** main_proc_lock for main_process */
+    t_void *pmain_proc_lock;
+    /** mlan_processing */
+    t_u32 mlan_processing;
+    /** Max tx buf size */
+    t_u16 max_tx_buf_size;
+    /** Tx buf size */
+    t_u16 tx_buf_size;
+    /** IO port */
+    t_u32 ioport;
+
+    /** STATUS variables */
+    WLAN_HARDWARE_STATUS hw_status;
+    /** PnP SUPPORT */
+    t_u8 surprise_removed;
+
+    /** Radio on flag */
+    t_u16 radio_on;
+
+    /** Firmware release number */
+    t_u32 fw_release_number;
+
+    /** Number of antenna used */
+    t_u16 number_of_antenna;
+
+    /** Firmware capability information */
+    t_u32 fw_cap_info;
+
+    /** Interrupt status */
+    t_u8 sdio_ireg;
+    /** SDIO multiple port read bitmap */
+    t_u16 mp_rd_bitmap;
+    /** SDIO multiple port write bitmap */
+    t_u16 mp_wr_bitmap;
+    /** SDIO end port from txbufcfg */
+    t_u16 mp_end_port;
+    /** SDIO port mask calculated based on txbufcfg end port */
+    t_u16 mp_data_port_mask;
+    /** Current available port for read */
+    t_u8 curr_rd_port;
+    /** Current available port for write */
+    t_u8 curr_wr_port;
+    /** Array to store values of SDIO multiple port group registers */
+    t_u8 *mp_regs;
+    /** allocated buf to read SDIO multiple port group registers */
+    t_u8 *mp_regs_buf;
+    /** Array to store data transfer eligibility based on tid (QoS-over-SDIO) */
+    t_u8 tx_eligibility[MAX_NUM_TID];
+
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+        /** data structure for SDIO MPA TX */
+    sdio_mpa_tx mpa_tx;
+#endif                          /* SDIO_MULTI_PORT_TX_AGGR */
+
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+        /** data structure for SDIO MPA RX */
+    sdio_mpa_rx mpa_rx;
+#endif                          /* SDIO_MULTI_PORT_RX_AGGR */
+
+    /** Event cause */
+    t_u32 event_cause;
+    /** Event buffer */
+    pmlan_buffer pmlan_buffer_event;
+    /** Upload length */
+    t_u32 upld_len;
+    /** Upload buffer*/
+    t_u8 upld_buf[WLAN_UPLD_SIZE];
+    /** Data sent: 
+     *       TRUE - Data is sent to fw, no Tx Done received
+     *       FALSE - Tx done received for previous Tx
+     */
+    t_u8 data_sent;
+    /** CMD sent: 
+     *       TRUE - CMD is sent to fw, no CMD Done received
+     *       FALSE - CMD done received for previous CMD
+     */
+    t_u8 cmd_sent;
+    /** CMD Response received: 
+     *       TRUE - CMD is response is received from fw, and yet to process
+     *       FALSE - No cmd response to process
+     */
+    t_u8 cmd_resp_received;
+    /** Event received: 
+     *       TRUE - Event received from fw, and yet to process
+     *       FALSE - No events to process
+     */
+    t_u8 event_received;
+
+    /** Data received:
+     *       TRUE - Event received from fw, and yet to process
+     *       FALSE - No events to process
+     */
+    t_u8 data_received;
+
+    /** Command-related variables */
+    /** Command sequence number */
+    t_u16 seq_num;
+    /** Command controller nodes */
+    cmd_ctrl_node *cmd_pool;
+    /** Current Command */
+    cmd_ctrl_node *curr_cmd;
+    /** mlan_lock for command */
+    t_void *pmlan_cmd_lock;
+    /** Number of command timeouts */
+    t_u32 num_cmd_timeout;
+    /** Last init fw command id */
+    t_u16 last_init_cmd;
+    /** Command timer */
+    t_void *pmlan_cmd_timer;
+    /** Command timer set flag */
+    t_u8 cmd_timer_is_set;
+
+    /** Command Queues */
+    /** Free command buffers */
+    mlan_list_head cmd_free_q;
+    /** Pending command buffers */
+    mlan_list_head cmd_pending_q;
+    /** Command queue for scanning */
+    mlan_list_head scan_pending_q;
+    /** mlan_processing */
+    t_u32 scan_processing;
+
+    /** Region code */
+    t_u16 region_code;
+    /** Region Channel data */
+    region_chan_t region_channel[MAX_REGION_CHANNEL_NUM];
+    /** FSM variable for 11d support */
+    wlan_802_11d_state_t state_11d;
+    /** Universal Channel data */
+    region_chan_t universal_channel[MAX_REGION_CHANNEL_NUM];
+    /** Parsed region channel */
+    parsed_region_chan_11d_t parsed_region_chan;
+    /** 11D and Domain Regulatory Data */
+    wlan_802_11d_domain_reg_t domain_reg;
+    /** FSM variable for 11h support */
+    wlan_11h_state_t state_11h;
+    /** FSM variable for MEAS support */
+    wlan_meas_state_t state_meas;
+    /** Scan table */
+    BSSDescriptor_t *pscan_table;
+
+    /** Number of records in the scan table */
+    t_u32 num_in_scan_table;
+    /** Scan probes */
+    t_u16 scan_probes;
+
+    /** Scan type */
+    t_u8 scan_type;
+    /** Scan mode */
+    t_u32 scan_mode;
+    /** Specific scan time */
+    t_u16 specific_scan_time;
+    /** Active scan time */
+    t_u16 active_scan_time;
+    /** Passive scan time */
+    t_u16 passive_scan_time;
+
+    /** Beacon buffer */
+    t_u8 bcn_buf[MAX_SCAN_BEACON_BUFFER];
+    /** Pointer to valid beacon buffer end */
+    t_u8 *pbcn_buf_end;
+
+    /** F/W supported bands */
+    t_u8 fw_bands;
+    /** User selected band to start adhoc network */
+    t_u8 adhoc_start_band;
+    /** User selected bands */
+    t_u8 config_bands;
+    /** Pointer to channel list last sent to the firmware for scanning */
+    ChanScanParamSet_t *pscan_channels;
+
+    /** Tx lock flag */
+    t_u8 tx_lock_flag;
+
+    /** sleep_params_t */
+    sleep_params_t sleep_params;
+    /** sleep_period_t (Enhanced Power Save) */
+    sleep_period_t sleep_period;
+
+    /** Power Save mode */
+    /**
+      * Wlan802_11PowerModeCAM = disable
+      * Wlan802_11PowerModePSP = enable
+      */
+    t_u16 ps_mode;
+    /** Power Save state */
+    t_u32 ps_state;
+    /** Need to wakeup flag */
+    t_u8 need_to_wakeup;
+
+    /** Multiple DTIM */
+    t_u16 multiple_dtim;
+    /** Local listen interval */
+    t_u16 local_listen_interval;
+    /** Null packet interval */
+    t_u16 null_pkt_interval;
+
+    /** Power save confirm sleep command buffer */
+    pmlan_buffer psleep_cfm;
+    /** Beacon miss timeout */
+    t_u16 bcn_miss_time_out;
+
+    /** AdHoc awake period */
+    t_u16 adhoc_awake_period;
+
+    /** Deep Sleep flag */
+    t_u8 is_deep_sleep;
+
+        /** delay null pkt flag */
+    t_u8 delay_null_pkt;
+    /** Delay to PS in milliseconds */
+    t_u16 delay_to_ps;
+    /** Enhanced PS mode */
+    t_u16 enhanced_ps_mode;
+    /** Device wakeup required flag */
+    t_u8 pm_wakeup_card_req;
+
+    /** Number of wakeup tries */
+    t_u32 pm_wakeup_fw_try;
+
+    /** Host Sleep configured flag */
+    t_u8 is_hs_configured;
+    /** Host Sleep configuration */
+    HostCmd_DS_802_11_HS_CFG_ENH hs_cfg;
+    /** Host Sleep activated flag */
+    t_u8 hs_activated;
+    /** Event body */
+    t_u8 event_body[MAX_EVENT_SIZE];
+    /** 802.11n device capabilities */
+    t_u32 hw_dot_11n_dev_cap;
+    /** Device support for MIMO abstraction of MCSs */
+    t_u8 hw_dev_mcs_support;
+    /** 802.11n Device Capabilities */
+    t_u32 usr_dot_11n_dev_cap;
+    /** MIMO abstraction of MCSs supported by device */
+    t_u8 usr_dev_mcs_support;
+    /** Enable 11n support for adhoc start */
+    t_u8 adhoc_11n_enabled;
+    /** Adhoc Secondary Channel Offset */
+    t_u8 chan_offset;
+
+#ifdef MFG_CMD_SUPPORT
+    t_u32 mfg_mode;
+#endif
+    /** Debug */
+    wlan_dbg dbg;
+
+    /** ARP filter buffer */
+    t_u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE];
+    /** ARP filter buffer size */
+    t_u32 arp_filter_size;
+
+} mlan_adapter, *pmlan_adapter;
+
+/* Function prototype */
+/** Download firmware */
+mlan_status wlan_dnld_fw(IN pmlan_adapter pmadapter, IN pmlan_fw_image pmfw);
+
+/** Initialize firmware */
+mlan_status wlan_init_fw(IN pmlan_adapter pmadapter);
+
+/** Initialize firmware complete */
+mlan_status wlan_init_fw_complete(IN pmlan_adapter pmadapter);
+
+/** Shutdown firmware */
+mlan_status wlan_shutdown_fw(IN pmlan_adapter pmadapter);
+
+/** Shutdown firmware complete */
+mlan_status wlan_shutdown_fw_complete(IN pmlan_adapter pmadapter);
+
+/** Receive event */
+mlan_status wlan_recv_event(pmlan_private priv,
+                            mlan_event_id event_id, t_void * pmevent);
+
+/** Initialize mlan_adapter structure */
+t_void wlan_init_adapter(IN pmlan_adapter pmadapter);
+
+/** Deletes the BSS priority table */
+t_void wlan_delete_bsspriotbl(pmlan_private priv);
+
+/** Initialize mlan_private structure */
+t_void wlan_init_priv(IN pmlan_private priv);
+
+/** Process event */
+mlan_status wlan_process_event(pmlan_adapter pmadapter);
+
+/** Prepare command */
+mlan_status wlan_prepare_cmd(IN pmlan_private priv,
+                             IN t_u16 cmd_no,
+                             IN t_u16 cmd_action,
+                             IN t_u32 cmd_oid,
+                             IN t_void * pioctl_buf, IN t_void * pdata_buf);
+
+/** cmd timeout handler */
+t_void wlan_cmd_timeout_func(t_void * FunctionContext);
+/** process host cmd */
+mlan_status wlan_misc_ioctl_host_cmd(IN pmlan_adapter pmadapter,
+                                     IN pmlan_ioctl_req pioctl_req);
+/** process init/shutdown cmd*/
+mlan_status wlan_misc_ioctl_init_shutdown(IN pmlan_adapter pmadapter,
+                                          IN pmlan_ioctl_req pioctl_req);
+/** process debug info */
+mlan_status wlan_get_info_debug_info(IN pmlan_adapter pmadapter,
+                                     IN pmlan_ioctl_req pioctl_req);
+
+/** Free adapter */
+t_void wlan_free_adapter(pmlan_adapter pmadapter);
+/** Allocate command buffer */
+mlan_status wlan_alloc_cmd_buffer(IN mlan_adapter * pmadapter);
+/** Free command buffer */
+mlan_status wlan_free_cmd_buffer(IN mlan_adapter * pmadapter);
+/** Request command lock */
+t_void wlan_request_cmd_lock(mlan_adapter * pmadapter);
+/** Release command lock */
+t_void wlan_release_cmd_lock(mlan_adapter * pmadapter);
+/**Cancel pending command */
+void wlan_cancel_all_pending_cmd(pmlan_adapter pmadapter);
+/**Cancel pending ioctl */
+void wlan_cancel_pending_ioctl(pmlan_adapter pmadapter,
+                               pmlan_ioctl_req pioctl_req);
+
+/** Insert command to free queue */
+t_void wlan_insert_cmd_to_free_q(IN mlan_adapter * pmadapter,
+                                 IN cmd_ctrl_node * pcmd_node);
+
+/** Insert command to pending queue */
+t_void wlan_insert_cmd_to_pending_q(IN mlan_adapter * pmadapter,
+                                    IN cmd_ctrl_node * pcmd_node,
+                                    IN t_u32 addtail);
+
+/** Execute next command */
+mlan_status wlan_exec_next_cmd(mlan_adapter * pmadapter);
+/** Proecess command response */
+mlan_status wlan_process_cmdresp(mlan_adapter * pmadapter);
+/** Handle received packet, has extra handling for aggregate packets */
+mlan_status wlan_handle_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf);
+/** Process transmission */
+mlan_status wlan_process_tx(pmlan_private priv, pmlan_buffer pmbuf,
+                            mlan_tx_param * tx_param);
+/** Transmit a null data packet */
+mlan_status wlan_send_null_packet(pmlan_private priv, t_u8 flags);
+
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+mlan_status wlan_alloc_sdio_mpa_buffers(IN mlan_adapter * pmadapter,
+                                        t_u32 mpa_tx_buf_size,
+                                        t_u32 mpa_rx_buf_size);
+
+mlan_status wlan_free_sdio_mpa_buffers(IN mlan_adapter * pmadapter);
+#endif
+
+/** Process write data complete */
+mlan_status wlan_write_data_complete(pmlan_adapter pmlan_adapter,
+                                     pmlan_buffer pmbuf, mlan_status status);
+/** Process receive packet complete */
+mlan_status wlan_recv_packet_complete(t_void * pmlan_adapter,
+                                      pmlan_buffer pmbuf, mlan_status status);
+/** Clean Tx Rx queues */
+t_void wlan_clean_txrx(pmlan_private priv);
+
+/** Check if this is the last packet */
+t_u8 wlan_check_last_packet_indication(pmlan_private priv);
+
+/** function to allocate a mlan_buffer */
+pmlan_buffer wlan_alloc_mlan_buffer(pmlan_callbacks pcb, t_u32 data_len);
+/** function to free a mlan_buffer */
+t_void wlan_free_mlan_buffer(pmlan_callbacks pcb, pmlan_buffer pmbuf);
+
+/** Check Power Save condition */
+t_void wlan_check_ps_cond(mlan_adapter * pmadapter);
+
+/** Process sleep confirm command response */
+void wlan_process_sleep_confirm_resp(pmlan_adapter pmadapter, t_u8 * pbuf,
+                                     t_u32 len);
+
+/** Perform hs related activities on receving the power up interrupt */
+void wlan_process_hs_config(pmlan_adapter pmadapter);
+
+mlan_status wlan_pm_reset_card(pmlan_adapter adapter);
+mlan_status wlan_pm_wakeup_card(pmlan_adapter pmadapter);
+
+t_void wlan_host_sleep_activated_event(pmlan_private priv, t_u8 activated);
+/** Handles the command response of hs_cfg */
+mlan_status wlan_ret_802_11_hs_cfg(IN pmlan_private pmpriv,
+                                   IN HostCmd_DS_COMMAND * resp,
+                                   IN mlan_ioctl_req * pioctl_buf);
+/** Sends HS_WAKEUP event to applications */
+t_void wlan_host_sleep_wakeup_event(pmlan_private priv);
+
+/** Process received packet */
+mlan_status wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf);
+/** ioctl handler for station mode */
+mlan_status mlan_sta_ioctl(t_void * adapter, pmlan_ioctl_req pioctl_req);
+
+/** cmd handler for station mode */
+mlan_status mlan_sta_prepare_cmd(IN t_void * priv,
+                                 IN t_u16 cmd_no,
+                                 IN t_u16 cmd_action,
+                                 IN t_u32 cmd_oid,
+                                 IN t_void * pioctl_buf,
+                                 IN t_void * pdata_buf, IN t_void * pcmd_buf);
+
+/** cmdresp handler for station mode */
+mlan_status mlan_process_sta_cmdresp(IN t_void * priv,
+                                     IN t_u16 cmdresp_no,
+                                     IN t_void * pcmd_buf, IN t_void * pioctl);
+
+/** rx handler for station mode */
+mlan_status mlan_process_sta_rx_packet(IN t_void * adapter,
+                                       IN pmlan_buffer pmbuf);
+
+/** event handler for station mode */
+mlan_status mlan_process_sta_event(IN t_void * priv);
+
+/** fill txpd for station mode */
+t_void *mlan_process_sta_txpd(IN t_void * priv, IN pmlan_buffer pmbuf);
+
+/** send init cmd to firmware for station mode */
+mlan_status mlan_sta_init_cmd(IN t_void * priv, IN t_u8 first_sta);
+
+/** Scan for networks */
+mlan_status wlan_scan_networks(IN mlan_private * pmpriv,
+                               IN t_void * pioctl_buf,
+                               IN const wlan_user_scan_cfg * puser_scan_in);
+
+/** Scan for specific SSID */
+mlan_status wlan_scan_specific_ssid(IN mlan_private * pmpriv,
+                                    IN t_void * pioctl_buf,
+                                    IN mlan_802_11_ssid * preq_ssid);
+
+/** Scan command handler */
+mlan_status wlan_cmd_802_11_scan(IN pmlan_private pmpriv,
+                                 IN HostCmd_DS_COMMAND * pcmd,
+                                 IN t_void * pdata_buf);
+
+/** Queue scan command handler */
+t_void wlan_queue_scan_cmd(IN mlan_private * pmpriv,
+                           IN cmd_ctrl_node * pcmd_node);
+
+/** Handler for scan command response */
+mlan_status wlan_ret_802_11_scan(IN pmlan_private pmpriv,
+                                 IN HostCmd_DS_COMMAND * resp,
+                                 IN t_void * pioctl_buf);
+
+/** Find an SSID in a list */
+t_s32 wlan_find_ssid_in_list(IN pmlan_private pmpriv,
+                             IN mlan_802_11_ssid * ssid,
+                             IN t_u8 * bssid, IN t_u32 mode);
+
+/** Find a BSSID in a list */
+t_s32 wlan_find_bssid_in_list(IN mlan_private * pmpriv,
+                              IN t_u8 * bssid, IN t_u32 mode);
+
+/** Find best network */
+mlan_status wlan_find_best_network(IN mlan_private * pmpriv,
+                                   OUT mlan_ssid_bssid * preq_ssid_bssid);
+
+/** Compare two SSIDs */
+t_s32 wlan_ssid_cmp(IN pmlan_adapter pmadapter,
+                    IN mlan_802_11_ssid * ssid1, IN mlan_802_11_ssid * ssid2);
+
+/** Associate */
+mlan_status wlan_associate(IN mlan_private * pmpriv,
+                           IN t_void * pioctl_buf,
+                           IN BSSDescriptor_t * pBSSDesc);
+
+/** Associate command handler */
+mlan_status wlan_cmd_802_11_associate(IN mlan_private * pmpriv,
+                                      IN HostCmd_DS_COMMAND * cmd,
+                                      IN t_void * pdata_buf);
+
+/** Handler for association command response */
+mlan_status wlan_ret_802_11_associate(IN mlan_private * pmpriv,
+                                      IN HostCmd_DS_COMMAND * resp,
+                                      IN t_void * pioctl_buf);
+
+/** Reset connected state */
+t_void wlan_reset_connect_state(pmlan_private priv);
+
+t_void wlan_2040_coex_event(pmlan_private pmpriv);
+
+/** convert band to radio type */
+t_u8 wlan_band_to_radio_type(IN t_u8 band);
+
+/** Disconnect */
+mlan_status wlan_disconnect(IN mlan_private * pmpriv,
+                            IN mlan_ioctl_req * pioctl_req,
+                            IN mlan_802_11_mac_addr * mac);
+
+/** Ad-Hoc start */
+mlan_status wlan_adhoc_start(IN mlan_private * pmpriv,
+                             IN t_void * pioctl_buf,
+                             IN mlan_802_11_ssid * padhoc_ssid);
+
+/** Ad-Hoc join */
+mlan_status wlan_adhoc_join(IN mlan_private * pmpriv,
+                            IN t_void * pioctl_buf,
+                            IN BSSDescriptor_t * pBSSDesc);
+
+/** Ad-Hoc start command handler */
+mlan_status wlan_cmd_802_11_ad_hoc_start(IN mlan_private * pmpriv,
+                                         IN HostCmd_DS_COMMAND * cmd,
+                                         IN t_void * pdata_buf);
+
+/** Ad-Hoc command handler */
+mlan_status wlan_cmd_802_11_ad_hoc_join(IN mlan_private * pmpriv,
+                                        IN HostCmd_DS_COMMAND * cmd,
+                                        IN t_void * pdata_buf);
+
+/** Handler for Ad-Hoc commands */
+mlan_status wlan_ret_802_11_ad_hoc(IN mlan_private * pmpriv,
+                                   IN HostCmd_DS_COMMAND * resp,
+                                   IN t_void * pioctl_buf);
+
+/** Handler for bgscan query commands */
+mlan_status wlan_cmd_802_11_bg_scan_query(IN mlan_private * pmpriv,
+                                          IN HostCmd_DS_COMMAND * pcmd,
+                                          IN t_void * pdata_buf);
+
+/* 802.11D related functions */
+/** Initialize 11D */
+t_void wlan_11d_init(mlan_adapter * pmadapter);
+/** Enable 11D */
+mlan_status wlan_11d_enable(mlan_private * pmpriv, t_void * pioctl_buf,
+                            state_11d_t flag);
+/** Set universal table */
+mlan_status wlan_11d_set_universaltable(mlan_private * pmpriv, t_u8 band);
+/** Get 11D state */
+state_11d_t wlan_11d_get_state(mlan_private * pmpriv);
+/** Create 11D country information for downloading */
+mlan_status wlan_11d_create_dnld_countryinfo(mlan_private * pmpriv, t_u8 band);
+/** Get scan type */
+t_u8 wlan_11d_get_scan_type(pmlan_adapter pmadapter, t_u8 chan,
+                            parsed_region_chan_11d_t * parsed_region_chan);
+/** Set 11D universal table */
+int wlan_set_universal_table(mlan_private * pmpriv, t_u8 band);
+/** Command handler for 11D country info */
+mlan_status wlan_cmd_802_11d_domain_info(mlan_private * pmpriv,
+                                         HostCmd_DS_COMMAND * pcmd,
+                                         t_u16 cmd_action);
+/** Handler for 11D country info command response */
+mlan_status wlan_ret_802_11d_domain_info(mlan_private * pmpriv,
+                                         HostCmd_DS_COMMAND * resp);
+/** Parse 11D country info */
+mlan_status wlan_11d_parse_dnld_countryinfo(mlan_private * pmpriv,
+                                            BSSDescriptor_t * pBSSDesc);
+/** Prepare 11D domain information for download */
+mlan_status wlan_11d_prepare_dnld_domain_info_cmd(mlan_private * pmpriv);
+/** Parse 11D country information  */
+mlan_status wlan_11d_parse_domain_info(pmlan_adapter pmadapter,
+                                       IEEEtypes_CountryInfoFullSet_t *
+                                       country_info, t_u8 band,
+                                       parsed_region_chan_11d_t *
+                                       parsed_region_chan);
+
+/** Convert channel to frequency */
+t_u32 wlan_11d_chan_2_freq(pmlan_adapter pmadapter, t_u8 chan, t_u8 band);
+/** Get Channel-Frequency-Power by band and channel */
+chan_freq_power_t *wlan_get_cfp_by_band_and_channel(pmlan_adapter pmadapter,
+                                                    t_u8 band, t_u16 channel,
+                                                    region_chan_t *
+                                                    region_channel);
+/** Find Channel-Frequency-Power by band and channel */
+chan_freq_power_t *wlan_find_cfp_by_band_and_channel(mlan_adapter * pmadapter,
+                                                     t_u8 band, t_u16 channel);
+/** Find Channel-Frequency-Power by band and frequecy */
+chan_freq_power_t *wlan_find_cfp_by_band_and_freq(mlan_adapter * pmadapter,
+                                                  t_u8 band, t_u32 freq);
+/** Get region Channel-Frequency-Power tabel */
+chan_freq_power_t *wlan_get_region_cfp_table(pmlan_adapter pmadapter,
+                                             t_u8 region, t_u8 band,
+                                             int *cfp_no);
+/** Get Tx power of channel from Channel-Frequency-Power */
+t_u8 wlan_get_txpwr_of_chan_from_cfp(mlan_private * pmpriv, t_u8 channel);
+/** Convert index into data rate */
+t_u32 wlan_index_to_data_rate(pmlan_adapter pmadapter, t_u8 index,
+                              t_u8 ht_info);
+t_u32 wlan_find_freq_from_band_chan(t_u8, t_u8);
+/** Set region table */
+mlan_status wlan_set_regiontable(mlan_private * pmpriv, t_u8 region, t_u8 band);
+/** Append the vendor specific TLV */
+int wlan_cmd_append_vsie_tlv(mlan_private * pmpriv, t_u16 vsie_mask,
+                             t_u8 ** ppbuffer);
+
+/* Rate related functions */
+/** Convert index into data rate */
+t_u32 wlan_index_to_data_rate(pmlan_adapter pmadapter, t_u8 index,
+                              t_u8 ht_info);
+/** Get active data rates */
+t_u32 wlan_get_active_data_rates(mlan_private * pmpriv,
+                                 WLAN_802_11_RATES rates);
+/** Get supported data rates */
+t_u32 wlan_get_supported_rates(mlan_private * pmpriv, WLAN_802_11_RATES rates);
+/** Convert data rate to index */
+t_u8 wlan_data_rate_to_index(pmlan_adapter pmadapter, t_u32 rate);
+/** Check if rate is auto */
+t_u8 wlan_is_rate_auto(mlan_private * pmpriv);
+/** Get rate index */
+int wlan_get_rate_index(pmlan_adapter pmadapter, t_u16 * rateBitmap, int size);
+/** Region code index table */
+extern t_u16 region_code_index[MRVDRV_MAX_REGION_CODE];
+
+/*  Save a beacon buffer of the current bss descriptor */
+t_void wlan_save_curr_bcn(IN mlan_private * pmpriv);
+/*  Restore a beacon buffer of the current bss descriptor */
+t_void wlan_restore_curr_bcn(IN mlan_private * pmpriv);
+/*  Free a beacon buffer of the current bss descriptor */
+t_void wlan_free_curr_bcn(IN mlan_private * pmpriv);
+
+/** 
+ *  @brief RA based queueing
+ *   
+ *  @param priv                 A pointer to mlan_private structure
+ *
+ *  @return 	   	        MTRUE or MFALSE
+ */
+static INLINE t_u8
+queuing_ra_based(pmlan_private priv)
+{
+    /* 
+     * Currently we assume if we are in Infra, then DA=RA. This might not be
+     * true in the future
+     */
+    if ((priv->bss_mode == MLAN_BSS_MODE_INFRA) &&
+        (priv->bss_type == MLAN_BSS_TYPE_STA))
+        return MFALSE;
+
+    return MTRUE;
+}
+
+/** 
+ *  @brief Copy Rates
+ *   
+ *  @param dest                 A pointer to Dest Buf
+ *  @param pos		        The position for copy
+ *  @param src		        A pointer to Src Buf
+ *  @param len                  The len of Src Buf
+ *
+ *  @return 	   	        Number of Rates copied
+ */
+static INLINE t_u32
+wlan_copy_rates(t_u8 * dest, t_u32 pos, t_u8 * src, int len)
+{
+    int i;
+
+    for (i = 0; i < len && src[i]; i++, pos++) {
+        if (pos >= sizeof(WLAN_802_11_RATES))
+            break;
+        dest[pos] = src[i];
+    }
+
+    return pos;
+}
+
+/** 
+ *  @brief strlen
+ *   
+ *  @param str		        A pointer to string
+ *
+ *  @return 	   	        Length of string
+ */
+static INLINE t_u32
+wlan_strlen(const t_s8 * str)
+{
+    t_u32 i;
+
+    for (i = 0; str[i] != 0; i++) {
+    }
+    return i;
+}
+
+/** delay unit */
+typedef enum _delay_unit
+{
+    USEC,
+    MSEC,
+    SEC,
+} t_delay_unit;
+
+/** delay function */
+t_void wlan_delay_func(mlan_adapter * pmadapter, t_u32 delay, t_delay_unit u);
+
+/** delay function wrapper */
+#define wlan_delay(p, n)   wlan_delay_func(p, n, SEC)
+/** delay function wrapper */
+#define wlan_mdelay(p, n)  wlan_delay_func(p, n, MSEC)
+/** delay function wrapper */
+#define wlan_udelay(p, n)  wlan_delay_func(p, n, USEC)
+
+/** Function to check if any command is pending in the queue */
+#define IS_COMMAND_PENDING(pmadapter) ((cmd_ctrl_node *)util_peek_list(&pmadapter->cmd_pending_q,\
+                                       pmadapter->callbacks.moal_spin_lock,\
+                                       pmadapter->callbacks.moal_spin_unlock))
+
+/** 
+ *  @brief This function returns first available priv
+ *  based on the bss_type
+ *  
+ *  @param handle    A pointer to mlan_adapter
+ *  @param bss_type  BSS type or MLAN_BSS_TYPE_ANY
+ *
+ *  @return          Pointer to mlan_private
+ */
+static INLINE mlan_private *
+wlan_get_priv(mlan_adapter * pmadapter, mlan_bss_type bss_type)
+{
+    int i;
+
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        if (pmadapter->priv[i]) {
+            if (bss_type == MLAN_BSS_TYPE_ANY ||
+                pmadapter->priv[i]->bss_type == bss_type)
+                break;
+        }
+    }
+    return ((i < MLAN_MAX_BSS_NUM) ? pmadapter->priv[i] : MNULL);
+}
+
+#endif /* !_MLAN_MAIN_H_ */
diff --git a/wlan_src/mlan/mlan_meas.c b/wlan_src/mlan/mlan_meas.c
new file mode 100755
index 0000000..292ac67
--- /dev/null
+++ b/wlan_src/mlan/mlan_meas.c
@@ -0,0 +1,488 @@
+/**
+ * @file mlan_meas.c
+ *
+ *  @brief Implementation of measurement interface code with the app/firmware
+ *
+ *  Driver implementation for sending and retrieving measurement requests
+ *    and responses. 
+ *  
+ *  Current use is limited to 802.11h.
+ *
+ *  Requires use of the following preprocessor define:
+ *    - ENABLE_MEAS
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ *   
+ */
+
+/*************************************************************
+Change Log:
+    03/24/2009: initial version
+************************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_ioctl.h"
+#include "mlan_meas.h"
+
+/** Default measurement duration when not provided by the application */
+#define WLAN_MEAS_DEFAULT_MEAS_DURATION    1000U        /* TUs */
+
+#ifdef DEBUG_LEVEL2
+/** String descriptions of the different measurement enums.  Debug display */
+static const char *meas_type_str[WLAN_MEAS_NUM_TYPES] = {
+    "basic",
+};
+
+/** 
+ *  @brief Retrieve the measurement string representation of a meas_type enum
+ *  Used for debug display only
+ *
+ *  @param meas_type Measurement type enumeration input for string lookup
+ * 
+ *  @return         Constant string representing measurement type
+ */
+static const char *
+wlan_meas_get_meas_type_str(MeasType_t meas_type)
+{
+    if (meas_type <= WLAN_MEAS_11H_MAX_TYPE)
+        return meas_type_str[meas_type];
+
+    return "Invld";
+}
+#endif
+
+/**
+ *  @brief Debug print display of the input measurement request
+ *
+ *  @param pmeas_req  Pointer to the measurement request to display
+ *
+ *  @return          void
+ */
+static void
+wlan_meas_dump_meas_req(const HostCmd_DS_MEASUREMENT_REQUEST * pmeas_req)
+{
+    PRINTM(MINFO, "Meas: Req: ------------------------------\n");
+
+    PRINTM(MINFO, "Meas: Req: mac_addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+           pmeas_req->mac_addr[0],
+           pmeas_req->mac_addr[1],
+           pmeas_req->mac_addr[2],
+           pmeas_req->mac_addr[3],
+           pmeas_req->mac_addr[4], pmeas_req->mac_addr[5]);
+
+    PRINTM(MINFO, "Meas: Req:  dlgTkn: %d\n", pmeas_req->dialog_token);
+    PRINTM(MINFO, "Meas: Req:    mode: dm[%c] rpt[%c] req[%c]\n",
+           pmeas_req->req_mode.duration_mandatory ? 'X' : ' ',
+           pmeas_req->req_mode.report ? 'X' : ' ',
+           pmeas_req->req_mode.request ? 'X' : ' ');
+    PRINTM(MINFO, "Meas: Req:        : en[%c] par[%c]\n",
+           pmeas_req->req_mode.enable ? 'X' : ' ',
+           pmeas_req->req_mode.parallel ? 'X' : ' ');
+#ifdef DEBUG_LEVEL2
+    PRINTM(MINFO, "Meas: Req: measTyp: %s\n",
+           wlan_meas_get_meas_type_str(pmeas_req->meas_type));
+#endif
+
+    switch (pmeas_req->meas_type) {
+    case WLAN_MEAS_BASIC:
+        /* Lazy cheat, fields of bas, cca, rpi union match on the request */
+        PRINTM(MINFO, "Meas: Req: chan: %u\n", pmeas_req->req.basic.channel);
+        PRINTM(MINFO, "Meas: Req: strt: %llu\n",
+               wlan_le64_to_cpu(pmeas_req->req.basic.start_time));
+        PRINTM(MINFO, "Meas: Req:  dur: %u\n",
+               wlan_le16_to_cpu(pmeas_req->req.basic.duration));
+        break;
+    default:
+        PRINTM(MINFO, "Meas: Req: <unhandled>\n");
+        break;
+    }
+
+    PRINTM(MINFO, "Meas: Req: ------------------------------\n");
+}
+
+/**
+ *  @brief Debug print display of the input measurement report
+ *
+ *  @param pmeas_rpt  Pointer to measurement report to display
+ *
+ *  @return          void
+ */
+static void
+wlan_meas_dump_meas_rpt(const HostCmd_DS_MEASUREMENT_REPORT * pmeas_rpt)
+{
+    PRINTM(MINFO, "Meas: Rpt: ------------------------------\n");
+    PRINTM(MINFO, "Meas: Rpt: mac_addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
+           pmeas_rpt->mac_addr[0],
+           pmeas_rpt->mac_addr[1],
+           pmeas_rpt->mac_addr[2],
+           pmeas_rpt->mac_addr[3],
+           pmeas_rpt->mac_addr[4], pmeas_rpt->mac_addr[5]);
+
+    PRINTM(MINFO, "Meas: Rpt:  dlgTkn: %d\n", pmeas_rpt->dialog_token);
+
+    PRINTM(MINFO, "Meas: Rpt: rptMode: (%x): Rfs[%c] ICp[%c] Lt[%c]\n",
+           *(t_u8 *) & pmeas_rpt->rpt_mode,
+           pmeas_rpt->rpt_mode.refused ? 'X' : ' ',
+           pmeas_rpt->rpt_mode.incapable ? 'X' : ' ',
+           pmeas_rpt->rpt_mode.late ? 'X' : ' ');
+#ifdef DEBUG_LEVEL2
+    PRINTM(MINFO, "Meas: Rpt: measTyp: %s\n",
+           wlan_meas_get_meas_type_str(pmeas_rpt->meas_type));
+#endif
+
+    switch (pmeas_rpt->meas_type) {
+    case WLAN_MEAS_BASIC:
+        PRINTM(MINFO, "Meas: Rpt: chan: %u\n", pmeas_rpt->rpt.basic.channel);
+        PRINTM(MINFO, "Meas: Rpt: strt: %llu\n",
+               wlan_le64_to_cpu(pmeas_rpt->rpt.basic.start_time));
+        PRINTM(MINFO, "Meas: Rpt:  dur: %u\n",
+               wlan_le16_to_cpu(pmeas_rpt->rpt.basic.duration));
+        PRINTM(MINFO, "Meas: Rpt:  bas: (%x): unmsd[%c], radar[%c]\n",
+               *(t_u8 *) & (pmeas_rpt->rpt.basic.map),
+               pmeas_rpt->rpt.basic.map.unmeasured ? 'X' : ' ',
+               pmeas_rpt->rpt.basic.map.radar ? 'X' : ' ');
+        PRINTM(MINFO, "Meas: Rpt:  bas: unidSig[%c] ofdm[%c] bss[%c]\n",
+               pmeas_rpt->rpt.basic.map.unidentified_sig ? 'X' : ' ',
+               pmeas_rpt->rpt.basic.map.ofdm_preamble ? 'X' : ' ',
+               pmeas_rpt->rpt.basic.map.bss ? 'X' : ' ');
+        break;
+    default:
+        PRINTM(MINFO, "Meas: Rpt: <unhandled>\n");
+        break;
+    }
+
+    PRINTM(MINFO, "Meas: Rpt: ------------------------------\n");
+}
+
+/**
+ *  @brief Retrieve a measurement report from the firmware
+ * 
+ *  Callback from command processing when a measurement report is received
+ *    from the firmware.  Perform the following when a report is received:
+ *
+ *   -# Debug displays the report if compiled with the appropriate flags
+ *   -# If we are pending on a specific measurement report token, and it 
+ *      matches the received report's token, store the report and wake up
+ *      any pending threads
+ *
+ *  @param pmpriv Private driver information structure
+ *  @param resp HostCmd_DS_COMMAND struct returned from the firmware command
+ *              passing a HostCmd_DS_MEASUREMENT_REPORT structure.    
+ *
+ *  @return     MLAN_STATUS_SUCCESS
+ */
+static int
+wlan_meas_cmdresp_get_report(mlan_private * pmpriv,
+                             const HostCmd_DS_COMMAND * resp)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    const HostCmd_DS_MEASUREMENT_REPORT *pmeas_rpt = &resp->params.meas_rpt;
+
+    ENTER();
+
+    PRINTM(MINFO, "Meas: Rpt: %#x-%u, Seq=%u, Ret=%u\n",
+           resp->command, resp->size, resp->seq_num, resp->result);
+
+    /* Debug displays the measurement report */
+    wlan_meas_dump_meas_rpt(pmeas_rpt);
+
+    /* 
+     * Check if we are pending on a measurement report and it matches 
+     *  the dialog token of the received report:
+     */
+    if (pmadapter->state_meas.meas_rpt_pend_on
+        && pmadapter->state_meas.meas_rpt_pend_on == pmeas_rpt->dialog_token) {
+        PRINTM(MINFO, "Meas: Rpt: RCV'd Pend on meas #%d\n",
+               pmadapter->state_meas.meas_rpt_pend_on);
+
+        /* Clear the pending report indicator */
+        pmadapter->state_meas.meas_rpt_pend_on = 0;
+
+        /* Copy the received report into the measurement state for retrieval */
+        memcpy(&pmadapter->state_meas.meas_rpt_returned, pmeas_rpt,
+               sizeof(pmadapter->state_meas.meas_rpt_returned));
+
+        /* 
+         * Wake up any threads pending on the wait queue
+         */
+    }
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Prepare CMD_MEASURMENT_REPORT firmware command
+ *
+ *  @param pmpriv     Private driver information structure
+ *  @param pcmd_ptr   Output parameter: Pointer to the command being prepared 
+ *                    for the firmware
+ *  @param pinfo_buf  HostCmd_DS_MEASUREMENT_REQUEST passed as void data block
+ *
+ *  @return          MLAN_STATUS_SUCCESS
+ */
+static int
+wlan_meas_cmd_request(mlan_private * pmpriv,
+                      HostCmd_DS_COMMAND * pcmd_ptr, const void *pinfo_buf)
+{
+    const HostCmd_DS_MEASUREMENT_REQUEST *pmeas_req =
+        (HostCmd_DS_MEASUREMENT_REQUEST *) pinfo_buf;
+
+    ENTER();
+
+    pcmd_ptr->command = HostCmd_CMD_MEASUREMENT_REQUEST;
+    pcmd_ptr->size = sizeof(HostCmd_DS_MEASUREMENT_REQUEST) + S_DS_GEN;
+
+    memcpy(&pcmd_ptr->params.meas_req, pmeas_req,
+           sizeof(pcmd_ptr->params.meas_req));
+
+    PRINTM(MINFO, "Meas: Req: %#x-%u, Seq=%u, Ret=%u\n",
+           pcmd_ptr->command, pcmd_ptr->size, pcmd_ptr->seq_num,
+           pcmd_ptr->result);
+
+    wlan_meas_dump_meas_req(pmeas_req);
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief  Retrieve a measurement report from the firmware
+ *
+ *  The firmware will send a EVENT_MEAS_REPORT_RDY event when it 
+ *    completes or receives a measurement report.  The event response
+ *    handler will then start a HostCmd_CMD_MEASUREMENT_REPORT firmware command
+ *    which gets completed for transmission to the firmware in this routine.
+ *
+ *  @param pmpriv    Private driver information structure
+ *  @param pcmd_ptr  Output parameter: Pointer to the command being prepared 
+ *                   for the firmware
+ *
+ *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+wlan_meas_cmd_get_report(mlan_private * pmpriv, HostCmd_DS_COMMAND * pcmd_ptr)
+{
+    ENTER();
+
+    pcmd_ptr->command = HostCmd_CMD_MEASUREMENT_REPORT;
+    pcmd_ptr->size = sizeof(HostCmd_DS_MEASUREMENT_REPORT) + S_DS_GEN;
+
+    memset(&pcmd_ptr->params.meas_rpt, 0x00, sizeof(pcmd_ptr->params.meas_rpt));
+
+    /* 
+     * Set the meas_rpt.mac_addr to our mac address to get a meas report,
+     *   setting the mac to another STA address instructs the firmware
+     *   to transmit this measurement report frame instead
+     */
+    memcpy(pcmd_ptr->params.meas_rpt.mac_addr, pmpriv->curr_addr,
+           sizeof(pcmd_ptr->params.meas_rpt.mac_addr));
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Initialize any needed structures for the measurement code
+ *
+ *  @param pmadapter mlan_adapter structure
+ *
+ *  @return      void
+ */
+void
+wlan_meas_init(mlan_adapter * pmadapter)
+{
+    ENTER();
+    LEAVE();
+}
+
+/** 
+ *  @brief Send the input measurement request to the firmware.
+ *
+ *  If the dialog token in the measurement request is set to 0, the function
+ *    will use an local static auto-incremented token in the measurement
+ *    request.  This ensures the dialog token is always set.
+ *
+ *  If wait_for_resp_timeout is set, the function will block its return on 
+ *     a timeout or returned measurement report that matches the requests
+ *     dialog token. 
+ *
+ *  @param pmpriv                  Private driver information structure
+ *  @param pmeas_req               Pointer to the measurement request to send
+ *  @param wait_for_resp_timeout   Timeout value of the measurement request
+ *                                 in ms.
+ *  @param pmeas_rpt               Output parameter: Pointer for the resulting
+ *                                 measurement report
+ *
+ *  @return
+ *    - 0 for success
+ *    - -ETIMEDOUT if the measurement report does not return before
+ *      the timeout expires
+ *    - Error return from wlan_prepare_cmd routine otherwise
+ */
+int
+wlan_meas_util_send_req(mlan_private * pmpriv,
+                        HostCmd_DS_MEASUREMENT_REQUEST * pmeas_req,
+                        t_u32 wait_for_resp_timeout,
+                        HostCmd_DS_MEASUREMENT_REPORT * pmeas_rpt)
+{
+    static t_u8 auto_dialog_tok = 0;
+    wlan_meas_state_t *pmeas_state = &pmpriv->adapter->state_meas;
+    int ret;
+    t_u32 calc_timeout;
+
+    ENTER();
+
+    /* If dialogTok was set to 0 or not provided, autoset */
+    pmeas_req->dialog_token = (pmeas_req->dialog_token ?
+                               pmeas_req->dialog_token : ++auto_dialog_tok);
+
+    /* Check for rollover of the dialog token.  Avoid using 0 as a token */
+    pmeas_req->dialog_token = (pmeas_req->dialog_token ?
+                               pmeas_req->dialog_token : 1);
+
+    /* 
+     * If the request is to pend waiting for the result, set the dialog token
+     * of this measurement request in the state structure.  The measurement
+     * report handling routines can then check the incoming measurement
+     * reports for a match with this dialog token.  
+     */
+    if (wait_for_resp_timeout) {
+        pmeas_state->meas_rpt_pend_on = pmeas_req->dialog_token;
+        PRINTM(MINFO, "Meas: Req: START Pend on meas #%d\n",
+               pmeas_req->dialog_token);
+    }
+
+    /* Send the measurement request to the firmware */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MEASUREMENT_REQUEST,
+                           HostCmd_ACT_GEN_SET, 0, MNULL, (void *) pmeas_req);
+
+    /* 
+     * If the measurement request was sent successfully, and the function
+     * must wait for the report, suspend execution until the meas_rpt_pend_on
+     * variable in the state structure has been reset to 0 by the report
+     * handling routines.
+     */
+    if (!ret && wait_for_resp_timeout) {
+        /* Add ~25% overhead to the timeout for firmware overhead */
+        calc_timeout = wait_for_resp_timeout + (wait_for_resp_timeout >> 2);
+
+        PRINTM(MINFO, "Meas: Req: TIMEOUT set to %d ms\n", calc_timeout);
+
+        /* extra 10 ms for the driver overhead - helps with small meas */
+        calc_timeout += 10;
+
+        PRINTM(MINFO, "Meas: Req: TIMEOUT set to %d milliseconds\n",
+               calc_timeout);
+
+        if (pmeas_state->meas_rpt_pend_on) {
+            PRINTM(MINFO, "Meas: Req: TIMEOUT Pend on meas #%d\n",
+                   pmeas_req->dialog_token);
+            ret = MLAN_STATUS_FAILURE;
+        } else {
+            PRINTM(MINFO, "Meas: Req: DONE Pend on meas #%d\n",
+                   pmeas_req->dialog_token);
+            memcpy(pmeas_rpt, &pmeas_state->meas_rpt_returned,
+                   sizeof(HostCmd_DS_MEASUREMENT_REPORT));
+        }
+    }
+
+    /* 
+     * The measurement request failed or we are not waiting for a response.
+     * In either case, the rpt_pend_on variable should be zero.
+     */
+    pmeas_state->meas_rpt_pend_on = 0;
+
+    LEAVE();
+
+    return ret;
+}
+
+/**
+ *  @brief  Prepare the HostCmd_DS_Command structure for a measurement command.
+ *
+ *  Use the Command field to determine if the command being set up is for
+ *     11h and call one of the local command handlers accordingly for:
+ *
+ *        - HostCmd_CMD_MEASUREMENT_REQUEST
+ *        - HostCmd_CMD_MEASUREMENT_REPORT
+ *
+ *  @param pmpriv     Private driver information structure
+ *  @param pcmd_ptr   Output parameter: Pointer to the command being prepared 
+ *                    for the firmware
+ *  @param pinfo_buf  Void buffer passthrough with data necessary for a
+ *                    specific command type
+ *
+ *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ *
+ */
+int
+wlan_meas_cmd_process(mlan_private * pmpriv,
+                      HostCmd_DS_COMMAND * pcmd_ptr, const void *pinfo_buf)
+{
+    int ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+    switch (pcmd_ptr->command) {
+    case HostCmd_CMD_MEASUREMENT_REQUEST:
+        ret = wlan_meas_cmd_request(pmpriv, pcmd_ptr, pinfo_buf);
+        break;
+    case HostCmd_CMD_MEASUREMENT_REPORT:
+        ret = wlan_meas_cmd_get_report(pmpriv, pcmd_ptr);
+        break;
+    default:
+        ret = MLAN_STATUS_FAILURE;
+    }
+
+    pcmd_ptr->command = wlan_cpu_to_le16(pcmd_ptr->command);
+    pcmd_ptr->size = wlan_cpu_to_le16(pcmd_ptr->size);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Handle the command response from the firmware for a measurement 
+ *         command
+ *
+ *  Use the Command field to determine if the command response being
+ *    is for meas.  Call the local command response handler accordingly for:
+ *
+ *        - HostCmd_CMD_802_MEASUREMENT_REQUEST
+ *        - HostCmd_CMD_802_MEASUREMENT_REPORT
+ *
+ *  @param pmpriv Private driver information structure
+ *  @param resp   HostCmd_DS_COMMAND struct returned from the firmware command
+ *
+ *  @return     MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+int
+wlan_meas_cmdresp_process(mlan_private * pmpriv,
+                          const HostCmd_DS_COMMAND * resp)
+{
+    int ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+    switch (resp->command) {
+    case HostCmd_CMD_MEASUREMENT_REQUEST:
+        PRINTM(MINFO, "Meas: Req Resp: Sz=%u, Seq=%u, Ret=%u\n",
+               resp->size, resp->seq_num, resp->result);
+
+        break;
+    case HostCmd_CMD_MEASUREMENT_REPORT:
+        ret = wlan_meas_cmdresp_get_report(pmpriv, resp);
+        break;
+    default:
+        ret = MLAN_STATUS_FAILURE;
+    }
+
+    LEAVE();
+    return ret;
+}
diff --git a/wlan_src/mlan/mlan_meas.h b/wlan_src/mlan/mlan_meas.h
new file mode 100755
index 0000000..97c7ffe
--- /dev/null
+++ b/wlan_src/mlan/mlan_meas.h
@@ -0,0 +1,45 @@
+/**
+ *  @file mlan_meas.h
+ *
+ *  @brief Interface for the measurement module implemented in mlan_meas.c
+ *
+ *  Driver interface functions and type declarations for the measurement module
+ *    implemented in mlan_meas.c
+ *  
+ *  @sa mlan_meas.c
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ *
+ */
+
+/*************************************************************
+Change Log:
+    03/25/2009: initial version
+************************************************************/
+
+#ifndef _MLAN_MEAS_H_
+#define _MLAN_MEAS_H_
+
+#include  "mlan_fw.h"
+
+/* Initialize the measurement code on startup */
+extern void wlan_meas_init(mlan_adapter * pmadapter);
+
+/* Send a given measurement request to the firmware, report back the result */
+extern int
+wlan_meas_util_send_req(mlan_private * pmpriv,
+                        HostCmd_DS_MEASUREMENT_REQUEST * pmeas_req,
+                        t_u32 wait_for_resp_timeout,
+                        HostCmd_DS_MEASUREMENT_REPORT * pmeas_rpt);
+
+/* Setup a measurement command before it is sent to the firmware */
+extern int wlan_meas_cmd_process(mlan_private * pmpriv,
+                                 HostCmd_DS_COMMAND * pcmd_ptr,
+                                 const t_void * pinfo_buf);
+
+/* Handle a given measurement command response from the firmware */
+extern int wlan_meas_cmdresp_process(mlan_private * pmpriv,
+                                     const HostCmd_DS_COMMAND * resp);
+
+#endif /* _MLAN_MEAS_H_ */
diff --git a/wlan_src/mlan/mlan_misc.c b/wlan_src/mlan/mlan_misc.c
new file mode 100755
index 0000000..8e78f2e
--- /dev/null
+++ b/wlan_src/mlan/mlan_misc.c
@@ -0,0 +1,406 @@
+/**
+ * @file mlan_misc.c
+ *
+ *  @brief This file include Miscellaneous functions for MLAN module
+ *
+ *
+ *  Copyright (C) 2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ *   
+ */
+
+/*************************************************************
+Change Log:
+    05/11/2009: initial version
+************************************************************/
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+                Local Variables
+********************************************************/
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+
+/********************************************************
+                Global Functions
+********************************************************/
+
+/** 
+ *  @brief send host cmd
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+mlan_status
+wlan_misc_ioctl_host_cmd(IN pmlan_adapter pmadapter,
+                         IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_misc_cfg *misc = MNULL;
+
+    ENTER();
+
+    misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           0,
+                           0,
+                           0,
+                           (t_void *) pioctl_req,
+                           (t_void *) & misc->param.hostcmd);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Send function init/shutdown command to firmware
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_PENDING --success, otherwise fail
+ */
+mlan_status
+wlan_misc_ioctl_init_shutdown(IN pmlan_adapter pmadapter,
+                              IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_misc_cfg *misc_cfg = MNULL;
+    t_u16 cmd;
+
+    ENTER();
+
+    misc_cfg = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+    if (misc_cfg->param.func_init_shutdown == MLAN_FUNC_INIT)
+        cmd = HostCmd_CMD_FUNC_INIT;
+    else if (misc_cfg->param.func_init_shutdown == MLAN_FUNC_SHUTDOWN)
+        cmd = HostCmd_CMD_FUNC_SHUTDOWN;
+    else {
+        PRINTM(MERROR, "Unsupported parameter\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    /* Send command to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           cmd,
+                           HostCmd_ACT_GEN_SET,
+                           0, (t_void *) pioctl_req, MNULL);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get debug information
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+mlan_status
+wlan_get_info_debug_info(IN pmlan_adapter pmadapter,
+                         IN pmlan_ioctl_req pioctl_req)
+{
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_get_info *info;
+
+    ENTER();
+
+    info = (mlan_ds_get_info *) pioctl_req->pbuf;
+
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        memcpy(pmpriv->wmm.packets_out, info->param.debug_info.packets_out,
+               sizeof(pmpriv->wmm.packets_out));
+        pmadapter->max_tx_buf_size =
+            (t_u16) info->param.debug_info.max_tx_buf_size;
+        pmadapter->tx_buf_size = (t_u16) info->param.debug_info.tx_buf_size;
+        pmadapter->ps_mode = info->param.debug_info.ps_mode;
+        pmadapter->ps_state = info->param.debug_info.ps_state;
+        pmadapter->is_deep_sleep = info->param.debug_info.is_deep_sleep;
+        pmadapter->pm_wakeup_card_req =
+            info->param.debug_info.pm_wakeup_card_req;
+        pmadapter->pm_wakeup_fw_try = info->param.debug_info.pm_wakeup_fw_try;
+        pmadapter->is_hs_configured = info->param.debug_info.is_hs_configured;
+        pmadapter->hs_activated = info->param.debug_info.hs_activated;
+
+        pmadapter->dbg.num_cmd_host_to_card_failure =
+            info->param.debug_info.num_cmd_host_to_card_failure;
+        pmadapter->dbg.num_cmd_sleep_cfm_host_to_card_failure =
+            info->param.debug_info.num_cmd_sleep_cfm_host_to_card_failure;
+        pmadapter->dbg.num_tx_host_to_card_failure =
+            info->param.debug_info.num_tx_host_to_card_failure;
+        pmadapter->dbg.num_event_deauth =
+            info->param.debug_info.num_event_deauth;
+        pmadapter->dbg.num_event_disassoc =
+            info->param.debug_info.num_event_disassoc;
+        pmadapter->dbg.num_event_link_lost =
+            info->param.debug_info.num_event_link_lost;
+        pmadapter->dbg.num_cmd_deauth = info->param.debug_info.num_cmd_deauth;
+        pmadapter->dbg.num_cmd_assoc_success =
+            info->param.debug_info.num_cmd_assoc_success;
+        pmadapter->dbg.num_cmd_assoc_failure =
+            info->param.debug_info.num_cmd_assoc_failure;
+        pmadapter->dbg.num_tx_timeout = info->param.debug_info.num_tx_timeout;
+        pmadapter->dbg.num_cmd_timeout = info->param.debug_info.num_cmd_timeout;
+        pmadapter->dbg.timeout_cmd_id = info->param.debug_info.timeout_cmd_id;
+        pmadapter->dbg.timeout_cmd_act = info->param.debug_info.timeout_cmd_act;
+        memcpy(pmadapter->dbg.last_cmd_id, info->param.debug_info.last_cmd_id,
+               sizeof(pmadapter->dbg.last_cmd_id));
+        memcpy(pmadapter->dbg.last_cmd_act, info->param.debug_info.last_cmd_act,
+               sizeof(pmadapter->dbg.last_cmd_act));
+        pmadapter->dbg.last_cmd_index = info->param.debug_info.last_cmd_index;
+        memcpy(pmadapter->dbg.last_cmd_resp_id,
+               info->param.debug_info.last_cmd_resp_id,
+               sizeof(pmadapter->dbg.last_cmd_resp_id));
+        pmadapter->dbg.last_cmd_resp_index =
+            info->param.debug_info.last_cmd_resp_index;
+        memcpy(pmadapter->dbg.last_event, info->param.debug_info.last_event,
+               sizeof(pmadapter->dbg.last_event));
+        pmadapter->dbg.last_event_index =
+            info->param.debug_info.last_event_index;
+
+        pmadapter->data_sent = info->param.debug_info.data_sent;
+        pmadapter->cmd_sent = info->param.debug_info.cmd_sent;
+        pmadapter->mp_rd_bitmap = info->param.debug_info.mp_rd_bitmap;
+        pmadapter->mp_wr_bitmap = info->param.debug_info.mp_wr_bitmap;
+        pmadapter->curr_rd_port = info->param.debug_info.curr_rd_port;
+        pmadapter->curr_wr_port = info->param.debug_info.curr_wr_port;
+        pmadapter->cmd_resp_received = info->param.debug_info.cmd_resp_received;
+    } else {                    /* MLAN_ACT_GET */
+        memcpy(info->param.debug_info.packets_out, pmpriv->wmm.packets_out,
+               sizeof(pmpriv->wmm.packets_out));
+        info->param.debug_info.max_tx_buf_size =
+            (t_u32) pmadapter->max_tx_buf_size;
+        info->param.debug_info.tx_buf_size = (t_u32) pmadapter->tx_buf_size;
+        info->param.debug_info.rx_tbl_num =
+            wlan_get_rxreorder_tbl(pmpriv, info->param.debug_info.rx_tbl);
+        info->param.debug_info.tx_tbl_num =
+            wlan_get_txbastream_tbl(pmpriv, info->param.debug_info.tx_tbl);
+        info->param.debug_info.ps_mode = pmadapter->ps_mode;
+        info->param.debug_info.ps_state = pmadapter->ps_state;
+        info->param.debug_info.is_deep_sleep = pmadapter->is_deep_sleep;
+
+        info->param.debug_info.pm_wakeup_card_req =
+            pmadapter->pm_wakeup_card_req;
+        info->param.debug_info.pm_wakeup_fw_try = pmadapter->pm_wakeup_fw_try;
+        info->param.debug_info.is_hs_configured = pmadapter->is_hs_configured;
+        info->param.debug_info.hs_activated = pmadapter->hs_activated;
+
+        info->param.debug_info.num_cmd_host_to_card_failure
+            = pmadapter->dbg.num_cmd_host_to_card_failure;
+        info->param.debug_info.num_cmd_sleep_cfm_host_to_card_failure
+            = pmadapter->dbg.num_cmd_sleep_cfm_host_to_card_failure;
+        info->param.debug_info.num_tx_host_to_card_failure
+            = pmadapter->dbg.num_tx_host_to_card_failure;
+        info->param.debug_info.num_event_deauth =
+            pmadapter->dbg.num_event_deauth;
+        info->param.debug_info.num_event_disassoc =
+            pmadapter->dbg.num_event_disassoc;
+        info->param.debug_info.num_event_link_lost =
+            pmadapter->dbg.num_event_link_lost;
+        info->param.debug_info.num_cmd_deauth = pmadapter->dbg.num_cmd_deauth;
+        info->param.debug_info.num_cmd_assoc_success =
+            pmadapter->dbg.num_cmd_assoc_success;
+        info->param.debug_info.num_cmd_assoc_failure =
+            pmadapter->dbg.num_cmd_assoc_failure;
+        info->param.debug_info.num_tx_timeout = pmadapter->dbg.num_tx_timeout;
+        info->param.debug_info.num_cmd_timeout = pmadapter->dbg.num_cmd_timeout;
+        info->param.debug_info.timeout_cmd_id = pmadapter->dbg.timeout_cmd_id;
+        info->param.debug_info.timeout_cmd_act = pmadapter->dbg.timeout_cmd_act;
+        memcpy(info->param.debug_info.last_cmd_id, pmadapter->dbg.last_cmd_id,
+               sizeof(pmadapter->dbg.last_cmd_id));
+        memcpy(info->param.debug_info.last_cmd_act, pmadapter->dbg.last_cmd_act,
+               sizeof(pmadapter->dbg.last_cmd_act));
+        info->param.debug_info.last_cmd_index = pmadapter->dbg.last_cmd_index;
+        memcpy(info->param.debug_info.last_cmd_resp_id,
+               pmadapter->dbg.last_cmd_resp_id,
+               sizeof(pmadapter->dbg.last_cmd_resp_id));
+        info->param.debug_info.last_cmd_resp_index =
+            pmadapter->dbg.last_cmd_resp_index;
+        memcpy(info->param.debug_info.last_event, pmadapter->dbg.last_event,
+               sizeof(pmadapter->dbg.last_event));
+        info->param.debug_info.last_event_index =
+            pmadapter->dbg.last_event_index;
+
+        info->param.debug_info.mp_rd_bitmap = pmadapter->mp_rd_bitmap;
+        info->param.debug_info.mp_wr_bitmap = pmadapter->mp_wr_bitmap;
+        info->param.debug_info.curr_rd_port = pmadapter->curr_rd_port;
+        info->param.debug_info.curr_wr_port = pmadapter->curr_wr_port;
+        info->param.debug_info.data_sent = pmadapter->data_sent;
+        info->param.debug_info.cmd_sent = pmadapter->cmd_sent;
+        info->param.debug_info.cmd_resp_received = pmadapter->cmd_resp_received;
+    }
+
+    pioctl_req->data_read_written =
+        sizeof(mlan_debug_info) + MLAN_SUB_COMMAND_SIZE;
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function wakes up the card.
+ *
+ *  @param pmadapter		A pointer to mlan_adapter structure
+ *
+ *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_pm_wakeup_card(IN pmlan_adapter pmadapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    ENTER();
+    PRINTM(MCMND, "Wakeup device...\n");
+    ret =
+        pcb->moal_write_reg(pmadapter->pmoal_handle, CONFIGURATION_REG,
+                            HOST_POWER_UP);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function resets the PM setting of the card.
+ *
+ *  @param pmadapter		A pointer to mlan_adapter structure
+ *
+ *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_pm_reset_card(IN pmlan_adapter pmadapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    ENTER();
+
+    ret = pcb->moal_write_reg(pmadapter->pmoal_handle, CONFIGURATION_REG, 0);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function allocates a mlan_buffer.
+ *
+ *  @param pcb        Pointer to mlan_callbacks
+ *  @param data_len   Data length
+ *
+ *  @return           mlan_buffer pointer or MNULL
+ */
+pmlan_buffer
+wlan_alloc_mlan_buffer(pmlan_callbacks pcb, t_u32 data_len)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_buffer pmbuf = MNULL;
+    t_u32 buf_size = sizeof(mlan_buffer) + data_len;
+
+    ENTER();
+
+    ret = pcb->moal_malloc(buf_size, (t_u8 **) & pmbuf);
+    if ((ret != MLAN_STATUS_SUCCESS) || !pmbuf) {
+        pmbuf = MNULL;
+        goto exit;
+    }
+
+    memset(pmbuf, 0, sizeof(mlan_buffer));
+
+    pmbuf->pdesc = MNULL;
+    pmbuf->pbuf = (t_u8 *) pmbuf + sizeof(mlan_buffer);
+    pmbuf->data_offset = 0;
+    pmbuf->data_len = data_len;
+
+  exit:
+    LEAVE();
+    return pmbuf;
+}
+
+/** 
+ *  @brief This function frees a mlan_buffer.
+ *
+ *  @param pcb        Pointer to mlan_callbacks
+ *  @param pmbuf      Pointer to mlan_buffer
+ *
+ *  @return           N/A
+ */
+t_void
+wlan_free_mlan_buffer(pmlan_callbacks pcb, pmlan_buffer pmbuf)
+{
+    ENTER();
+
+    if (pcb && pmbuf)
+        pcb->moal_mfree((t_u8 *) pmbuf);
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief Delay function implementation
+ *   
+ *  @param pmadapter        A pointer to mlan_adapter structure
+ *  @param delay            Delay value
+ *  @param u                Units of delay (sec, msec or usec)
+ */
+t_void
+wlan_delay_func(mlan_adapter * pmadapter, t_u32 delay, t_delay_unit u)
+{
+    t_u32 now_tv_sec, now_tv_usec;
+    t_u32 upto_tv_sec, upto_tv_usec;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    pcb->moal_get_system_time(&upto_tv_sec, &upto_tv_usec);
+
+    switch (u) {
+    case SEC:
+        upto_tv_sec += delay;
+        break;
+    case MSEC:
+        delay *= 1000;
+    case USEC:
+        upto_tv_sec += (delay / 1000000);
+        upto_tv_usec += (delay % 1000000);
+        break;
+    }
+
+    do {
+        pcb->moal_get_system_time(&now_tv_sec, &now_tv_usec);
+        if (now_tv_sec > upto_tv_sec)
+            return;
+
+        if ((now_tv_sec == upto_tv_sec) && (now_tv_usec >= upto_tv_usec))
+            return;
+    } while (MTRUE);
+
+    return;
+}
diff --git a/wlan_src/mlan/mlan_module.c b/wlan_src/mlan/mlan_module.c
new file mode 100755
index 0000000..29f22be
--- /dev/null
+++ b/wlan_src/mlan/mlan_module.c
@@ -0,0 +1,28 @@
+/** @file mlan_module.c
+ *
+ *  @brief This file declares the exported symbols from MLAN.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    12/08/2008: initial version
+******************************************************/
+
+#ifdef LINUX
+#include <linux/module.h>
+#include "mlan_decl.h"
+#include "mlan_ioctl.h"
+
+EXPORT_SYMBOL(mlan_register);
+EXPORT_SYMBOL(mlan_unregister);
+EXPORT_SYMBOL(mlan_init_fw);
+EXPORT_SYMBOL(mlan_dnld_fw);
+EXPORT_SYMBOL(mlan_shutdown_fw);
+EXPORT_SYMBOL(mlan_send_packet);
+EXPORT_SYMBOL(mlan_ioctl);
+EXPORT_SYMBOL(mlan_main_process);
+EXPORT_SYMBOL(mlan_interrupt);
+#endif /* LINUX */
diff --git a/wlan_src/mlan/mlan_scan.c b/wlan_src/mlan/mlan_scan.c
new file mode 100755
index 0000000..d0f6c49
--- /dev/null
+++ b/wlan_src/mlan/mlan_scan.c
@@ -0,0 +1,3219 @@
+/** @file mlan_scan.c
+ *
+ *  @brief Functions implementing wlan scan IOCTL and firmware command APIs
+ *
+ *  IOCTL handlers as well as command preparation and response routines
+ *  for sending scan commands to the firmware.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    10/28/2008: initial version
+******************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_11n.h"
+#include "mlan_11h.h"
+
+/********************************************************
+                Local Constants
+********************************************************/
+
+/** The maximum number of channels the firmware can scan per command */
+#define MRVDRV_MAX_CHANNELS_PER_SPECIFIC_SCAN   14
+
+/**
+ * Number of channels to scan per firmware scan command issuance.
+ *
+ * Number restricted to prevent hitting the limit on the amount of scan data
+ * returned in a single firmware scan command.
+ */
+#define MRVDRV_CHANNELS_PER_SCAN_CMD            4
+
+/** Memory needed to store a max sized Channel List TLV for a firmware scan */
+#define CHAN_TLV_MAX_SIZE  (sizeof(MrvlIEtypesHeader_t)                  \
+                            + (MRVDRV_MAX_CHANNELS_PER_SPECIFIC_SCAN     \
+                               * sizeof(ChanScanParamSet_t)))
+
+/** Memory needed to store supported rate */
+#define RATE_TLV_MAX_SIZE   (sizeof(MrvlIEtypes_RatesParamSet_t) + HOSTCMD_SUPPORTED_RATES)
+
+/** Memory needed to store a max number/size WildCard SSID TLV for a firmware scan */
+#define WILDCARD_SSID_TLV_MAX_SIZE  \
+            (MRVDRV_MAX_SSID_LIST_LENGTH  * (sizeof(MrvlIEtypes_WildCardSsIdParamSet_t) + MRVDRV_MAX_SSID_LENGTH))
+
+/** Maximum memory needed for a wlan_scan_cmd_config with all TLVs at max */
+#define MAX_SCAN_CFG_ALLOC (sizeof(wlan_scan_cmd_config)        \
+                            + sizeof(MrvlIEtypes_NumProbes_t)   \
+                            + sizeof(MrvlIETypes_HTCap_t)       \
+                            + CHAN_TLV_MAX_SIZE                 \
+                            + RATE_TLV_MAX_SIZE                 \
+                            + WILDCARD_SSID_TLV_MAX_SIZE)
+
+/** Macro to enable/disable SSID checking before storing a scan table */
+#ifdef DISCARD_BAD_SSID
+#define CHECK_SSID_IS_VALID(x)    wlan_ssid_valid(&bssidEntry.ssid)
+#else
+#define CHECK_SSID_IS_VALID(x)    MTRUE
+#endif
+
+/********************************************************
+                Local Variables
+********************************************************/
+
+/**
+ * Interally used to send a configured scan cmd between driver routines
+ */
+typedef union
+{
+    /** Scan configuration (variable length) */
+    wlan_scan_cmd_config config;
+    /** Max allocated block */
+    t_u8 config_alloc_buf[MAX_SCAN_CFG_ALLOC];
+} wlan_scan_cmd_config_tlv;
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+t_u8 wpa_oui_aes[] = { 0x00, 0x50, 0xf2, 0x04 };        /* AES */
+t_u8 rsn_oui_aes[] = { 0x00, 0x0f, 0xac, 0x04 };        /* AES */
+
+/**
+ *  @brief This function will parse a given IE for a given OUI
+ *
+ *  Parse a given WPA/RSN IE to find if it has a given oui in PTK, 
+ *  if no OUI found for PTK it returns 0.
+ *
+ *  @param pbss_desc       A pointer to current BSS descriptor
+ *  @return                0 on failure to find OUI, 1 on success.
+ */
+static t_u8
+search_oui_in_ie(IEBody * ie_body, t_u8 * oui)
+{
+    t_u8 count;
+
+    count = ie_body->PtkCnt[0];
+
+    /* There could be multiple OUIs for PTK hence 1) Take the length. 2) Check 
+       all the OUIs for AES. 3) If one of them is AES then pass success. */
+    while (count) {
+        if (!memcmp(ie_body->PtkBody, oui, sizeof(ie_body->PtkBody))) {
+            return MLAN_OUI_PRESENT;
+        }
+
+        --count;
+        if (count) {
+            ie_body = (IEBody *) ((t_u8 *) ie_body + sizeof(ie_body->PtkBody));
+        }
+    }
+
+    PRINTM(MINFO, "PTK not AES\n");
+    return MLAN_OUI_NOT_PRESENT;
+}
+
+/**
+ *  @brief This function will pass the correct ie and oui to search_oui_in_ie
+ *
+ *  Check the pbss_desc for appropriate IE and then check if RSN IE has AES
+ *  OUI in it. If RSN IE does not have AES in PTK then return 0;
+ *
+ *  @param pbss_desc       A pointer to current BSS descriptor
+ *  @return                0 on failure to find AES OUI, 1 on success.
+ */
+static t_u8
+is_rsn_aes_present(BSSDescriptor_t * pbss_desc)
+{
+    t_u8 *oui = MNULL;
+    IEBody *ie_body = MNULL;
+    t_u8 ret = MLAN_OUI_NOT_PRESENT;
+
+    if (((pbss_desc->prsn_ie) && ((*(pbss_desc->prsn_ie)).
+                                  ieee_hdr.element_id == RSN_IE))) {
+        ie_body = (IEBody *) (((t_u8 *) pbss_desc->prsn_ie->data) +
+                              RSN_GTK_OUI_OFFSET);
+        oui = rsn_oui_aes;
+        if ((ret = search_oui_in_ie(ie_body, oui)))
+            return ret;
+    }
+    return ret;
+}
+
+/**
+ *  @brief This function will pass the correct ie and oui to search_oui_in_ie
+ *
+ *  Check the pbss_desc for appropriate IE and then check if WPA IE has AES
+ *  OUI in it. If WPA IE does not have AES in PTK then return 0;
+ *
+ *  @param pbss_desc       A pointer to current BSS descriptor
+ *  @return                0 on failure to find AES OUI, 1 on success.
+ */
+static t_u8
+is_wpa_aes_present(BSSDescriptor_t * pbss_desc)
+{
+    t_u8 *oui = MNULL;
+    IEBody *ie_body = MNULL;
+    t_u8 ret = MLAN_OUI_NOT_PRESENT;
+
+    if (((pbss_desc->pwpa_ie) && ((*(pbss_desc->pwpa_ie)).
+                                  vend_hdr.element_id == WPA_IE))) {
+        ie_body = (IEBody *) pbss_desc->pwpa_ie->data;
+        oui = wpa_oui_aes;
+        if ((ret = search_oui_in_ie(ie_body, oui)))
+            return ret;
+    }
+    return ret;
+}
+
+/**
+ *  @brief Check if a scanned network compatible with the driver settings
+ *
+ *   WEP     WPA     WPA2    ad-hoc  encrypt                      Network
+ * enabled enabled  enabled   AES     mode   Privacy  WPA  WPA2  Compatible
+ *    0       0        0       0      NONE      0      0    0   yes No security
+ *    0       1        0       0       x        1x     1    x   yes WPA
+ *    0       0        1       0       x        1x     x    1   yes WPA2
+ *    0       0        0       1      NONE      1      0    0   yes Ad-hoc AES
+ *
+ *    1       0        0       0      NONE      1      0    0   yes Static WEP
+ *    0       0        0       0     !=NONE     1      0    0   yes Dynamic WEP
+ *
+ *
+ *  @param pmpriv  A pointer to mlan_private
+ *  @param index   Index in scan table to check against current driver settings
+ *  @param mode    Network mode: Infrastructure or IBSS
+ *
+ *  @return        Index in ScanTable, or negative value if error 
+ */
+static t_s32
+wlan_is_network_compatible(IN mlan_private * pmpriv,
+                           IN t_u32 index, IN t_u32 mode)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    BSSDescriptor_t *pbss_desc;
+
+    ENTER();
+
+    pbss_desc = &pmadapter->pscan_table[index];
+
+    /* Don't check for compatibility if roaming */
+    if ((pmpriv->media_connected == MTRUE)
+        && (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA)
+        && (pbss_desc->bss_mode == MLAN_BSS_MODE_INFRA)) {
+        LEAVE();
+        return index;
+    }
+
+    if ((pbss_desc->bss_mode == mode) &&
+        (pmpriv->sec_info.ewpa_enabled == MTRUE)) {
+        if (((pbss_desc->pwpa_ie) &&
+             ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE)) ||
+            ((pbss_desc->prsn_ie) &&
+             ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id == RSN_IE))) {
+            if (((pmpriv->adapter->config_bands & BAND_GN ||
+                  pmpriv->adapter->config_bands & BAND_AN) &&
+                 pbss_desc->pht_cap)
+                && !is_wpa_aes_present(pbss_desc)
+                && !is_rsn_aes_present(pbss_desc)) {
+                PRINTM(MINFO, "AES not supported by AP when 11n enabled\n");
+                LEAVE();
+                return -1;
+            }
+            LEAVE();
+            return index;
+        } else {
+            PRINTM(MINFO, "ewpa_enabled: Ignore none WPA/WPA2 AP\n");
+            LEAVE();
+            return -1;
+        }
+    }
+
+    if (pmpriv->wps.session_enable == MTRUE) {
+        PRINTM(MINFO, "Return success directly in WPS period\n");
+        LEAVE();
+        return index;
+    }
+    if (pmpriv->sec_info.wapi_enabled &&
+        (pbss_desc->pwapi_ie &&
+         ((*(pbss_desc->pwapi_ie)).ieee_hdr.element_id == WAPI_IE))) {
+        PRINTM(MINFO, "Return success for WAPI AP\n");
+        LEAVE();
+        return index;
+    }
+
+    if (pbss_desc->bss_mode == mode) {
+        if (pmpriv->sec_info.wep_status == Wlan802_11WEPDisabled
+            && !pmpriv->sec_info.wpa_enabled
+            && !pmpriv->sec_info.wpa2_enabled
+            && ((!pbss_desc->pwpa_ie) ||
+                ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id != WPA_IE))
+            && ((!pbss_desc->prsn_ie) ||
+                ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id != RSN_IE))
+            && !pmpriv->adhoc_aes_enabled &&
+            pmpriv->sec_info.encryption_mode == MLAN_ENCRYPTION_MODE_NONE &&
+            !pbss_desc->privacy) {
+            /* No security */
+            LEAVE();
+            return index;
+        } else if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled
+                   && !pmpriv->sec_info.wpa_enabled
+                   && !pmpriv->sec_info.wpa2_enabled
+                   && !pmpriv->adhoc_aes_enabled && pbss_desc->privacy) {
+            /* Static WEP enabled */
+            LEAVE();
+            return index;
+        } else if (pmpriv->sec_info.wep_status == Wlan802_11WEPDisabled
+                   && pmpriv->sec_info.wpa_enabled
+                   && !pmpriv->sec_info.wpa2_enabled
+                   && ((pbss_desc->pwpa_ie) &&
+                       ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE))
+                   && !pmpriv->adhoc_aes_enabled
+                   /* 
+                    * Privacy bit may NOT be set in some APs like LinkSys WRT54G
+                    * && pbss_desc->privacy
+                    */
+            ) {
+            /* WPA enabled */
+            PRINTM(MINFO,
+                   "wlan_is_network_compatible() WPA: index=%d wpa_ie=%#x "
+                   "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode=%#x "
+                   "privacy=%#x\n", index,
+                   (pbss_desc->pwpa_ie) ? (*(pbss_desc->pwpa_ie)).vend_hdr.
+                   element_id : 0,
+                   (pbss_desc->prsn_ie) ? (*(pbss_desc->prsn_ie)).ieee_hdr.
+                   element_id : 0,
+                   (pmpriv->sec_info.wep_status ==
+                    Wlan802_11WEPEnabled) ? "e" : "d",
+                   (pmpriv->sec_info.wpa_enabled) ? "e" : "d",
+                   (pmpriv->sec_info.wpa2_enabled) ? "e" : "d",
+                   pmpriv->sec_info.encryption_mode, pbss_desc->privacy);
+            if (((pmpriv->adapter->config_bands & BAND_GN ||
+                  pmpriv->adapter->config_bands & BAND_AN) &&
+                 pbss_desc->pht_cap)
+                && !is_wpa_aes_present(pbss_desc)) {
+                PRINTM(MINFO, "AES not supported by AP when 11n enabled\n");
+                LEAVE();
+                return -1;
+            }
+            LEAVE();
+            return index;
+        } else if (pmpriv->sec_info.wep_status == Wlan802_11WEPDisabled
+                   && !pmpriv->sec_info.wpa_enabled
+                   && pmpriv->sec_info.wpa2_enabled
+                   && ((pbss_desc->prsn_ie) &&
+                       ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id == RSN_IE))
+                   && !pmpriv->adhoc_aes_enabled
+                   /* 
+                    * Privacy bit may NOT be set in some APs like LinkSys WRT54G
+                    * && pbss_desc->privacy
+                    */
+            ) {
+            /* WPA2 enabled */
+            PRINTM(MINFO,
+                   "wlan_is_network_compatible() WPA2: index=%d wpa_ie=%#x "
+                   "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode=%#x "
+                   "privacy=%#x\n", index,
+                   (pbss_desc->pwpa_ie) ? (*(pbss_desc->pwpa_ie)).vend_hdr.
+                   element_id : 0,
+                   (pbss_desc->prsn_ie) ? (*(pbss_desc->prsn_ie)).ieee_hdr.
+                   element_id : 0,
+                   (pmpriv->sec_info.wep_status ==
+                    Wlan802_11WEPEnabled) ? "e" : "d",
+                   (pmpriv->sec_info.wpa_enabled) ? "e" : "d",
+                   (pmpriv->sec_info.wpa2_enabled) ? "e" : "d",
+                   pmpriv->sec_info.encryption_mode, pbss_desc->privacy);
+            if (((pmpriv->adapter->config_bands & BAND_GN ||
+                  pmpriv->adapter->config_bands & BAND_AN) &&
+                 pbss_desc->pht_cap)
+                && !is_rsn_aes_present(pbss_desc)) {
+                PRINTM(MINFO, "AES not supported by AP when 11n enabled\n");
+                LEAVE();
+                return -1;
+            }
+            LEAVE();
+            return index;
+        } else if (pmpriv->sec_info.wep_status == Wlan802_11WEPDisabled
+                   && !pmpriv->sec_info.wpa_enabled
+                   && !pmpriv->sec_info.wpa2_enabled
+                   && ((!pbss_desc->pwpa_ie) ||
+                       ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id != WPA_IE))
+                   && ((!pbss_desc->prsn_ie) ||
+                       ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id != RSN_IE))
+                   && pmpriv->adhoc_aes_enabled &&
+                   pmpriv->sec_info.encryption_mode == MLAN_ENCRYPTION_MODE_NONE
+                   && pbss_desc->privacy) {
+            /* Ad-hoc AES enabled */
+            LEAVE();
+            return index;
+        } else if (pmpriv->sec_info.wep_status == Wlan802_11WEPDisabled
+                   && !pmpriv->sec_info.wpa_enabled
+                   && !pmpriv->sec_info.wpa2_enabled
+                   && ((!pbss_desc->pwpa_ie) ||
+                       ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id != WPA_IE))
+                   && ((!pbss_desc->prsn_ie) ||
+                       ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id != RSN_IE))
+                   && !pmpriv->adhoc_aes_enabled &&
+                   pmpriv->sec_info.encryption_mode != MLAN_ENCRYPTION_MODE_NONE
+                   && pbss_desc->privacy) {
+            /* Dynamic WEP enabled */
+            PRINTM(MINFO, "wlan_is_network_compatible() dynamic WEP: index=%d "
+                   "wpa_ie=%#x wpa2_ie=%#x EncMode=%#x privacy=%#x\n",
+                   index,
+                   (pbss_desc->pwpa_ie) ? (*(pbss_desc->pwpa_ie)).vend_hdr.
+                   element_id : 0,
+                   (pbss_desc->prsn_ie) ? (*(pbss_desc->prsn_ie)).ieee_hdr.
+                   element_id : 0, pmpriv->sec_info.encryption_mode,
+                   pbss_desc->privacy);
+            LEAVE();
+            return index;
+        }
+
+        /* Security doesn't match */
+        PRINTM(MINFO,
+               "wlan_is_network_compatible() FAILED: index=%d wpa_ie=%#x "
+               "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n",
+               index,
+               (pbss_desc->pwpa_ie) ? (*(pbss_desc->pwpa_ie)).vend_hdr.
+               element_id : 0,
+               (pbss_desc->prsn_ie) ? (*(pbss_desc->prsn_ie)).ieee_hdr.
+               element_id : 0,
+               (pmpriv->sec_info.wep_status ==
+                Wlan802_11WEPEnabled) ? "e" : "d",
+               (pmpriv->sec_info.wpa_enabled) ? "e" : "d",
+               (pmpriv->sec_info.wpa2_enabled) ? "e" : "d",
+               pmpriv->sec_info.encryption_mode, pbss_desc->privacy);
+        LEAVE();
+        return -1;
+    }
+
+    /* Mode doesn't match */
+    LEAVE();
+    return -1;
+}
+
+/**
+ *  @brief This function finds the best SSID in the Scan List
+ *
+ *  Search the scan table for the best SSID that also matches the current
+ *   adapter network preference (infrastructure or adhoc)
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @return             index in BSSID list
+ */
+static t_s32
+wlan_find_best_network_in_list(IN mlan_private * pmpriv)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    t_u32 mode = pmpriv->bss_mode;
+    t_s32 best_net = -1;
+    t_s32 best_rssi = 0;
+    t_u32 i;
+
+    ENTER();
+
+    PRINTM(MINFO, "Num of BSSIDs = %d\n", pmadapter->num_in_scan_table);
+
+    for (i = 0; i < pmadapter->num_in_scan_table; i++) {
+        switch (mode) {
+        case MLAN_BSS_MODE_INFRA:
+        case MLAN_BSS_MODE_IBSS:
+            if (wlan_is_network_compatible(pmpriv, i, mode) >= 0) {
+                if (SCAN_RSSI(pmadapter->pscan_table[i].rssi) > best_rssi) {
+                    best_rssi = SCAN_RSSI(pmadapter->pscan_table[i].rssi);
+                    best_net = i;
+                }
+            }
+            break;
+        case MLAN_BSS_MODE_AUTO:
+        default:
+            if (SCAN_RSSI(pmadapter->pscan_table[i].rssi) > best_rssi) {
+                best_rssi = SCAN_RSSI(pmadapter->pscan_table[i].rssi);
+                best_net = i;
+            }
+            break;
+        }
+    }
+
+    LEAVE();
+    return best_net;
+}
+
+/**
+ *  @brief Create a channel list for the driver to scan based on region info
+ *
+ *  Use the driver region/band information to construct a comprehensive list
+ *    of channels to scan.  This routine is used for any scan that is not
+ *    provided a specific channel list to scan.
+ *
+ *  @param pmpriv           A pointer to mlan_private structure
+ *  @param puser_scan_in    MNULL or pointer to scan configuration parameters
+ *  @param pscan_chan_list  Output parameter: Resulting channel list to scan
+ *  @param filtered_scan    Flag indicating whether or not a BSSID or SSID filter
+ *                          is being sent in the command to firmware.  Used to 
+ *                          increase the number of channels sent in a scan
+ *                          command and to disable the firmware channel scan
+ *                          filter.
+ *
+ *  @return                 n/a
+ */
+static t_void
+wlan_scan_create_channel_list(IN mlan_private * pmpriv,
+                              IN const wlan_user_scan_cfg * puser_scan_in,
+                              OUT ChanScanParamSet_t * pscan_chan_list,
+                              IN t_u8 filtered_scan)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    region_chan_t *pscan_region;
+    chan_freq_power_t *cfp;
+    t_u32 region_idx;
+    t_u32 chan_idx;
+    t_u32 next_chan;
+    t_u8 scan_type;
+
+    ENTER();
+
+    chan_idx = 0;
+
+    /* Set the default scan type to the user specified type, will later be
+       changed to passive on a per channel basis if restricted by regulatory
+       requirements (11d or 11h) */
+    scan_type = pmadapter->scan_type;
+
+    for (region_idx = 0;
+         region_idx < NELEMENTS(pmadapter->region_channel); region_idx++) {
+
+        if (wlan_11d_get_state(pmpriv) == ENABLE_11D &&
+            pmpriv->media_connected != MTRUE) {
+            /* Scan all the supported chan for the first scan */
+            if (!pmadapter->universal_channel[region_idx].valid)
+                continue;
+            pscan_region = &pmadapter->universal_channel[region_idx];
+        } else {
+            if (!pmadapter->region_channel[region_idx].valid)
+                continue;
+            pscan_region = &pmadapter->region_channel[region_idx];
+        }
+
+        for (next_chan = 0;
+             next_chan < pscan_region->num_cfp; next_chan++, chan_idx++) {
+
+            cfp = pscan_region->pcfp + next_chan;
+
+            if (wlan_11d_get_state(pmpriv) == ENABLE_11D)
+                scan_type =
+                    wlan_11d_get_scan_type(pmadapter, (t_u8) cfp->channel,
+                                           &pmadapter->parsed_region_chan);
+
+            switch (pscan_region->band) {
+            case BAND_A:
+                pscan_chan_list[chan_idx].radio_type =
+                    HostCmd_SCAN_RADIO_TYPE_A;
+                if (wlan_11h_radar_detect_required(pmpriv, cfp->channel)) {
+                    scan_type = HostCmd_SCAN_TYPE_PASSIVE;
+                }
+                break;
+            case BAND_B:
+            case BAND_G:
+            default:
+                pscan_chan_list[chan_idx].radio_type =
+                    HostCmd_SCAN_RADIO_TYPE_BG;
+                break;
+            }
+
+            if (puser_scan_in && puser_scan_in->chan_list[0].scan_time) {
+                pscan_chan_list[chan_idx].max_scan_time =
+                    wlan_cpu_to_le16((t_u16) puser_scan_in->chan_list[0].
+                                     scan_time);
+            } else if (scan_type == HostCmd_SCAN_TYPE_PASSIVE) {
+                pscan_chan_list[chan_idx].max_scan_time =
+                    wlan_cpu_to_le16(pmadapter->passive_scan_time);
+            } else {
+                pscan_chan_list[chan_idx].max_scan_time =
+                    wlan_cpu_to_le16(pmadapter->active_scan_time);
+            }
+
+            if (scan_type == HostCmd_SCAN_TYPE_PASSIVE) {
+                pscan_chan_list[chan_idx].chan_scan_mode.passive_scan = MTRUE;
+            } else {
+                pscan_chan_list[chan_idx].chan_scan_mode.passive_scan = MFALSE;
+            }
+
+            pscan_chan_list[chan_idx].chan_number = (t_u8) cfp->channel;
+
+            if (filtered_scan) {
+                pscan_chan_list[chan_idx].max_scan_time =
+                    wlan_cpu_to_le16(pmadapter->specific_scan_time);
+                pscan_chan_list[chan_idx].chan_scan_mode.disable_chan_filt =
+                    MTRUE;
+            }
+        }
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Construct and send multiple scan config commands to the firmware
+ *
+ *  Previous routines have created a wlan_scan_cmd_config with any requested
+ *   TLVs.  This function splits the channel TLV into max_chan_per_scan lists
+ *   and sends the portion of the channel TLV along with the other TLVs
+ *   to the wlan_cmd routines for execution in the firmware.
+ *
+ *  @param pmpriv             A pointer to mlan_private structure
+ *  @param pioctl_buf         A pointer to MLAN IOCTl Request buffer
+ *  @param max_chan_per_scan  Maximum number channels to be included in each
+ *                            scan command sent to firmware
+ *  @param filtered_scan      Flag indicating whether or not a BSSID or SSID
+ *                            filter is being used for the firmware command
+ *                            scan command sent to firmware
+ *  @param pscan_cfg_out      Scan configuration used for this scan.
+ *  @param pchan_tlv_out      Pointer in the pscan_cfg_out where the channel TLV
+ *                            should start.  This is past any other TLVs that
+ *                            must be sent down in each firmware command.
+ *  @param pscan_chan_list    List of channels to scan in max_chan_per_scan segments
+ *
+ *  @return                   MLAN_STATUS_SUCCESS or error return otherwise
+ */
+static mlan_status
+wlan_scan_channel_list(IN mlan_private * pmpriv,
+                       IN t_void * pioctl_buf,
+                       IN t_u32 max_chan_per_scan,
+                       IN t_u8 filtered_scan,
+                       OUT wlan_scan_cmd_config * pscan_cfg_out,
+                       OUT MrvlIEtypes_ChanListParamSet_t * pchan_tlv_out,
+                       IN ChanScanParamSet_t * pscan_chan_list)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    ChanScanParamSet_t *ptmp_chan_list;
+    ChanScanParamSet_t *pstart_chan;
+
+    t_u32 tlv_idx;
+    t_u32 total_scan_time;
+    t_u32 done_early;
+
+    ENTER();
+
+    if (!pscan_cfg_out || !pchan_tlv_out || !pscan_chan_list) {
+        PRINTM(MINFO, "Scan: Null detect: %p, %p, %p\n",
+               pscan_cfg_out, pchan_tlv_out, pscan_chan_list);
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    pchan_tlv_out->header.type = wlan_cpu_to_le16(TLV_TYPE_CHANLIST);
+
+    /* Set the temp channel struct pointer to the start of the desired list */
+    ptmp_chan_list = pscan_chan_list;
+
+    /* Loop through the desired channel list, sending a new firmware scan
+       commands for each max_chan_per_scan channels (or for 1,6,11 individually 
+       if configured accordingly) */
+    while (ptmp_chan_list->chan_number) {
+
+        tlv_idx = 0;
+        total_scan_time = 0;
+        pchan_tlv_out->header.len = 0;
+        pstart_chan = ptmp_chan_list;
+        done_early = MFALSE;
+
+        /* 
+         * Construct the Channel TLV for the scan command.  Continue to
+         * insert channel TLVs until:
+         *   - the tlv_idx hits the maximum configured per scan command
+         *   - the next channel to insert is 0 (end of desired channel list)
+         *   - done_early is set (controlling individual scanning of 1,6,11)
+         */
+        while (tlv_idx < max_chan_per_scan && ptmp_chan_list->chan_number &&
+               !done_early) {
+
+            PRINTM(MINFO, "Scan: Chan(%3d), Radio(%d), Mode(%d,%d), Dur(%d)\n",
+                   ptmp_chan_list->chan_number,
+                   ptmp_chan_list->radio_type,
+                   ptmp_chan_list->chan_scan_mode.passive_scan,
+                   ptmp_chan_list->chan_scan_mode.disable_chan_filt,
+                   wlan_le16_to_cpu(ptmp_chan_list->max_scan_time));
+
+            /* Copy the current channel TLV to the command being prepared */
+            memcpy(pchan_tlv_out->chan_scan_param + tlv_idx,
+                   ptmp_chan_list, sizeof(pchan_tlv_out->chan_scan_param));
+
+            /* Increment the TLV header length by the size appended */
+            pchan_tlv_out->header.len += sizeof(pchan_tlv_out->chan_scan_param);
+
+            /* 
+             * The tlv buffer length is set to the number of bytes of the
+             *   between the channel tlv pointer and the start of the
+             *   tlv buffer.  This compensates for any TLVs that were appended
+             *   before the channel list.
+             */
+            pscan_cfg_out->tlv_buf_len = (t_u32) ((t_u8 *) pchan_tlv_out
+                                                  - pscan_cfg_out->tlv_buf);
+
+            /* Add the size of the channel tlv header and the data length */
+            pscan_cfg_out->tlv_buf_len += (sizeof(pchan_tlv_out->header)
+                                           + pchan_tlv_out->header.len);
+
+            /* Increment the index to the channel tlv we are constructing */
+            tlv_idx++;
+
+            /* Count the total scan time per command */
+            total_scan_time += wlan_le16_to_cpu(ptmp_chan_list->max_scan_time);
+
+            done_early = MFALSE;
+
+            /* Stop the loop if the *current* channel is in the 1,6,11 set and
+               we are not filtering on a BSSID or SSID. */
+            if (!filtered_scan && (ptmp_chan_list->chan_number == 1 ||
+                                   ptmp_chan_list->chan_number == 6 ||
+                                   ptmp_chan_list->chan_number == 11)) {
+                done_early = MTRUE;
+            }
+
+            /* Increment the tmp pointer to the next channel to be scanned */
+            ptmp_chan_list++;
+
+            /* Stop the loop if the *next* channel is in the 1,6,11 set.  This
+               will cause it to be the only channel scanned on the next
+               interation */
+            if (!filtered_scan && (ptmp_chan_list->chan_number == 1 ||
+                                   ptmp_chan_list->chan_number == 6 ||
+                                   ptmp_chan_list->chan_number == 11)) {
+                done_early = MTRUE;
+            }
+        }
+
+        /* The total scan time should be less than scan command timeout value */
+        if (total_scan_time > MRVDRV_MAX_TOTAL_SCAN_TIME) {
+            PRINTM(MMSG,
+                   "Total scan time %d ms is over limit (%d ms), scan skipped\n",
+                   total_scan_time, MRVDRV_MAX_TOTAL_SCAN_TIME);
+            ret = MLAN_STATUS_FAILURE;
+            break;
+        }
+
+        pchan_tlv_out->header.len = wlan_cpu_to_le16(pchan_tlv_out->header.len);
+
+        pmpriv->adapter->pscan_channels = pstart_chan;
+
+        /* Send the scan command to the firmware with the specified cfg */
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_802_11_SCAN,
+                               HostCmd_ACT_GEN_SET,
+                               0, pioctl_buf, pscan_cfg_out);
+        if (ret)
+            break;
+    }
+
+    LEAVE();
+
+    if (ret) {
+        return MLAN_STATUS_FAILURE;
+    }
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Construct a wlan_scan_cmd_config structure to use in issue scan commands
+ *
+ *  Application layer or other functions can invoke wlan_scan_networks
+ *    with a scan configuration supplied in a wlan_ioctl_user_scan_cfg struct.
+ *    This structure is used as the basis of one or many wlan_scan_cmd_config
+ *    commands that are sent to the command processing module and sent to
+ *    firmware.
+ *
+ *  Create a wlan_scan_cmd_config based on the following user supplied
+ *    parameters (if present):
+ *             - SSID filter
+ *             - BSSID filter
+ *             - Number of Probes to be sent
+ *             - Channel list
+ *
+ *  If the SSID or BSSID filter is not present, disable/clear the filter.
+ *  If the number of probes is not set, use the adapter default setting
+ *  Qualify the channel
+ *
+ *  @param pmpriv               A pointer to mlan_private structure
+ *  @param puser_scan_in        MNULL or pointer to scan configuration parameters
+ *  @param pscan_cfg_out        Output parameter: Resulting scan configuration
+ *  @param ppchan_list_out      Output parameter: Pointer to the start of the
+ *                              channel TLV portion of the output scan config
+ *  @param pscan_chan_list      Output parameter: Pointer to the resulting 
+ *                              channel list to scan
+ *  @param pmax_chan_per_scan   Output parameter: Number of channels to scan for
+ *                              each issuance of the firmware scan command
+ *  @param pfiltered_scan       Output parameter: Flag indicating whether or not
+ *                              a BSSID or SSID filter is being sent in the
+ *                              command to firmware.  Used to increase the number
+ *                              of channels sent in a scan command and to 
+ *                              disable the firmware channel scan filter.
+ *  @param pscan_current_only   Output parameter: Flag indicating whether or not
+ *                              we are only scanning our current active channel
+ *
+ *  @return                 n/a
+ */
+static t_void
+wlan_scan_setup_scan_config(IN mlan_private * pmpriv,
+                            IN const wlan_user_scan_cfg * puser_scan_in,
+                            OUT wlan_scan_cmd_config * pscan_cfg_out,
+                            OUT MrvlIEtypes_ChanListParamSet_t **
+                            ppchan_list_out,
+                            OUT ChanScanParamSet_t * pscan_chan_list,
+                            OUT t_u8 * pmax_chan_per_scan,
+                            OUT t_u8 * pfiltered_scan,
+                            OUT t_u8 * pscan_current_only)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    MrvlIEtypes_NumProbes_t *pnum_probes_tlv;
+    MrvlIEtypes_WildCardSsIdParamSet_t *pwildcard_ssid_tlv;
+    MrvlIEtypes_RatesParamSet_t *prates_tlv;
+    const t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = { 0, 0, 0, 0, 0, 0 };
+    t_u8 *ptlv_pos;
+    t_u32 num_probes;
+    t_u32 ssid_len;
+    t_u32 chan_idx;
+    t_u32 scan_type;
+    t_u16 scan_dur;
+    t_u8 channel;
+    t_u8 radio_type;
+    t_u32 ssid_idx;
+    t_u8 ssid_filter;
+    WLAN_802_11_RATES rates;
+    t_u32 rates_size;
+    MrvlIETypes_HTCap_t *pht_cap;
+
+    ENTER();
+
+    /* The tlv_buf_len is calculated for each scan command.  The TLVs added in
+       this routine will be preserved since the routine that sends the command
+       will append channelTLVs at *ppchan_list_out.  The difference between the 
+       *ppchan_list_out and the tlv_buf start will be used to calculate the
+       size of anything we add in this routine. */
+    pscan_cfg_out->tlv_buf_len = 0;
+
+    /* Running tlv pointer.  Assigned to ppchan_list_out at end of function so
+       later routines know where channels can be added to the command buf */
+    ptlv_pos = pscan_cfg_out->tlv_buf;
+
+    /* Initialize the scan as un-filtered; the flag is later set to TRUE below
+       if a SSID or BSSID filter is sent in the command */
+    *pfiltered_scan = MFALSE;
+
+    /* Initialize the scan as not being only on the current channel.  If the
+       channel list is customized, only contains one channel, and is the active 
+       channel, this is set true and data flow is not halted. */
+    *pscan_current_only = MFALSE;
+
+    if (puser_scan_in) {
+
+        /* Default the ssid_filter flag to TRUE, set false under certain
+           wildcard conditions and qualified by the existence of an SSID list
+           before marking the scan as filtered */
+        ssid_filter = MTRUE;
+
+        /* Set the bss type scan filter, use Adapter setting if unset */
+        pscan_cfg_out->bss_mode =
+            (puser_scan_in->bss_mode ? (t_u8) puser_scan_in->
+             bss_mode : (t_u8) pmadapter->scan_mode);
+
+        /* Set the number of probes to send, use Adapter setting if unset */
+        num_probes = (puser_scan_in->num_probes ? puser_scan_in->num_probes :
+                      pmadapter->scan_probes);
+
+        /* 
+         * Set the BSSID filter to the incoming configuration,
+         *   if non-zero.  If not set, it will remain disabled (all zeros).
+         */
+        memcpy(pscan_cfg_out->specific_bssid,
+               puser_scan_in->specific_bssid,
+               sizeof(pscan_cfg_out->specific_bssid));
+
+        for (ssid_idx = 0; ((ssid_idx < NELEMENTS(puser_scan_in->ssid_list))
+                            && (*puser_scan_in->ssid_list[ssid_idx].ssid
+                                || puser_scan_in->ssid_list[ssid_idx].max_len));
+             ssid_idx++) {
+
+            ssid_len =
+                wlan_strlen((t_s8 *) puser_scan_in->ssid_list[ssid_idx].ssid) +
+                1;
+
+            pwildcard_ssid_tlv
+                = (MrvlIEtypes_WildCardSsIdParamSet_t *) ptlv_pos;
+            pwildcard_ssid_tlv->header.type
+                = wlan_cpu_to_le16(TLV_TYPE_WILDCARDSSID);
+            pwildcard_ssid_tlv->header.len
+                =
+                (t_u16) (ssid_len +
+                         sizeof(pwildcard_ssid_tlv->max_ssid_length));
+            pwildcard_ssid_tlv->max_ssid_length =
+                puser_scan_in->ssid_list[ssid_idx].max_len;
+
+            memcpy(pwildcard_ssid_tlv->ssid,
+                   puser_scan_in->ssid_list[ssid_idx].ssid, ssid_len);
+
+            ptlv_pos += (sizeof(pwildcard_ssid_tlv->header)
+                         + pwildcard_ssid_tlv->header.len);
+
+            pwildcard_ssid_tlv->header.len
+                = wlan_cpu_to_le16(pwildcard_ssid_tlv->header.len);
+
+            PRINTM(MINFO, "Scan: ssid_list[%d]: %s, %d\n",
+                   ssid_idx,
+                   pwildcard_ssid_tlv->ssid,
+                   pwildcard_ssid_tlv->max_ssid_length);
+
+            /* Empty wildcard ssid with a maxlen will match many or potentially 
+               all SSIDs (maxlen == 32), therefore do not treat the scan as
+               filtered. */
+            if (!ssid_len && pwildcard_ssid_tlv->max_ssid_length) {
+                ssid_filter = MFALSE;
+            }
+        }
+
+        /* 
+         *  The default number of channels sent in the command is low to
+         *    ensure the response buffer from the firmware does not truncate
+         *    scan results.  That is not an issue with an SSID or BSSID
+         *    filter applied to the scan results in the firmware.
+         */
+        if ((ssid_idx && ssid_filter)
+            || memcmp(pscan_cfg_out->specific_bssid, &zero_mac,
+                      sizeof(zero_mac))) {
+            *pfiltered_scan = MTRUE;
+        }
+
+    } else {
+        pscan_cfg_out->bss_mode = (t_u8) pmadapter->scan_mode;
+        num_probes = pmadapter->scan_probes;
+    }
+
+    /* 
+     *  If a specific BSSID or SSID is used, the number of channels in the 
+     *  scan command will be increased to the absolute maximum.
+     */
+    if (*pfiltered_scan)
+        *pmax_chan_per_scan = MRVDRV_MAX_CHANNELS_PER_SPECIFIC_SCAN;
+    else
+        *pmax_chan_per_scan = MRVDRV_CHANNELS_PER_SCAN_CMD;
+
+    /* If the input config or adapter has the number of Probes set, add tlv */
+    if (num_probes) {
+
+        PRINTM(MINFO, "Scan: num_probes = %d\n", num_probes);
+
+        pnum_probes_tlv = (MrvlIEtypes_NumProbes_t *) ptlv_pos;
+        pnum_probes_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_NUMPROBES);
+        pnum_probes_tlv->header.len = sizeof(pnum_probes_tlv->num_probes);
+        pnum_probes_tlv->num_probes = wlan_cpu_to_le16((t_u16) num_probes);
+
+        ptlv_pos +=
+            sizeof(pnum_probes_tlv->header) + pnum_probes_tlv->header.len;
+
+        pnum_probes_tlv->header.len =
+            wlan_cpu_to_le16(pnum_probes_tlv->header.len);
+    }
+
+    /* Append rates tlv */
+    memset(rates, 0, sizeof(rates));
+
+    rates_size = wlan_get_supported_rates(pmpriv, rates);
+
+    prates_tlv = (MrvlIEtypes_RatesParamSet_t *) ptlv_pos;
+    prates_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_RATES);
+    prates_tlv->header.len = wlan_cpu_to_le16((t_u16) rates_size);
+    memcpy(prates_tlv->rates, rates, rates_size);
+    ptlv_pos += sizeof(prates_tlv->header) + rates_size;
+
+    PRINTM(MINFO, "SCAN_CMD: Rates size = %d\n", rates_size);
+
+    if (ISSUPP_11NENABLED(pmpriv->adapter->fw_cap_info)
+        && (pmpriv->adapter->config_bands & BAND_GN
+            || pmpriv->adapter->config_bands & BAND_AN)) {
+        pht_cap = (MrvlIETypes_HTCap_t *) ptlv_pos;
+        memset(pht_cap, 0, sizeof(MrvlIETypes_HTCap_t));
+        pht_cap->header.type = wlan_cpu_to_le16(HT_CAPABILITY);
+        pht_cap->header.len = sizeof(HTCap_t);
+        wlan_fill_cap_info(pmadapter, pht_cap);
+        pht_cap->ht_cap.ht_cap_info =
+            wlan_cpu_to_le16(pht_cap->ht_cap.ht_cap_info);
+        HEXDUMP("SCAN: HT_CAPABILITIES IE", (t_u8 *) pht_cap,
+                sizeof(MrvlIETypes_HTCap_t));
+        ptlv_pos += sizeof(MrvlIETypes_HTCap_t);
+        pht_cap->header.len = wlan_cpu_to_le16(pht_cap->header.len);
+    }
+
+    /** Append vendor specific IE TLV */
+    wlan_cmd_append_vsie_tlv(pmpriv, MLAN_VSIE_MASK_SCAN, &ptlv_pos);
+
+    /* 
+     * Set the output for the channel TLV to the address in the tlv buffer
+     *   past any TLVs that were added in this function (SSID, num_probes).
+     *   Channel TLVs will be added past this for each scan command, preserving
+     *   the TLVs that were previously added.
+     */
+    *ppchan_list_out = (MrvlIEtypes_ChanListParamSet_t *) ptlv_pos;
+
+    if (puser_scan_in && puser_scan_in->chan_list[0].chan_number) {
+
+        PRINTM(MINFO, "Scan: Using supplied channel list\n");
+
+        for (chan_idx = 0;
+             chan_idx < WLAN_USER_SCAN_CHAN_MAX
+             && puser_scan_in->chan_list[chan_idx].chan_number; chan_idx++) {
+
+            channel = puser_scan_in->chan_list[chan_idx].chan_number;
+            (pscan_chan_list + chan_idx)->chan_number = channel;
+
+            radio_type = puser_scan_in->chan_list[chan_idx].radio_type;
+            (pscan_chan_list + chan_idx)->radio_type = radio_type;
+
+            scan_type = puser_scan_in->chan_list[chan_idx].scan_type;
+
+            /* Prevent active scanning on a radar controlled channel */
+            if (radio_type == HostCmd_SCAN_RADIO_TYPE_A) {
+                if (wlan_11h_radar_detect_required(pmpriv, channel)) {
+                    scan_type = HostCmd_SCAN_TYPE_PASSIVE;
+                }
+            }
+            if (scan_type == HostCmd_SCAN_TYPE_PASSIVE) {
+                (pscan_chan_list + chan_idx)->chan_scan_mode.passive_scan =
+                    MTRUE;
+            } else {
+                (pscan_chan_list + chan_idx)->chan_scan_mode.passive_scan =
+                    MFALSE;
+            }
+
+            if (puser_scan_in->chan_list[chan_idx].scan_time) {
+                scan_dur = (t_u16) puser_scan_in->chan_list[chan_idx].scan_time;
+            } else {
+                if (scan_type == HostCmd_SCAN_TYPE_PASSIVE) {
+                    scan_dur = pmadapter->passive_scan_time;
+                } else if (*pfiltered_scan) {
+                    scan_dur = pmadapter->specific_scan_time;
+                } else {
+                    scan_dur = pmadapter->active_scan_time;
+                }
+            }
+
+            (pscan_chan_list + chan_idx)->min_scan_time =
+                wlan_cpu_to_le16(scan_dur);
+            (pscan_chan_list + chan_idx)->max_scan_time =
+                wlan_cpu_to_le16(scan_dur);
+        }
+
+        /* Check if we are only scanning the current channel */
+        if ((chan_idx == 1)
+            && (puser_scan_in->chan_list[0].chan_number
+                == pmpriv->curr_bss_params.bss_descriptor.channel)) {
+            *pscan_current_only = MTRUE;
+            PRINTM(MINFO, "Scan: Scanning current channel only");
+        }
+
+    } else {
+        PRINTM(MINFO, "Scan: Creating full region channel list\n");
+        wlan_scan_create_channel_list(pmpriv, puser_scan_in, pscan_chan_list,
+                                      *pfiltered_scan);
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Inspect the scan response buffer for pointers to expected TLVs
+ *
+ *  TLVs can be included at the end of the scan response BSS information.
+ *    Parse the data in the buffer for pointers to TLVs that can potentially
+ *    be passed back in the response
+ *
+ *  @param pmadapter        Pointer to the mlan_adapter structure
+ *  @param ptlv             Pointer to the start of the TLV buffer to parse
+ *  @param tlv_buf_size     Size of the TLV buffer
+ *  @param req_tlv_type     Request TLV's type 
+ *  @param pptlv            Output parameter: Pointer to the request TLV if found
+ *
+ *  @return                 n/a
+ */
+static t_void
+wlan_ret_802_11_scan_get_tlv_ptrs(IN pmlan_adapter pmadapter,
+                                  IN MrvlIEtypes_Data_t * ptlv,
+                                  IN t_u32 tlv_buf_size,
+                                  IN t_u32 req_tlv_type,
+                                  OUT MrvlIEtypes_Data_t ** pptlv)
+{
+    MrvlIEtypes_Data_t *pcurrent_tlv;
+    t_u32 tlv_buf_left;
+    t_u32 tlv_type;
+    t_u32 tlv_len;
+
+    ENTER();
+
+    pcurrent_tlv = ptlv;
+    tlv_buf_left = tlv_buf_size;
+    *pptlv = MNULL;
+
+    PRINTM(MINFO, "SCAN_RESP: tlv_buf_size = %d\n", tlv_buf_size);
+
+    while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
+
+        tlv_type = wlan_le16_to_cpu(pcurrent_tlv->header.type);
+        tlv_len = wlan_le16_to_cpu(pcurrent_tlv->header.len);
+
+        if (sizeof(ptlv->header) + tlv_len > tlv_buf_left) {
+            PRINTM(MERROR, "SCAN_RESP: TLV buffer corrupt\n");
+            break;
+        }
+
+        if (req_tlv_type == tlv_type) {
+            switch (tlv_type) {
+            case TLV_TYPE_TSFTIMESTAMP:
+                PRINTM(MINFO, "SCAN_RESP: TSF Timestamp TLV, len = %d\n",
+                       tlv_len);
+                *pptlv = (MrvlIEtypes_Data_t *) pcurrent_tlv;
+                break;
+            case TLV_TYPE_CHANNELBANDLIST:
+                PRINTM(MINFO, "SCAN_RESP: CHANNEL BAND LIST TLV, len = %d\n",
+                       tlv_len);
+                *pptlv = (MrvlIEtypes_Data_t *) pcurrent_tlv;
+                break;
+            default:
+                PRINTM(MERROR, "SCAN_RESP: Unhandled TLV = %d\n", tlv_type);
+                /* Give up, this seems corrupted */
+                LEAVE();
+                return;
+            }
+        }
+
+        if (*pptlv) {
+            // HEXDUMP("SCAN_RESP: TLV Buf", (t_u8 *)*pptlv+4, tlv_len);
+            break;
+        }
+
+        tlv_buf_left -= (sizeof(ptlv->header) + tlv_len);
+        pcurrent_tlv = (MrvlIEtypes_Data_t *) (pcurrent_tlv->data + tlv_len);
+
+    }                           /* while */
+
+    LEAVE();
+}
+
+/**
+ *  @brief Interpret a BSS scan response returned from the firmware
+ *
+ *  Parse the various fixed fields and IEs passed back for a BSS probe
+ *   response or beacon from the scan command.  Record information as needed
+ *   in the scan table BSSDescriptor_t for that entry.
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pbss_entry   Output parameter: Pointer to the BSS Entry
+ *  @param pbeacon_info Pointer to the Beacon information
+ *  @param bytes_left   Number of bytes left to parse
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_interpret_bss_desc_with_ie(IN pmlan_adapter pmadapter,
+                                OUT BSSDescriptor_t * pbss_entry,
+                                IN t_u8 ** pbeacon_info, IN t_u32 * bytes_left)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    IEEEtypes_ElementId_e element_id;
+    IEEEtypes_FhParamSet_t *pfh_param_set;
+    IEEEtypes_DsParamSet_t *pds_param_set;
+    IEEEtypes_CfParamSet_t *pcf_param_set;
+    IEEEtypes_IbssParamSet_t *pibss_param_set;
+    IEEEtypes_CapInfo_t *pcap_info;
+    WLAN_802_11_FIXED_IEs fixed_ie;
+    t_u8 *pcurrent_ptr;
+    t_u8 *prate;
+    t_u8 element_len;
+    t_u16 total_ie_len;
+    t_u8 bytes_to_copy;
+    t_u8 rate_size;
+    t_u16 beacon_size;
+    t_u8 found_data_rate_ie;
+    t_u32 bytes_left_for_current_beacon;
+    IEEEtypes_ERPInfo_t *perp_info;
+
+    IEEEtypes_VendorSpecific_t *pvendor_ie;
+    const t_u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
+    const t_u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
+
+    IEEEtypes_CountryInfoSet_t *pcountry_info;
+
+    ENTER();
+
+    found_data_rate_ie = MFALSE;
+    rate_size = 0;
+    beacon_size = 0;
+
+    if (*bytes_left >= sizeof(beacon_size)) {
+        /* Extract & convert beacon size from the command buffer */
+        memcpy(&beacon_size, *pbeacon_info, sizeof(beacon_size));
+        beacon_size = wlan_le16_to_cpu(beacon_size);
+        *bytes_left -= sizeof(beacon_size);
+        *pbeacon_info += sizeof(beacon_size);
+    }
+
+    if (!beacon_size || beacon_size > *bytes_left) {
+
+        *pbeacon_info += *bytes_left;
+        *bytes_left = 0;
+
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Initialize the current working beacon pointer for this BSS iteration */
+    pcurrent_ptr = *pbeacon_info;
+
+    /* Advance the return beacon pointer past the current beacon */
+    *pbeacon_info += beacon_size;
+    *bytes_left -= beacon_size;
+
+    bytes_left_for_current_beacon = beacon_size;
+
+    memcpy(pbss_entry->mac_address, pcurrent_ptr, MLAN_MAC_ADDR_LENGTH);
+    PRINTM(MINFO, "InterpretIE: AP MAC Addr-%02x:%02x:%02x:%02x:%02x:%02x\n",
+           pbss_entry->mac_address[0], pbss_entry->mac_address[1],
+           pbss_entry->mac_address[2], pbss_entry->mac_address[3],
+           pbss_entry->mac_address[4], pbss_entry->mac_address[5]);
+
+    pcurrent_ptr += MLAN_MAC_ADDR_LENGTH;
+    bytes_left_for_current_beacon -= MLAN_MAC_ADDR_LENGTH;
+
+    if (bytes_left_for_current_beacon < 12) {
+        PRINTM(MERROR, "InterpretIE: Not enough bytes left\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* 
+     * Next 4 fields are RSSI, time stamp, beacon interval,
+     *   and capability information
+     */
+
+    /* RSSI is 1 byte long */
+    pbss_entry->rssi = (t_s32) (*pcurrent_ptr);
+    PRINTM(MINFO, "InterpretIE: RSSI=%02X\n", *pcurrent_ptr);
+    pcurrent_ptr += 1;
+    bytes_left_for_current_beacon -= 1;
+
+    /* 
+     *  The RSSI is not part of the beacon/probe response.  After we have
+     *    advanced pcurrent_ptr past the RSSI field, save the remaining
+     *    data for use at the application layer
+     */
+    pbss_entry->pbeacon_buf = pcurrent_ptr;
+    pbss_entry->beacon_buf_size = bytes_left_for_current_beacon;
+
+    /* Time stamp is 8 bytes long */
+    memcpy(fixed_ie.time_stamp, pcurrent_ptr, 8);
+    memcpy(pbss_entry->time_stamp, pcurrent_ptr, 8);
+    pcurrent_ptr += 8;
+    bytes_left_for_current_beacon -= 8;
+
+    /* Beacon interval is 2 bytes long */
+    memcpy(&fixed_ie.beacon_interval, pcurrent_ptr, 2);
+    pbss_entry->beacon_period = wlan_le16_to_cpu(fixed_ie.beacon_interval);
+    pcurrent_ptr += 2;
+    bytes_left_for_current_beacon -= 2;
+
+    /* Capability information is 2 bytes long */
+    memcpy(&fixed_ie.capabilities, pcurrent_ptr, 2);
+    PRINTM(MINFO, "InterpretIE: fixed_ie.capabilities=0x%X\n",
+           fixed_ie.capabilities);
+    fixed_ie.capabilities = wlan_le16_to_cpu(fixed_ie.capabilities);
+    pcap_info = (IEEEtypes_CapInfo_t *) & fixed_ie.capabilities;
+    memcpy(&pbss_entry->cap_info, pcap_info, sizeof(IEEEtypes_CapInfo_t));
+    pcurrent_ptr += 2;
+    bytes_left_for_current_beacon -= 2;
+
+    /* Rest of the current buffer are IE's */
+    PRINTM(MINFO, "InterpretIE: IELength for this AP = %d\n",
+           bytes_left_for_current_beacon);
+
+    HEXDUMP("InterpretIE: IE info", (t_u8 *) pcurrent_ptr,
+            bytes_left_for_current_beacon);
+
+    if (pcap_info->privacy) {
+        PRINTM(MINFO, "InterpretIE: AP WEP enabled\n");
+        pbss_entry->privacy = Wlan802_11PrivFilter8021xWEP;
+    } else {
+        pbss_entry->privacy = Wlan802_11PrivFilterAcceptAll;
+    }
+
+    if (pcap_info->ibss == 1) {
+        pbss_entry->bss_mode = MLAN_BSS_MODE_IBSS;
+    } else {
+        pbss_entry->bss_mode = MLAN_BSS_MODE_INFRA;
+    }
+
+    if (pcap_info->spectrum_mgmt == 1) {
+        PRINTM(MINFO, "InterpretIE: 11h- Spectrum Management "
+               "capability bit found\n");
+        pbss_entry->wlan_11h_bss_info.sensed_11h = 1;
+    }
+
+    /* Process variable IE */
+    while (bytes_left_for_current_beacon >= 2) {
+        element_id = (IEEEtypes_ElementId_e) (*((t_u8 *) pcurrent_ptr));
+        element_len = *((t_u8 *) pcurrent_ptr + 1);
+        total_ie_len = element_len + sizeof(IEEEtypes_Header_t);
+
+        if (bytes_left_for_current_beacon < total_ie_len) {
+            PRINTM(MERROR, "InterpretIE: Error in processing IE, "
+                   "bytes left < IE length\n");
+            bytes_left_for_current_beacon = 0;
+            ret = MLAN_STATUS_FAILURE;
+            continue;
+        }
+
+        switch (element_id) {
+
+        case SSID:
+            pbss_entry->ssid.ssid_len = element_len;
+            memcpy(pbss_entry->ssid.ssid, (pcurrent_ptr + 2), element_len);
+            PRINTM(MINFO, "InterpretIE: ssid: %-32s\n", pbss_entry->ssid.ssid);
+            break;
+
+        case SUPPORTED_RATES:
+            memcpy(pbss_entry->data_rates, pcurrent_ptr + 2, element_len);
+            memcpy(pbss_entry->supported_rates, pcurrent_ptr + 2, element_len);
+            HEXDUMP("InterpretIE: SupportedRates:",
+                    pbss_entry->supported_rates, element_len);
+            rate_size = element_len;
+            found_data_rate_ie = MTRUE;
+            break;
+
+        case FH_PARAM_SET:
+            pfh_param_set = (IEEEtypes_FhParamSet_t *) pcurrent_ptr;
+            pbss_entry->network_type_use = Wlan802_11FH;
+            memcpy(&pbss_entry->phy_param_set.fh_param_set, pfh_param_set,
+                   sizeof(IEEEtypes_FhParamSet_t));
+            pbss_entry->phy_param_set.fh_param_set.dwell_time
+                =
+                wlan_le16_to_cpu(pbss_entry->phy_param_set.fh_param_set.
+                                 dwell_time);
+            break;
+
+        case DS_PARAM_SET:
+            pds_param_set = (IEEEtypes_DsParamSet_t *) pcurrent_ptr;
+
+            pbss_entry->network_type_use = Wlan802_11DS;
+            pbss_entry->channel = pds_param_set->current_chan;
+
+            memcpy(&pbss_entry->phy_param_set.ds_param_set, pds_param_set,
+                   sizeof(IEEEtypes_DsParamSet_t));
+            break;
+
+        case CF_PARAM_SET:
+            pcf_param_set = (IEEEtypes_CfParamSet_t *) pcurrent_ptr;
+            memcpy(&pbss_entry->ss_param_set.cf_param_set, pcf_param_set,
+                   sizeof(IEEEtypes_CfParamSet_t));
+            break;
+
+        case IBSS_PARAM_SET:
+            pibss_param_set = (IEEEtypes_IbssParamSet_t *) pcurrent_ptr;
+            pbss_entry->atim_window =
+                wlan_le16_to_cpu(pibss_param_set->atim_window);
+            memcpy(&pbss_entry->ss_param_set.ibss_param_set, pibss_param_set,
+                   sizeof(IEEEtypes_IbssParamSet_t));
+            break;
+
+            /* Handle Country Info IE */
+        case COUNTRY_INFO:
+            pcountry_info = (IEEEtypes_CountryInfoSet_t *) pcurrent_ptr;
+
+            if (pcountry_info->len < sizeof(pcountry_info->country_code) ||
+                (unsigned) (pcountry_info->len + 2) >
+                sizeof(IEEEtypes_CountryInfoFullSet_t)) {
+                PRINTM(MERROR,
+                       "InterpretIE: 11D- Err "
+                       "country_info len =%d min=%d max=%d\n",
+                       pcountry_info->len, sizeof(pcountry_info->country_code),
+                       sizeof(IEEEtypes_CountryInfoFullSet_t));
+                LEAVE();
+                return MLAN_STATUS_FAILURE;
+            }
+
+            memcpy(&pbss_entry->country_info,
+                   pcountry_info, pcountry_info->len + 2);
+            HEXDUMP("InterpretIE: 11D- country_info:",
+                    (t_u8 *) pcountry_info, (t_u32) (pcountry_info->len + 2));
+            break;
+
+        case ERP_INFO:
+            perp_info = (IEEEtypes_ERPInfo_t *) pcurrent_ptr;
+            pbss_entry->erp_flags = perp_info->erp_flags;
+            break;
+
+        case POWER_CONSTRAINT:
+        case POWER_CAPABILITY:
+        case TPC_REPORT:
+        case CHANNEL_SWITCH_ANN:
+        case QUIET:
+        case IBSS_DFS:
+        case SUPPORTED_CHANNELS:
+        case TPC_REQUEST:
+            wlan_11h_process_bss_elem(&pbss_entry->wlan_11h_bss_info,
+                                      pcurrent_ptr);
+            break;
+        case EXTENDED_SUPPORTED_RATES:
+            /* 
+             * Only process extended supported rate
+             * if data rate is already found.
+             * Data rate IE should come before
+             * extended supported rate IE
+             */
+            if (found_data_rate_ie) {
+                if ((element_len + rate_size) > WLAN_SUPPORTED_RATES) {
+                    bytes_to_copy = (WLAN_SUPPORTED_RATES - rate_size);
+                } else {
+                    bytes_to_copy = element_len;
+                }
+
+                prate = (t_u8 *) pbss_entry->data_rates;
+                prate += rate_size;
+                memcpy(prate, pcurrent_ptr + 2, bytes_to_copy);
+
+                prate = (t_u8 *) pbss_entry->supported_rates;
+                prate += rate_size;
+                memcpy(prate, pcurrent_ptr + 2, bytes_to_copy);
+            }
+            HEXDUMP("InterpretIE: ExtSupportedRates:",
+                    pbss_entry->supported_rates, element_len + rate_size);
+            break;
+
+        case VENDOR_SPECIFIC_221:
+            pvendor_ie = (IEEEtypes_VendorSpecific_t *) pcurrent_ptr;
+
+            if (!memcmp(pvendor_ie->vend_hdr.oui, wpa_oui, sizeof(wpa_oui))) {
+                pbss_entry->pwpa_ie =
+                    (IEEEtypes_VendorSpecific_t *) pcurrent_ptr;
+                pbss_entry->wpa_offset =
+                    (t_u16) (pcurrent_ptr - pbss_entry->pbeacon_buf);
+                HEXDUMP("InterpretIE: Resp WPA_IE",
+                        (t_u8 *) pbss_entry->pwpa_ie,
+                        ((*(pbss_entry->pwpa_ie)).vend_hdr.len +
+                         sizeof(IEEEtypes_Header_t)));
+            } else
+                if (!memcmp(pvendor_ie->vend_hdr.oui, wmm_oui, sizeof(wmm_oui)))
+            {
+                if (total_ie_len == sizeof(IEEEtypes_WmmParameter_t)
+                    || total_ie_len == sizeof(IEEEtypes_WmmInfo_t)) {
+
+                    /* 
+                     * Only accept and copy the WMM IE if it matches
+                     * the size expected for the WMM Info IE or the
+                     * WMM Parameter IE.
+                     */
+                    memcpy((t_u8 *) & pbss_entry->wmm_ie, pcurrent_ptr,
+                           total_ie_len);
+                    HEXDUMP("InterpretIE: Resp WMM_IE",
+                            (t_u8 *) & pbss_entry->wmm_ie, total_ie_len);
+                }
+            }
+            break;
+        case RSN_IE:
+            pbss_entry->prsn_ie = (IEEEtypes_Generic_t *) pcurrent_ptr;
+            pbss_entry->rsn_offset =
+                (t_u16) (pcurrent_ptr - pbss_entry->pbeacon_buf);
+            HEXDUMP("InterpretIE: Resp RSN_IE", (t_u8 *) pbss_entry->prsn_ie,
+                    (*(pbss_entry->prsn_ie)).ieee_hdr.len +
+                    sizeof(IEEEtypes_Header_t));
+            break;
+        case WAPI_IE:
+            pbss_entry->pwapi_ie = (IEEEtypes_Generic_t *) pcurrent_ptr;
+            pbss_entry->wapi_offset =
+                (t_u16) (pcurrent_ptr - pbss_entry->pbeacon_buf);
+            HEXDUMP("InterpretIE: Resp WAPI_IE", (t_u8 *) pbss_entry->pwapi_ie,
+                    (*(pbss_entry->pwapi_ie)).ieee_hdr.len +
+                    sizeof(IEEEtypes_Header_t));
+            break;
+        case HT_CAPABILITY:
+            pbss_entry->pht_cap = (IEEEtypes_HTCap_t *) pcurrent_ptr;
+            pbss_entry->ht_cap_offset =
+                (t_u16) (pcurrent_ptr - pbss_entry->pbeacon_buf);
+            HEXDUMP("InterpretIE: Resp HTCAP_IE", (t_u8 *) pbss_entry->pht_cap,
+                    (*(pbss_entry->pht_cap)).ieee_hdr.len +
+                    sizeof(IEEEtypes_Header_t));
+            break;
+        case HT_OPERATION:
+            pbss_entry->pht_info = (IEEEtypes_HTInfo_t *) pcurrent_ptr;
+            pbss_entry->ht_info_offset =
+                (t_u16) (pcurrent_ptr - pbss_entry->pbeacon_buf);
+            HEXDUMP("InterpretIE: Resp HTINFO_IE",
+                    (t_u8 *) pbss_entry->pht_info,
+                    (*(pbss_entry->pht_info)).ieee_hdr.len +
+                    sizeof(IEEEtypes_Header_t));
+            break;
+        case BSSCO_2040:
+            pbss_entry->pbss_co_2040 = (IEEEtypes_2040BSSCo_t *) pcurrent_ptr;
+            pbss_entry->bss_co_2040_offset =
+                (t_u16) (pcurrent_ptr - pbss_entry->pbeacon_buf);
+            HEXDUMP("InterpretIE: Resp 2040BSSCOEXISTANCE_IE",
+                    (t_u8 *) pbss_entry->pbss_co_2040,
+                    (*(pbss_entry->pbss_co_2040)).ieee_hdr.len +
+                    sizeof(IEEEtypes_Header_t));
+            break;
+        case EXT_CAPABILITY:
+            pbss_entry->pext_cap = (IEEEtypes_ExtCap_t *) pcurrent_ptr;
+            pbss_entry->ext_cap_offset =
+                (t_u16) (pcurrent_ptr - pbss_entry->pbeacon_buf);
+            HEXDUMP("InterpretIE: Resp EXTCAP_IE",
+                    (t_u8 *) pbss_entry->pext_cap,
+                    (*(pbss_entry->pext_cap)).ieee_hdr.len +
+                    sizeof(IEEEtypes_Header_t));
+            break;
+        case OVERLAPBSSSCANPARAM:
+            pbss_entry->poverlap_bss_scan_param =
+                (IEEEtypes_OverlapBSSScanParam_t *) pcurrent_ptr;
+            pbss_entry->overlap_bss_offset =
+                (t_u16) (pcurrent_ptr - pbss_entry->pbeacon_buf);
+            HEXDUMP("InterpretIE: Resp HTCAP_IE",
+                    (t_u8 *) pbss_entry->poverlap_bss_scan_param,
+                    (*(pbss_entry->poverlap_bss_scan_param)).ieee_hdr.len +
+                    sizeof(IEEEtypes_Header_t));
+            break;
+        }
+
+        pcurrent_ptr += element_len + 2;
+
+        /* Need to account for IE ID and IE Len */
+        bytes_left_for_current_beacon -= (element_len + 2);
+
+    }                           /* while (bytes_left_for_current_beacon > 2) */
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Store a beacon or probe response for a BSS returned in the scan
+ *  
+ *  Store a new scan response or an update for a previous scan response.  New
+ *    entries need to verify that they do not exceed the total amount of 
+ *    memory allocated for the table.
+
+ *  Replacement entries need to take into consideration the amount of space 
+ *    currently allocated for the beacon/probe response and adjust the entry
+ *    as needed.  
+ *
+ *  A small amount of extra pad (SCAN_BEACON_ENTRY_PAD) is generally reserved
+ *    for an entry in case it is a beacon since a probe response for the
+ *    network will by larger per the standard.  This helps to reduce the 
+ *    amount of memory copying to fit a new probe response into an entry 
+ *    already occupied by a network's previously stored beacon.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param beacon_idx   Index in the scan table to store this entry; may be
+ *                      replacing an older duplicate entry for this BSS
+ *  @param num_of_ent   Number of entries currently in the table
+ *  @param pnew_beacon  Pointer to the new beacon/probe response to save
+ *
+ *  @return           n/a
+ */
+static t_void
+wlan_ret_802_11_scan_store_beacon(IN mlan_private * pmpriv,
+                                  IN t_u32 beacon_idx,
+                                  IN t_u32 num_of_ent,
+                                  IN BSSDescriptor_t * pnew_beacon)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    t_u8 *pbcn_store;
+    t_u32 new_bcn_size;
+    t_u32 old_bcn_size;
+    t_u32 bcn_space;
+    t_u32 adj_idx;
+
+    ENTER();
+
+    if (pmadapter->pscan_table[beacon_idx].pbeacon_buf) {
+
+        new_bcn_size = pnew_beacon->beacon_buf_size;
+        old_bcn_size = pmadapter->pscan_table[beacon_idx].beacon_buf_size;
+        bcn_space = pmadapter->pscan_table[beacon_idx].beacon_buf_size_max;
+        pbcn_store = pmadapter->pscan_table[beacon_idx].pbeacon_buf;
+
+        /* Set the max to be the same as current entry unless changed below */
+        pnew_beacon->beacon_buf_size_max = bcn_space;
+
+        if (new_bcn_size == old_bcn_size) {
+            /* 
+             * Beacon is the same size as the previous entry.
+             *   Replace the previous contents with the scan result
+             */
+            memcpy(pbcn_store,
+                   pnew_beacon->pbeacon_buf, pnew_beacon->beacon_buf_size);
+
+        } else if (new_bcn_size <= bcn_space) {
+            /* 
+             * New beacon size will fit in the amount of space
+             *   we have previously allocated for it
+             */
+
+            /* Copy the new beacon buffer entry over the old one */
+            memcpy(pbcn_store, pnew_beacon->pbeacon_buf, new_bcn_size);
+
+            /* 
+             *  If the old beacon size was less than the maximum
+             *  we had alloted for the entry, and the new entry
+             *  is even smaller, reset the max size to the old beacon
+             *  entry and compress the storage space (leaving a new
+             *  pad space of (old_bcn_size - new_bcn_size).
+             */
+            if (old_bcn_size < bcn_space && new_bcn_size <= old_bcn_size) {
+                /* 
+                 * Old Beacon size is smaller than the alloted storage size.
+                 *   Shrink the alloted storage space.
+                 */
+                PRINTM(MINFO, "AppControl: Smaller Duplicate Beacon (%d), "
+                       "old = %d, new = %d, space = %d, left = %d\n",
+                       beacon_idx, old_bcn_size, new_bcn_size, bcn_space,
+                       (sizeof(pmadapter->bcn_buf) -
+                        (pmadapter->pbcn_buf_end - pmadapter->bcn_buf)));
+
+                /* 
+                 *  memmove (since the memory overlaps) the data
+                 *  after the beacon we just stored to the end of
+                 *  the current beacon.  This cleans up any unused
+                 *  space the old larger beacon was using in the buffer
+                 */
+                memmove(pbcn_store + old_bcn_size,
+                        pbcn_store + bcn_space,
+                        pmadapter->pbcn_buf_end - (pbcn_store + bcn_space));
+
+                /* 
+                 * Decrement the end pointer by the difference between
+                 *  the old larger size and the new smaller size since
+                 *  we are using less space due to the new beacon being
+                 *  smaller
+                 */
+                pmadapter->pbcn_buf_end -= (bcn_space - old_bcn_size);
+
+                /* Set the maximum storage size to the old beacon size */
+                pnew_beacon->beacon_buf_size_max = old_bcn_size;
+
+                /* Adjust beacon buffer pointers that are past the current */
+                for (adj_idx = 0; adj_idx < num_of_ent; adj_idx++) {
+                    if (pmadapter->pscan_table[adj_idx].pbeacon_buf >
+                        pbcn_store) {
+                        pmadapter->pscan_table[adj_idx].pbeacon_buf -=
+                            (bcn_space - old_bcn_size);
+                        if (pmadapter->pscan_table[adj_idx].pwpa_ie) {
+                            pmadapter->pscan_table[adj_idx].pwpa_ie =
+                                (IEEEtypes_VendorSpecific_t *)
+                                (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                                 pmadapter->pscan_table[adj_idx].wpa_offset);
+                        }
+                        if (pmadapter->pscan_table[adj_idx].prsn_ie) {
+                            pmadapter->pscan_table[adj_idx].prsn_ie =
+                                (IEEEtypes_Generic_t *)
+                                (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                                 pmadapter->pscan_table[adj_idx].rsn_offset);
+                        }
+                        if (pmadapter->pscan_table[adj_idx].pwapi_ie) {
+                            pmadapter->pscan_table[adj_idx].pwapi_ie =
+                                (IEEEtypes_Generic_t *)
+                                (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                                 pmadapter->pscan_table[adj_idx].wapi_offset);
+                        }
+                        if (pmadapter->pscan_table[adj_idx].pht_cap) {
+                            pmadapter->pscan_table[adj_idx].pht_cap =
+                                (IEEEtypes_HTCap_t *)
+                                (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                                 pmadapter->pscan_table[adj_idx].ht_cap_offset);
+                        }
+
+                        if (pmadapter->pscan_table[adj_idx].pht_info) {
+                            pmadapter->pscan_table[adj_idx].pht_info =
+                                (IEEEtypes_HTInfo_t *)
+                                (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                                 pmadapter->pscan_table[adj_idx].
+                                 ht_info_offset);
+                        }
+                        if (pmadapter->pscan_table[adj_idx].pbss_co_2040) {
+                            pmadapter->pscan_table[adj_idx].pbss_co_2040 =
+                                (IEEEtypes_2040BSSCo_t *)
+                                (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                                 pmadapter->pscan_table[adj_idx].
+                                 bss_co_2040_offset);
+                        }
+                        if (pmadapter->pscan_table[adj_idx].pext_cap) {
+                            pmadapter->pscan_table[adj_idx].pext_cap =
+                                (IEEEtypes_ExtCap_t *)
+                                (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                                 pmadapter->pscan_table[adj_idx].
+                                 ext_cap_offset);
+                        }
+                        if (pmadapter->pscan_table[adj_idx].
+                            poverlap_bss_scan_param) {
+                            pmadapter->pscan_table[adj_idx].
+                                poverlap_bss_scan_param =
+                                (IEEEtypes_OverlapBSSScanParam_t *)
+                                (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                                 pmadapter->pscan_table[adj_idx].
+                                 overlap_bss_offset);
+                        }
+                    }
+                }
+            }
+        } else if (pmadapter->pbcn_buf_end + (new_bcn_size - bcn_space)
+                   < (pmadapter->bcn_buf + sizeof(pmadapter->bcn_buf))) {
+            /* 
+             * Beacon is larger than space previously allocated (bcn_space)
+             *   and there is enough space left in the beaconBuffer to store
+             *   the additional data
+             */
+            PRINTM(MINFO, "AppControl: Larger Duplicate Beacon (%d), "
+                   "old = %d, new = %d, space = %d, left = %d\n",
+                   beacon_idx, old_bcn_size, new_bcn_size, bcn_space,
+                   (sizeof(pmadapter->bcn_buf) -
+                    (pmadapter->pbcn_buf_end - pmadapter->bcn_buf)));
+
+            /* 
+             * memmove (since the memory overlaps) the data
+             *  after the beacon we just stored to the end of
+             *  the current beacon.  This moves the data for
+             *  the beacons after this further in memory to
+             *  make space for the new larger beacon we are
+             *  about to copy in.
+             */
+            memmove(pbcn_store + new_bcn_size,
+                    pbcn_store + bcn_space,
+                    pmadapter->pbcn_buf_end - (pbcn_store + bcn_space));
+
+            /* Copy the new beacon buffer entry over the old one */
+            memcpy(pbcn_store, pnew_beacon->pbeacon_buf, new_bcn_size);
+
+            /* Move the beacon end pointer by the amount of new beacon data we
+               are adding */
+            pmadapter->pbcn_buf_end += (new_bcn_size - bcn_space);
+
+            /* 
+             * This entry is bigger than the alloted max space
+             *  previously reserved.  Increase the max space to
+             *  be equal to the new beacon size
+             */
+            pnew_beacon->beacon_buf_size_max = new_bcn_size;
+
+            /* Adjust beacon buffer pointers that are past the current */
+            for (adj_idx = 0; adj_idx < num_of_ent; adj_idx++) {
+                if (pmadapter->pscan_table[adj_idx].pbeacon_buf > pbcn_store) {
+                    pmadapter->pscan_table[adj_idx].pbeacon_buf
+                        += (new_bcn_size - bcn_space);
+                    if (pmadapter->pscan_table[adj_idx].pwpa_ie) {
+                        pmadapter->pscan_table[adj_idx].pwpa_ie =
+                            (IEEEtypes_VendorSpecific_t *)
+                            (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                             pmadapter->pscan_table[adj_idx].wpa_offset);
+                    }
+                    if (pmadapter->pscan_table[adj_idx].prsn_ie) {
+                        pmadapter->pscan_table[adj_idx].prsn_ie =
+                            (IEEEtypes_Generic_t *)
+                            (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                             pmadapter->pscan_table[adj_idx].rsn_offset);
+                    }
+                    if (pmadapter->pscan_table[adj_idx].pwapi_ie) {
+                        pmadapter->pscan_table[adj_idx].pwapi_ie =
+                            (IEEEtypes_Generic_t *)
+                            (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                             pmadapter->pscan_table[adj_idx].wapi_offset);
+                    }
+                    if (pmadapter->pscan_table[adj_idx].pht_cap) {
+                        pmadapter->pscan_table[adj_idx].pht_cap =
+                            (IEEEtypes_HTCap_t *)
+                            (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                             pmadapter->pscan_table[adj_idx].ht_cap_offset);
+                    }
+
+                    if (pmadapter->pscan_table[adj_idx].pht_info) {
+                        pmadapter->pscan_table[adj_idx].pht_info =
+                            (IEEEtypes_HTInfo_t *)
+                            (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                             pmadapter->pscan_table[adj_idx].ht_info_offset);
+                    }
+                    if (pmadapter->pscan_table[adj_idx].pbss_co_2040) {
+                        pmadapter->pscan_table[adj_idx].pbss_co_2040 =
+                            (IEEEtypes_2040BSSCo_t *)
+                            (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                             pmadapter->pscan_table[adj_idx].
+                             bss_co_2040_offset);
+                    }
+                    if (pmadapter->pscan_table[adj_idx].pext_cap) {
+                        pmadapter->pscan_table[adj_idx].pext_cap =
+                            (IEEEtypes_ExtCap_t *)
+                            (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                             pmadapter->pscan_table[adj_idx].ext_cap_offset);
+                    }
+                    if (pmadapter->pscan_table[adj_idx].poverlap_bss_scan_param) {
+                        pmadapter->pscan_table[adj_idx].
+                            poverlap_bss_scan_param =
+                            (IEEEtypes_OverlapBSSScanParam_t *)
+                            (pmadapter->pscan_table[adj_idx].pbeacon_buf +
+                             pmadapter->pscan_table[adj_idx].
+                             overlap_bss_offset);
+                    }
+                }
+            }
+        } else {
+            /* 
+             * Beacon is larger than the previously allocated space, but
+             *   there is not enough free space to store the additional data
+             */
+            PRINTM(MERROR,
+                   "AppControl: Failed: Larger Duplicate Beacon (%d),"
+                   " old = %d, new = %d, space = %d, left = %d\n",
+                   beacon_idx, old_bcn_size, new_bcn_size, bcn_space,
+                   (sizeof(pmadapter->bcn_buf) -
+                    (pmadapter->pbcn_buf_end - pmadapter->bcn_buf)));
+
+            /* Storage failure, keep old beacon intact */
+            pnew_beacon->beacon_buf_size = old_bcn_size;
+            if (pnew_beacon->pwpa_ie)
+                pnew_beacon->wpa_offset =
+                    pmadapter->pscan_table[beacon_idx].wpa_offset;
+            if (pnew_beacon->prsn_ie)
+                pnew_beacon->rsn_offset =
+                    pmadapter->pscan_table[beacon_idx].rsn_offset;
+            if (pnew_beacon->pwapi_ie)
+                pnew_beacon->wapi_offset =
+                    pmadapter->pscan_table[beacon_idx].wapi_offset;
+            if (pnew_beacon->pht_cap)
+                pnew_beacon->ht_cap_offset =
+                    pmadapter->pscan_table[beacon_idx].ht_cap_offset;
+            if (pnew_beacon->pht_info)
+                pnew_beacon->ht_info_offset =
+                    pmadapter->pscan_table[beacon_idx].ht_info_offset;
+            if (pnew_beacon->pbss_co_2040)
+                pnew_beacon->bss_co_2040_offset =
+                    pmadapter->pscan_table[beacon_idx].bss_co_2040_offset;
+            if (pnew_beacon->pext_cap)
+                pnew_beacon->ext_cap_offset =
+                    pmadapter->pscan_table[beacon_idx].ext_cap_offset;
+            if (pnew_beacon->poverlap_bss_scan_param)
+                pnew_beacon->overlap_bss_offset =
+                    pmadapter->pscan_table[beacon_idx].overlap_bss_offset;
+        }
+        /* Point the new entry to its permanent storage space */
+        pnew_beacon->pbeacon_buf = pbcn_store;
+        if (pnew_beacon->pwpa_ie) {
+            pnew_beacon->pwpa_ie = (IEEEtypes_VendorSpecific_t *)
+                (pnew_beacon->pbeacon_buf + pnew_beacon->wpa_offset);
+        }
+        if (pnew_beacon->prsn_ie) {
+            pnew_beacon->prsn_ie = (IEEEtypes_Generic_t *)
+                (pnew_beacon->pbeacon_buf + pnew_beacon->rsn_offset);
+        }
+        if (pnew_beacon->pwapi_ie) {
+            pnew_beacon->pwapi_ie = (IEEEtypes_Generic_t *)
+                (pnew_beacon->pbeacon_buf + pnew_beacon->wapi_offset);
+        }
+        if (pnew_beacon->pht_cap) {
+            pnew_beacon->pht_cap = (IEEEtypes_HTCap_t *)
+                (pnew_beacon->pbeacon_buf + pnew_beacon->ht_cap_offset);
+        }
+
+        if (pnew_beacon->pht_info) {
+            pnew_beacon->pht_info = (IEEEtypes_HTInfo_t *)
+                (pnew_beacon->pbeacon_buf + pnew_beacon->ht_info_offset);
+        }
+        if (pnew_beacon->pbss_co_2040) {
+            pnew_beacon->pbss_co_2040 = (IEEEtypes_2040BSSCo_t *)
+                (pnew_beacon->pbeacon_buf + pnew_beacon->bss_co_2040_offset);
+        }
+        if (pnew_beacon->pext_cap) {
+            pnew_beacon->pext_cap = (IEEEtypes_ExtCap_t *)
+                (pnew_beacon->pbeacon_buf + pnew_beacon->ext_cap_offset);
+        }
+        if (pnew_beacon->poverlap_bss_scan_param) {
+            pnew_beacon->poverlap_bss_scan_param =
+                (IEEEtypes_OverlapBSSScanParam_t *)
+                (pnew_beacon->pbeacon_buf + pnew_beacon->overlap_bss_offset);
+        }
+
+    } else {
+        /* 
+         * No existing beacon data exists for this entry, check to see
+         *   if we can fit it in the remaining space
+         */
+        if (pmadapter->pbcn_buf_end + pnew_beacon->beacon_buf_size +
+            SCAN_BEACON_ENTRY_PAD < (pmadapter->bcn_buf +
+                                     sizeof(pmadapter->bcn_buf))) {
+
+            /* 
+             * Copy the beacon buffer data from the local entry to the
+             *   adapter dev struct buffer space used to store the raw
+             *   beacon data for each entry in the scan table
+             */
+            memcpy(pmadapter->pbcn_buf_end, pnew_beacon->pbeacon_buf,
+                   pnew_beacon->beacon_buf_size);
+
+            /* Update the beacon ptr to point to the table save area */
+            pnew_beacon->pbeacon_buf = pmadapter->pbcn_buf_end;
+            pnew_beacon->beacon_buf_size_max = (pnew_beacon->beacon_buf_size
+                                                + SCAN_BEACON_ENTRY_PAD);
+
+            if (pnew_beacon->pwpa_ie) {
+                pnew_beacon->pwpa_ie = (IEEEtypes_VendorSpecific_t *)
+                    (pnew_beacon->pbeacon_buf + pnew_beacon->wpa_offset);
+            }
+            if (pnew_beacon->prsn_ie) {
+                pnew_beacon->prsn_ie = (IEEEtypes_Generic_t *)
+                    (pnew_beacon->pbeacon_buf + pnew_beacon->rsn_offset);
+            }
+            if (pnew_beacon->pwapi_ie) {
+                pnew_beacon->pwapi_ie = (IEEEtypes_Generic_t *)
+                    (pnew_beacon->pbeacon_buf + pnew_beacon->wapi_offset);
+            }
+            if (pnew_beacon->pht_cap) {
+                pnew_beacon->pht_cap = (IEEEtypes_HTCap_t *)
+                    (pnew_beacon->pbeacon_buf + pnew_beacon->ht_cap_offset);
+            }
+
+            if (pnew_beacon->pht_info) {
+                pnew_beacon->pht_info = (IEEEtypes_HTInfo_t *)
+                    (pnew_beacon->pbeacon_buf + pnew_beacon->ht_info_offset);
+            }
+            if (pnew_beacon->pbss_co_2040) {
+                pnew_beacon->pbss_co_2040 = (IEEEtypes_2040BSSCo_t *)
+                    (pnew_beacon->pbeacon_buf +
+                     pnew_beacon->bss_co_2040_offset);
+            }
+            if (pnew_beacon->pext_cap) {
+                pnew_beacon->pext_cap = (IEEEtypes_ExtCap_t *)
+                    (pnew_beacon->pbeacon_buf + pnew_beacon->ext_cap_offset);
+            }
+            if (pnew_beacon->poverlap_bss_scan_param) {
+                pnew_beacon->poverlap_bss_scan_param =
+                    (IEEEtypes_OverlapBSSScanParam_t *)
+                    (pnew_beacon->pbeacon_buf +
+                     pnew_beacon->overlap_bss_offset);
+            }
+
+            /* Increment the end pointer by the size reserved */
+            pmadapter->pbcn_buf_end += pnew_beacon->beacon_buf_size_max;
+
+            PRINTM(MINFO, "AppControl: Beacon[%02d] sz=%03d,"
+                   " used = %04d, left = %04d\n",
+                   beacon_idx,
+                   pnew_beacon->beacon_buf_size,
+                   (pmadapter->pbcn_buf_end - pmadapter->bcn_buf),
+                   (sizeof(pmadapter->bcn_buf) -
+                    (pmadapter->pbcn_buf_end - pmadapter->bcn_buf)));
+        } else {
+            /* 
+             * No space for new beacon
+             */
+            PRINTM(MINFO, "AppControl: No space beacon (%d): "
+                   "%02x:%02x:%02x:%02x:%02x:%02x; sz=%03d, left=%03d\n",
+                   beacon_idx,
+                   pnew_beacon->mac_address[0], pnew_beacon->mac_address[1],
+                   pnew_beacon->mac_address[2], pnew_beacon->mac_address[3],
+                   pnew_beacon->mac_address[4], pnew_beacon->mac_address[5],
+                   pnew_beacon->beacon_buf_size,
+                   (sizeof(pmadapter->bcn_buf) -
+                    (pmadapter->pbcn_buf_end - pmadapter->bcn_buf)));
+
+            /* Storage failure; clear storage records for this bcn */
+            pnew_beacon->pbeacon_buf = MNULL;
+            pnew_beacon->beacon_buf_size = 0;
+            pnew_beacon->beacon_buf_size_max = 0;
+            pnew_beacon->pwpa_ie = MNULL;
+            pnew_beacon->wpa_offset = 0;
+            pnew_beacon->prsn_ie = MNULL;
+            pnew_beacon->rsn_offset = 0;
+            pnew_beacon->pwapi_ie = MNULL;
+            pnew_beacon->wapi_offset = 0;
+            pnew_beacon->pht_cap = MNULL;
+            pnew_beacon->ht_cap_offset = 0;
+            pnew_beacon->pht_info = MNULL;
+            pnew_beacon->ht_info_offset = 0;
+            pnew_beacon->pbss_co_2040 = MNULL;
+            pnew_beacon->bss_co_2040_offset = 0;
+            pnew_beacon->pext_cap = MNULL;
+            pnew_beacon->ext_cap_offset = 0;
+            pnew_beacon->poverlap_bss_scan_param = MNULL;
+            pnew_beacon->overlap_bss_offset = 0;
+        }
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Post process the scan table after a new scan command has completed
+ *
+ *  Inspect each entry of the scan table and try to find an entry that
+ *    matches our current associated/joined network from the scan.  If
+ *    one is found, update the stored copy of the BSSDescriptor for our
+ *    current network.
+ *
+ *  Debug dump the current scan table contents if compiled accordingly.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *
+ *  @return             n/a
+ */
+static t_void
+wlan_scan_process_results(IN mlan_private * pmpriv)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    t_s32 j;
+    t_u32 i;
+
+    ENTER();
+
+    if (pmpriv->media_connected == MTRUE) {
+
+        j = wlan_find_ssid_in_list(pmpriv,
+                                   &pmpriv->curr_bss_params.bss_descriptor.ssid,
+                                   pmpriv->curr_bss_params.bss_descriptor.
+                                   mac_address, pmpriv->bss_mode);
+
+        if (j >= 0) {
+            pmadapter->callbacks.moal_spin_lock(pmpriv->curr_bcn_buf_lock);
+            pmpriv->curr_bss_params.bss_descriptor.pwpa_ie = MNULL;
+            pmpriv->curr_bss_params.bss_descriptor.wpa_offset = 0;
+            pmpriv->curr_bss_params.bss_descriptor.prsn_ie = MNULL;
+            pmpriv->curr_bss_params.bss_descriptor.rsn_offset = 0;
+            pmpriv->curr_bss_params.bss_descriptor.pwapi_ie = MNULL;
+            pmpriv->curr_bss_params.bss_descriptor.wapi_offset = 0;
+            pmpriv->curr_bss_params.bss_descriptor.pht_cap = MNULL;
+            pmpriv->curr_bss_params.bss_descriptor.ht_cap_offset = 0;
+            pmpriv->curr_bss_params.bss_descriptor.pht_info = MNULL;
+            pmpriv->curr_bss_params.bss_descriptor.ht_info_offset = 0;
+            pmpriv->curr_bss_params.bss_descriptor.pbss_co_2040 = MNULL;
+            pmpriv->curr_bss_params.bss_descriptor.bss_co_2040_offset = 0;
+            pmpriv->curr_bss_params.bss_descriptor.pext_cap = MNULL;
+            pmpriv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
+            pmpriv->curr_bss_params.bss_descriptor.poverlap_bss_scan_param =
+                MNULL;
+            pmpriv->curr_bss_params.bss_descriptor.overlap_bss_offset = 0;
+            pmpriv->curr_bss_params.bss_descriptor.pbeacon_buf = MNULL;
+            pmpriv->curr_bss_params.bss_descriptor.beacon_buf_size = 0;
+            pmpriv->curr_bss_params.bss_descriptor.beacon_buf_size_max = 0;
+
+            PRINTM(MINFO, "Found current ssid/bssid in list @ index #%d\n", j);
+            /* Make a copy of current BSSID descriptor */
+            memcpy(&pmpriv->curr_bss_params.bss_descriptor,
+                   &pmadapter->pscan_table[j],
+                   sizeof(pmpriv->curr_bss_params.bss_descriptor));
+
+            wlan_save_curr_bcn(pmpriv);
+            pmadapter->callbacks.moal_spin_unlock(pmpriv->curr_bcn_buf_lock);
+        } else {
+            wlan_restore_curr_bcn(pmpriv);
+        }
+    }
+
+    for (i = 0; i < pmadapter->num_in_scan_table; i++)
+        PRINTM(MINFO, "Scan:(%02d) %02x:%02x:%02x:%02x:%02x:%02x, "
+               "RSSI[%03d], SSID[%s]\n",
+               i,
+               pmadapter->pscan_table[i].mac_address[0],
+               pmadapter->pscan_table[i].mac_address[1],
+               pmadapter->pscan_table[i].mac_address[2],
+               pmadapter->pscan_table[i].mac_address[3],
+               pmadapter->pscan_table[i].mac_address[4],
+               pmadapter->pscan_table[i].mac_address[5],
+               (t_s32) pmadapter->pscan_table[i].rssi,
+               pmadapter->pscan_table[i].ssid.ssid);
+
+    /* 
+     * Prepares domain info from scan table and downloads the 
+     *   domain info command to the FW.
+     */
+    wlan_11d_prepare_dnld_domain_info_cmd(pmpriv);
+
+    LEAVE();
+}
+
+/**
+ *  @brief Convert radio type scan parameter to a band config used in join cmd
+ *
+ *  @param radio_type Scan parameter indicating the radio used for a channel
+ *                    in a scan command.
+ *
+ *  @return          Band type conversion of scanBand used in join/assoc cmds
+ *
+ */
+static t_u8
+radio_type_to_band(t_u8 radio_type)
+{
+    t_u8 ret_band;
+
+    switch (radio_type) {
+    case HostCmd_SCAN_RADIO_TYPE_A:
+        ret_band = BAND_A;
+        break;
+    case HostCmd_SCAN_RADIO_TYPE_BG:
+    default:
+        ret_band = BAND_G;
+        break;
+    }
+
+    return ret_band;
+}
+
+/**
+ *  @brief Delete a specific indexed entry from the scan table.
+ *
+ *  Delete the scan table entry indexed by table_idx.  Compact the remaining
+ *    entries and adjust any buffering of beacon/probe response data
+ *    if needed.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param table_idx    Scan table entry index to delete from the table
+ *
+ *  @return             N/A
+ *
+ *  @pre                table_idx must be an index to a valid entry
+ */
+static t_void
+wlan_scan_delete_table_entry(IN mlan_private * pmpriv, IN t_s32 table_idx)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    t_u32 del_idx;
+    t_u32 beacon_buf_adj;
+    t_u8 *pbeacon_buf;
+
+    ENTER();
+
+    /* 
+     * Shift the saved beacon buffer data for the scan table back over the
+     *   entry being removed.  Update the end of buffer pointer.  Save the 
+     *   deleted buffer allocation size for pointer adjustments for entries
+     *   compacted after the deleted index.
+     */
+    beacon_buf_adj = pmadapter->pscan_table[table_idx].beacon_buf_size_max;
+
+    PRINTM(MINFO, "Scan: Delete Entry %d, beacon buffer removal = %d bytes\n",
+           table_idx, beacon_buf_adj);
+
+    /* Check if the table entry had storage allocated for its beacon */
+    if (beacon_buf_adj) {
+        pbeacon_buf = pmadapter->pscan_table[table_idx].pbeacon_buf;
+
+        /* 
+         * Remove the entry's buffer space, decrement the table end pointer
+         *   by the amount we are removing 
+         */
+        pmadapter->pbcn_buf_end -= beacon_buf_adj;
+
+        PRINTM(MINFO,
+               "Scan: Delete Entry %d, compact data: %p <- %p (sz = %d)\n",
+               table_idx,
+               pbeacon_buf,
+               pbeacon_buf + beacon_buf_adj,
+               pmadapter->pbcn_buf_end - pbeacon_buf);
+
+        /* 
+         * Compact data storage.  Copy all data after the deleted entry's
+         *   end address (pbeacon_buf + beacon_buf_adj) back to the original
+         *   start address (pbeacon_buf).
+         *
+         * Scan table entries affected by the move will have their entry
+         *   pointer adjusted below.
+         *
+         * Use memmove since the dest/src memory regions overlap.
+         */
+        memmove(pbeacon_buf,
+                pbeacon_buf + beacon_buf_adj,
+                pmadapter->pbcn_buf_end - pbeacon_buf);
+    }
+
+    PRINTM(MINFO, "Scan: Delete Entry %d, num_in_scan_table = %d\n",
+           table_idx, pmadapter->num_in_scan_table);
+
+    /* Shift all of the entries after the table_idx back by one, compacting the 
+       table and removing the requested entry */
+    for (del_idx = table_idx; (del_idx + 1) < pmadapter->num_in_scan_table;
+         del_idx++) {
+        /* Copy the next entry over this one */
+        memcpy(pmadapter->pscan_table + del_idx,
+               pmadapter->pscan_table + del_idx + 1, sizeof(BSSDescriptor_t));
+
+        /* 
+         * Adjust this entry's pointer to its beacon buffer based on the 
+         *   removed/compacted entry from the deleted index.  Don't decrement
+         *   if the buffer pointer is MNULL (no data stored for this entry).
+         */
+        if (pmadapter->pscan_table[del_idx].pbeacon_buf) {
+            pmadapter->pscan_table[del_idx].pbeacon_buf -= beacon_buf_adj;
+            if (pmadapter->pscan_table[del_idx].pwpa_ie) {
+                pmadapter->pscan_table[del_idx].pwpa_ie =
+                    (IEEEtypes_VendorSpecific_t *)
+                    (pmadapter->pscan_table[del_idx].pbeacon_buf +
+                     pmadapter->pscan_table[del_idx].wpa_offset);
+            }
+            if (pmadapter->pscan_table[del_idx].prsn_ie) {
+                pmadapter->pscan_table[del_idx].prsn_ie =
+                    (IEEEtypes_Generic_t *)
+                    (pmadapter->pscan_table[del_idx].pbeacon_buf +
+                     pmadapter->pscan_table[del_idx].rsn_offset);
+            }
+            if (pmadapter->pscan_table[del_idx].pwapi_ie) {
+                pmadapter->pscan_table[del_idx].pwapi_ie =
+                    (IEEEtypes_Generic_t *)
+                    (pmadapter->pscan_table[del_idx].pbeacon_buf +
+                     pmadapter->pscan_table[del_idx].wapi_offset);
+            }
+            if (pmadapter->pscan_table[del_idx].pht_cap) {
+                pmadapter->pscan_table[del_idx].pht_cap =
+                    (IEEEtypes_HTCap_t *) (pmadapter->pscan_table[del_idx].
+                                           pbeacon_buf +
+                                           pmadapter->pscan_table[del_idx].
+                                           ht_cap_offset);
+            }
+
+            if (pmadapter->pscan_table[del_idx].pht_info) {
+                pmadapter->pscan_table[del_idx].pht_info =
+                    (IEEEtypes_HTInfo_t *) (pmadapter->pscan_table[del_idx].
+                                            pbeacon_buf +
+                                            pmadapter->pscan_table[del_idx].
+                                            ht_info_offset);
+            }
+            if (pmadapter->pscan_table[del_idx].pbss_co_2040) {
+                pmadapter->pscan_table[del_idx].pbss_co_2040 =
+                    (IEEEtypes_2040BSSCo_t *) (pmadapter->pscan_table[del_idx].
+                                               pbeacon_buf +
+                                               pmadapter->pscan_table[del_idx].
+                                               bss_co_2040_offset);
+            }
+            if (pmadapter->pscan_table[del_idx].pext_cap) {
+                pmadapter->pscan_table[del_idx].pext_cap =
+                    (IEEEtypes_ExtCap_t *) (pmadapter->pscan_table[del_idx].
+                                            pbeacon_buf +
+                                            pmadapter->pscan_table[del_idx].
+                                            ext_cap_offset);
+            }
+            if (pmadapter->pscan_table[del_idx].poverlap_bss_scan_param) {
+                pmadapter->pscan_table[del_idx].poverlap_bss_scan_param =
+                    (IEEEtypes_OverlapBSSScanParam_t *) (pmadapter->
+                                                         pscan_table[del_idx].
+                                                         pbeacon_buf +
+                                                         pmadapter->
+                                                         pscan_table[del_idx].
+                                                         overlap_bss_offset);
+            }
+
+        }
+    }
+
+    /* The last entry is invalid now that it has been deleted or moved back */
+    memset(pmadapter->pscan_table + pmadapter->num_in_scan_table - 1,
+           0x00, sizeof(BSSDescriptor_t));
+
+    pmadapter->num_in_scan_table--;
+
+    LEAVE();
+}
+
+/**
+ *  @brief Delete all occurrences of a given SSID from the scan table
+ *
+ *  Iterate through the scan table and delete all entries that match a given
+ *    SSID.  Compact the remaining scan table entries.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pdel_ssid    Pointer to an SSID to be used in deleting all
+ *                        matching SSIDs from the scan table
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_scan_delete_ssid_table_entry(IN mlan_private * pmpriv,
+                                  IN mlan_802_11_ssid * pdel_ssid)
+{
+    mlan_status ret = MLAN_STATUS_FAILURE;
+    t_s32 table_idx;
+
+    ENTER();
+
+    PRINTM(MINFO, "Scan: Delete Ssid Entry: %-32s\n", pdel_ssid->ssid);
+
+    /* If the requested SSID is found in the table, delete it.  Then keep
+       searching the table for multiple entires for the SSID until no more are
+       found */
+    while ((table_idx = wlan_find_ssid_in_list(pmpriv,
+                                               pdel_ssid,
+                                               MNULL,
+                                               MLAN_BSS_MODE_AUTO)) >= 0) {
+        PRINTM(MINFO, "Scan: Delete SSID Entry: Found Idx = %d\n", table_idx);
+        ret = MLAN_STATUS_SUCCESS;
+        wlan_scan_delete_table_entry(pmpriv, table_idx);
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/********************************************************
+                Global Functions
+********************************************************/
+
+/**
+ *  @brief Internal function used to start a scan based on an input config
+ *
+ *  Use the input user scan configuration information when provided in
+ *    order to send the appropriate scan commands to firmware to populate or
+ *    update the internal driver scan table
+ *
+ *  @param pmpriv           A pointer to mlan_private structure
+ *  @param pioctl_buf       A pointer to MLAN IOCTl Request buffer
+ *  @param puser_scan_in    Pointer to the input configuration for the requested
+ *                          scan.
+ *
+ *  @return              MLAN_STATUS_SUCCESS or < 0 if error
+ */
+mlan_status
+wlan_scan_networks(IN mlan_private * pmpriv,
+                   IN t_void * pioctl_buf,
+                   IN const wlan_user_scan_cfg * puser_scan_in)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmadapter->callbacks;
+    cmd_ctrl_node *pcmd_node = MNULL;
+
+    wlan_scan_cmd_config_tlv *pscan_cfg_out = MNULL;
+    MrvlIEtypes_ChanListParamSet_t *pchan_list_out;
+    t_u32 buf_size;
+    ChanScanParamSet_t *pscan_chan_list;
+
+    t_u8 keep_previous_scan;
+    t_u8 filtered_scan;
+    t_u8 scan_current_chan_only;
+    t_u8 max_chan_per_scan;
+
+    ENTER();
+
+    ret = pcb->moal_malloc(sizeof(wlan_scan_cmd_config_tlv),
+                           (t_u8 **) & pscan_cfg_out);
+    if (ret != MLAN_STATUS_SUCCESS || !pscan_cfg_out) {
+        PRINTM(MERROR, "Memory allocation for pscan_cfg_out failed!\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    buf_size = sizeof(ChanScanParamSet_t) * WLAN_USER_SCAN_CHAN_MAX;
+    ret = pcb->moal_malloc(buf_size, (t_u8 **) & pscan_chan_list);
+    if (ret != MLAN_STATUS_SUCCESS || !pscan_chan_list) {
+        PRINTM(MERROR, "Failed to allocate scan_chan_list\n");
+        if (pscan_cfg_out)
+            pcb->moal_mfree((t_u8 *) pscan_cfg_out);
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    memset(pscan_chan_list, 0x00, buf_size);
+    memset(pscan_cfg_out, 0x00, sizeof(wlan_scan_cmd_config_tlv));
+
+    keep_previous_scan = MFALSE;
+
+    wlan_scan_setup_scan_config(pmpriv,
+                                puser_scan_in,
+                                &pscan_cfg_out->config,
+                                &pchan_list_out,
+                                pscan_chan_list,
+                                &max_chan_per_scan,
+                                &filtered_scan, &scan_current_chan_only);
+
+    if (puser_scan_in) {
+        keep_previous_scan = puser_scan_in->keep_previous_scan;
+    }
+
+    if (keep_previous_scan == MFALSE) {
+        memset(pmadapter->pscan_table, 0x00,
+               sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST);
+        pmadapter->num_in_scan_table = 0;
+        pmadapter->pbcn_buf_end = pmadapter->bcn_buf;
+    }
+
+    ret = wlan_scan_channel_list(pmpriv,
+                                 pioctl_buf,
+                                 max_chan_per_scan,
+                                 filtered_scan,
+                                 &pscan_cfg_out->config,
+                                 pchan_list_out, pscan_chan_list);
+
+    /* Get scan command from scan_pending_q and put to cmd_pending_q */
+    if (ret == MLAN_STATUS_SUCCESS) {
+        if (util_peek_list
+            (&pmadapter->scan_pending_q, pcb->moal_spin_lock,
+             pcb->moal_spin_unlock)) {
+            pcmd_node =
+                (cmd_ctrl_node *) util_dequeue_list(&pmadapter->scan_pending_q,
+                                                    pcb->moal_spin_lock,
+                                                    pcb->moal_spin_unlock);
+            wlan_request_cmd_lock(pmadapter);
+            pmadapter->scan_processing = MTRUE;
+            wlan_release_cmd_lock(pmadapter);
+            wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node, MTRUE);
+        }
+    }
+    if (pscan_cfg_out)
+        pcb->moal_mfree((t_u8 *) pscan_cfg_out);
+
+    if (pscan_chan_list)
+        pcb->moal_mfree((t_u8 *) pscan_chan_list);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Prepare a scan command to be sent to the firmware
+ *
+ *  Use the wlan_scan_cmd_config sent to the command processing module in
+ *   the wlan_prepare_cmd to configure a HostCmd_DS_802_11_SCAN command
+ *   struct to send to firmware.
+ *
+ *  The fixed fields specifying the BSS type and BSSID filters as well as a
+ *   variable number/length of TLVs are sent in the command to firmware.
+ *
+ *  @param pmpriv     A pointer to mlan_private structure
+ *  @param pcmd       A pointer to HostCmd_DS_COMMAND structure to be sent to
+ *                    firmware with the HostCmd_DS_801_11_SCAN structure
+ *  @param pdata_buf  Void pointer cast of a wlan_scan_cmd_config struct used
+ *                    to set the fields/TLVs for the command sent to firmware
+ *
+ *  @return           MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_802_11_scan(IN mlan_private * pmpriv,
+                     IN HostCmd_DS_COMMAND * pcmd, IN t_void * pdata_buf)
+{
+    HostCmd_DS_802_11_SCAN *pscan_cmd = &pcmd->params.scan;
+    wlan_scan_cmd_config *pscan_cfg;
+
+    ENTER();
+
+    pscan_cfg = (wlan_scan_cmd_config *) pdata_buf;
+
+    /* Set fixed field variables in scan command */
+    pscan_cmd->bss_mode = pscan_cfg->bss_mode;
+    memcpy(pscan_cmd->bssid, pscan_cfg->specific_bssid,
+           sizeof(pscan_cmd->bssid));
+    memcpy(pscan_cmd->tlv_buffer, pscan_cfg->tlv_buf, pscan_cfg->tlv_buf_len);
+
+    pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SCAN);
+
+    /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
+    pcmd->size = (t_u16) wlan_cpu_to_le16((t_u16) (sizeof(pscan_cmd->bss_mode)
+                                                   + sizeof(pscan_cmd->bssid)
+                                                   + pscan_cfg->tlv_buf_len
+                                                   + S_DS_GEN));
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles the command response of scan
+ *
+ *   The response buffer for the scan command has the following
+ *      memory layout:
+ *
+ *     .-------------------------------------------------------------.
+ *     |  Header (4 * sizeof(t_u16)):  Standard command response hdr |
+ *     .-------------------------------------------------------------.
+ *     |  BufSize (t_u16) : sizeof the BSS Description data          |
+ *     .-------------------------------------------------------------.
+ *     |  NumOfSet (t_u8) : Number of BSS Descs returned             |
+ *     .-------------------------------------------------------------.
+ *     |  BSSDescription data (variable, size given in BufSize)      |
+ *     .-------------------------------------------------------------.
+ *     |  TLV data (variable, size calculated using Header->Size,    |
+ *     |            BufSize and sizeof the fixed fields above)       |
+ *     .-------------------------------------------------------------.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_ret_802_11_scan(IN mlan_private * pmpriv,
+                     IN HostCmd_DS_COMMAND * resp, IN t_void * pioctl_buf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_callbacks *pcb = MNULL;
+    mlan_ioctl_req *pioctl_req = (mlan_ioctl_req *) pioctl_buf;
+    cmd_ctrl_node *pcmd_node = MNULL;
+    HostCmd_DS_802_11_SCAN_RSP *pscan_rsp = MNULL;
+    BSSDescriptor_t *bss_new_entry = MNULL;
+    MrvlIEtypes_Data_t *ptlv;
+    MrvlIEtypes_TsfTimestamp_t *ptsf_tlv;
+    t_u8 *pbss_info;
+    t_u32 scan_resp_size;
+    t_u32 bytes_left;
+    t_u32 num_in_table;
+    t_u32 bss_idx;
+    t_u32 idx;
+    t_u32 tlv_buf_size;
+    t_u64 tsf_val;
+    chan_freq_power_t *cfp;
+    MrvlIEtypes_ChanBandListParamSet_t *pchan_band_tlv;
+    ChanBandParamSet_t *pchan_band;
+    t_u8 band;
+    t_u8 is_bgscan_resp;
+
+    ENTER();
+    pcb = (pmlan_callbacks) & pmadapter->callbacks;
+
+    is_bgscan_resp = (resp->command == HostCmd_CMD_802_11_BG_SCAN_QUERY);
+    if (is_bgscan_resp) {
+        pscan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
+    } else {
+        pscan_rsp = &resp->params.scan_resp;
+    }
+
+    if (pscan_rsp->number_of_sets > MRVDRV_MAX_BSSID_LIST) {
+        PRINTM(MERROR, "SCAN_RESP: Invalid number of AP returned (%d)!!\n",
+               pscan_rsp->number_of_sets);
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    bytes_left = wlan_le16_to_cpu(pscan_rsp->bss_descript_size);
+    PRINTM(MINFO, "SCAN_RESP: bss_descript_size %d\n", bytes_left);
+
+    scan_resp_size = resp->size;
+
+    PRINTM(MINFO, "SCAN_RESP: returned %d APs before parsing\n",
+           pscan_rsp->number_of_sets);
+
+    num_in_table = pmadapter->num_in_scan_table;
+    pbss_info = pscan_rsp->bss_desc_and_tlv_buffer;
+
+    /* 
+     * The size of the TLV buffer is equal to the entire command response
+     *   size (scan_resp_size) minus the fixed fields (sizeof()'s), the
+     *   BSS Descriptions (bss_descript_size as bytesLef) and the command
+     *   response header (S_DS_GEN)
+     */
+    tlv_buf_size = scan_resp_size - (bytes_left
+                                     + sizeof(pscan_rsp->bss_descript_size)
+                                     + sizeof(pscan_rsp->number_of_sets)
+                                     + S_DS_GEN);
+
+    ptlv =
+        (MrvlIEtypes_Data_t *) (pscan_rsp->bss_desc_and_tlv_buffer +
+                                bytes_left);
+
+    /* Search the TLV buffer space in the scan response for any valid TLVs */
+    wlan_ret_802_11_scan_get_tlv_ptrs(pmadapter,
+                                      ptlv,
+                                      tlv_buf_size,
+                                      TLV_TYPE_TSFTIMESTAMP,
+                                      (MrvlIEtypes_Data_t **) & ptsf_tlv);
+
+    /* Search the TLV buffer space in the scan response for any valid TLVs */
+    wlan_ret_802_11_scan_get_tlv_ptrs(pmadapter,
+                                      ptlv,
+                                      tlv_buf_size,
+                                      TLV_TYPE_CHANNELBANDLIST,
+                                      (MrvlIEtypes_Data_t **) & pchan_band_tlv);
+
+    /* 
+     *  Process each scan response returned (pscan_rsp->number_of_sets).  Save
+     *    the information in the bss_new_entry and then insert into the
+     *    driver scan table either as an update to an existing entry
+     *    or as an addition at the end of the table
+     */
+    ret = pcb->moal_malloc(sizeof(BSSDescriptor_t), (t_u8 **) & bss_new_entry);
+
+    if (ret != MLAN_STATUS_SUCCESS || !bss_new_entry) {
+        PRINTM(MERROR, "Memory allocation for bss_new_entry failed!\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    for (idx = 0; idx < pscan_rsp->number_of_sets && bytes_left; idx++) {
+        /* Zero out the bss_new_entry we are about to store info in */
+        memset(bss_new_entry, 0x00, sizeof(BSSDescriptor_t));
+
+        /* Process the data fields and IEs returned for this BSS */
+        if ((wlan_interpret_bss_desc_with_ie(pmadapter,
+                                             bss_new_entry,
+                                             &pbss_info,
+                                             &bytes_left) ==
+             MLAN_STATUS_SUCCESS)
+            && CHECK_SSID_IS_VALID(bss_new_entry.ssid)) {
+
+            PRINTM(MINFO, "SCAN_RESP: BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
+                   bss_new_entry->mac_address[0], bss_new_entry->mac_address[1],
+                   bss_new_entry->mac_address[2], bss_new_entry->mac_address[3],
+                   bss_new_entry->mac_address[4],
+                   bss_new_entry->mac_address[5]);
+
+            /* 
+             * Search the scan table for the same bssid
+             */
+            for (bss_idx = 0; bss_idx < num_in_table; bss_idx++) {
+                if (!memcmp(bss_new_entry->mac_address,
+                            pmadapter->pscan_table[bss_idx].mac_address,
+                            sizeof(bss_new_entry->mac_address))) {
+                    /* 
+                     * If the SSID matches as well, it is a duplicate of
+                     *   this entry.  Keep the bss_idx set to this
+                     *   entry so we replace the old contents in the table
+                     */
+                    if ((bss_new_entry->ssid.ssid_len ==
+                         pmadapter->pscan_table[bss_idx].ssid.ssid_len)
+                        && (!memcmp(bss_new_entry->ssid.ssid,
+                                    pmadapter->pscan_table[bss_idx].ssid.ssid,
+                                    bss_new_entry->ssid.ssid_len))) {
+                        PRINTM(MINFO, "SCAN_RESP: Duplicate of index: %d\n",
+                               bss_idx);
+                        break;
+                    }
+                }
+            }
+            /* 
+             * If the bss_idx is equal to the number of entries in the table,
+             *   the new entry was not a duplicate; append it to the scan
+             *   table
+             */
+            if (bss_idx == num_in_table) {
+                /* Range check the bss_idx, keep it limited to the last entry */
+                if (bss_idx == MRVDRV_MAX_BSSID_LIST) {
+                    bss_idx--;
+                } else {
+                    num_in_table++;
+                }
+            }
+
+            /* 
+             * Save the beacon/probe response returned for later application
+             *   retrieval.  Duplicate beacon/probe responses are updated if
+             *   possible
+             */
+            wlan_ret_802_11_scan_store_beacon(pmpriv,
+                                              bss_idx,
+                                              num_in_table, bss_new_entry);
+            /* 
+             * If the TSF TLV was appended to the scan results, save
+             *   this entry's TSF value in the networkTSF field.  The
+             *   networkTSF is the firmware's TSF value at the time the
+             *   beacon or probe response was received.
+             */
+            if (ptsf_tlv) {
+                memcpy(&tsf_val, &ptsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
+                       sizeof(tsf_val));
+                tsf_val = wlan_le64_to_cpu(tsf_val);
+                memcpy(&bss_new_entry->network_tsf,
+                       &tsf_val, sizeof(bss_new_entry->network_tsf));
+            }
+            band = BAND_G;
+            if (pchan_band_tlv) {
+                pchan_band = &pchan_band_tlv->chan_band_param[idx];
+                band =
+                    radio_type_to_band(pchan_band->
+                                       radio_type & (MBIT(0) | MBIT(1)));
+            }
+
+            /* Save the band designation for this entry for use in join */
+            bss_new_entry->bss_band = band;
+            cfp =
+                wlan_find_cfp_by_band_and_channel(pmadapter,
+                                                  (t_u8) bss_new_entry->
+                                                  bss_band,
+                                                  (t_u16) bss_new_entry->
+                                                  channel);
+
+            if (cfp)
+                bss_new_entry->freq = cfp->freq;
+            else
+                bss_new_entry->freq = 0;
+
+            /* Copy the locally created bss_new_entry to the scan table */
+            memcpy(&pmadapter->pscan_table[bss_idx],
+                   bss_new_entry, sizeof(pmadapter->pscan_table[bss_idx]));
+
+        } else {
+
+            /* Error parsing/interpreting the scan response, skipped */
+            PRINTM(MERROR, "SCAN_RESP: "
+                   "wlan_interpret_bss_desc_with_ie returned ERROR\n");
+        }
+    }
+
+    PRINTM(MINFO, "SCAN_RESP: Scanned %2d APs, %d valid, %d total\n",
+           pscan_rsp->number_of_sets,
+           num_in_table - pmadapter->num_in_scan_table, num_in_table);
+
+    /* Update the total number of BSSIDs in the scan table */
+    pmadapter->num_in_scan_table = num_in_table;
+
+    if (!util_peek_list
+        (&pmadapter->scan_pending_q, pcb->moal_spin_lock,
+         pcb->moal_spin_unlock)) {
+        wlan_request_cmd_lock(pmadapter);
+        pmadapter->scan_processing = MFALSE;
+        wlan_release_cmd_lock(pmadapter);
+        /* 
+         * Process the resulting scan table:
+         *   - Remove any bad ssids
+         *   - Update our current BSS information from scan data
+         */
+        wlan_scan_process_results(pmpriv);
+
+        /* Need to indicate IOCTL complete */
+        if (pioctl_req != MNULL) {
+            pioctl_req->status_code = MLAN_ERROR_NO_ERROR;
+
+            /* Indicate ioctl complete */
+            pcb->moal_ioctl_complete(pmadapter->pmoal_handle,
+                                     (pmlan_ioctl_req) pioctl_buf,
+                                     MLAN_STATUS_SUCCESS);
+        }
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_SCAN_REPORT, MNULL);
+    } else {
+        /* Get scan command from scan_pending_q and put to cmd_pending_q */
+        pcmd_node =
+            (cmd_ctrl_node *) util_dequeue_list(&pmadapter->scan_pending_q,
+                                                pcb->moal_spin_lock,
+                                                pcb->moal_spin_unlock);
+
+        wlan_insert_cmd_to_pending_q(pmadapter, pcmd_node, MTRUE);
+    }
+
+  done:
+    if (bss_new_entry)
+        pcb->moal_mfree((t_u8 *) bss_new_entry);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function prepares command of bg_scan_query.
+ *
+ *  @param pmpriv     A pointer to mlan_private structure
+ *  @param pcmd       A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf  Void pointer cast of a wlan_scan_cmd_config struct used
+ *                    to set the fields/TLVs for the command sent to firmware
+ *
+ *  @return           MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_802_11_bg_scan_query(IN mlan_private * pmpriv,
+                              IN HostCmd_DS_COMMAND * pcmd,
+                              IN t_void * pdata_buf)
+{
+    HostCmd_DS_802_11_BG_SCAN_QUERY *bg_query = &pcmd->params.bg_scan_query;
+
+    ENTER();
+
+    pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_QUERY);
+    pcmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_BG_SCAN_QUERY) + S_DS_GEN);
+
+    bg_query->flush = 1;
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function finds ssid in ssid list.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param ssid         SSID to find in the list
+ *  @param bssid        BSSID to qualify the SSID selection (if provided)
+ *  @param mode         Network mode: Infrastructure or IBSS
+ *
+ *  @return             index in BSSID list or < 0 if error
+ */
+t_s32
+wlan_find_ssid_in_list(IN mlan_private * pmpriv,
+                       IN mlan_802_11_ssid * ssid,
+                       IN t_u8 * bssid, IN t_u32 mode)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    t_s32 net = -1, j;
+    t_u8 best_rssi = 0;
+    t_u32 i;
+
+    ENTER();
+    PRINTM(MINFO, "Num of Entries in Table = %d\n",
+           pmadapter->num_in_scan_table);
+
+    /* 
+     * Loop through the table until the maximum is reached or until a match
+     *   is found based on the bssid field comparison 
+     */
+    for (i = 0;
+         i < pmadapter->num_in_scan_table && (!bssid || (bssid && net < 0));
+         i++) {
+        if (!wlan_ssid_cmp(pmadapter, &pmadapter->pscan_table[i].ssid, ssid) &&
+            (!bssid
+             || !memcmp(pmadapter->pscan_table[i].mac_address, bssid,
+                        MLAN_MAC_ADDR_LENGTH))) {
+            switch (mode) {
+            case MLAN_BSS_MODE_INFRA:
+            case MLAN_BSS_MODE_IBSS:
+                j = wlan_is_network_compatible(pmpriv, i, mode);
+
+                if (j >= 0) {
+                    if (SCAN_RSSI(pmadapter->pscan_table[i].rssi) > best_rssi) {
+                        best_rssi = SCAN_RSSI(pmadapter->pscan_table[i].rssi);
+                        net = i;
+                    }
+                } else {
+                    if (net == -1) {
+                        net = j;
+                    }
+                }
+                break;
+            case MLAN_BSS_MODE_AUTO:
+            default:
+                /* 
+                 * Do not check compatibility if the mode requested is 
+                 *   Auto/Unknown.  Allows generic find to work without 
+                 *   verifying against the Adapter security settings
+                 */
+                if (SCAN_RSSI(pmadapter->pscan_table[i].rssi) > best_rssi) {
+                    best_rssi = SCAN_RSSI(pmadapter->pscan_table[i].rssi);
+                    net = i;
+                }
+                break;
+            }
+        }
+    }
+
+    if (net >= 0) {
+        if (!wlan_find_cfp_by_band_and_channel(pmadapter,
+                                               (t_u8) pmadapter->
+                                               pscan_table[net].bss_band,
+                                               (t_u16) pmadapter->
+                                               pscan_table[net].channel)) {
+            net = -1;
+        }
+    }
+
+    LEAVE();
+    return net;
+}
+
+/**
+ *  @brief This function finds a specific compatible BSSID in the scan list
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param bssid        BSSID to find in the scan list
+ *  @param mode         Network mode: Infrastructure or IBSS
+ *
+ *  @return             index in BSSID list or < 0 if error
+ */
+t_s32
+wlan_find_bssid_in_list(IN mlan_private * pmpriv,
+                        IN t_u8 * bssid, IN t_u32 mode)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    t_s32 net = -1;
+    t_u32 i;
+
+    ENTER();
+
+    if (!bssid) {
+        LEAVE();
+        return -1;
+    }
+
+    PRINTM(MINFO, "FindBSSID: Num of BSSIDs = %d\n",
+           pmadapter->num_in_scan_table);
+
+    /* 
+     * Look through the scan table for a compatible match. The ret return
+     *   variable will be equal to the index in the scan table (greater
+     *   than zero) if the network is compatible.  The loop will continue
+     *   past a matched bssid that is not compatible in case there is an
+     *   AP with multiple SSIDs assigned to the same BSSID
+     */
+    for (i = 0; net < 0 && i < pmadapter->num_in_scan_table; i++) {
+        if (!memcmp
+            (pmadapter->pscan_table[i].mac_address, bssid,
+             MLAN_MAC_ADDR_LENGTH)) {
+            switch (mode) {
+            case MLAN_BSS_MODE_INFRA:
+            case MLAN_BSS_MODE_IBSS:
+                net = wlan_is_network_compatible(pmpriv, i, mode);
+                break;
+            default:
+                net = i;
+                break;
+            }
+        }
+    }
+
+    if (net >= 0) {
+        if (!wlan_find_cfp_by_band_and_channel(pmadapter,
+                                               (t_u8) pmadapter->
+                                               pscan_table[net].bss_band,
+                                               (t_u16) pmadapter->
+                                               pscan_table[net].channel)) {
+            net = -1;
+        }
+    }
+
+    LEAVE();
+    return net;
+}
+
+/**
+ *  @brief Compare two SSIDs
+ *
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param ssid1     A pointer to ssid to compare
+ *  @param ssid2     A pointer to ssid to compare
+ *
+ *  @return         0--ssid is same, otherwise is different
+ */
+t_s32
+wlan_ssid_cmp(IN pmlan_adapter pmadapter,
+              IN mlan_802_11_ssid * ssid1, IN mlan_802_11_ssid * ssid2)
+{
+    ENTER();
+
+    if (!ssid1 || !ssid2) {
+        LEAVE();
+        return -1;
+    }
+
+    if (ssid1->ssid_len != ssid2->ssid_len) {
+        LEAVE();
+        return -1;
+    }
+
+    LEAVE();
+    return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
+}
+
+/** 
+ *  @brief This function inserts scan command node to scan_pending_q.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pcmd_node    A pointer to cmd_ctrl_node structure
+ *  @return             n/a
+ */
+t_void
+wlan_queue_scan_cmd(IN mlan_private * pmpriv, IN cmd_ctrl_node * pcmd_node)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+
+    ENTER();
+
+    if (pcmd_node == MNULL)
+        goto done;
+    util_enqueue_list_tail(&pmadapter->scan_pending_q,
+                           (pmlan_linked_list) pcmd_node,
+                           pmadapter->callbacks.moal_spin_lock,
+                           pmadapter->callbacks.moal_spin_unlock);
+
+  done:
+    LEAVE();
+}
+
+/**
+ *  @brief Find the AP with specific ssid in the scan list
+ *
+ *  @param pmpriv               A pointer to mlan_private structure
+ *  @param preq_ssid_bssid      A pointer to AP's ssid returned
+ *
+ *  @return                     MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+mlan_status
+wlan_find_best_network(IN mlan_private * pmpriv,
+                       OUT mlan_ssid_bssid * preq_ssid_bssid)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    BSSDescriptor_t *preq_bss;
+    t_s32 i;
+
+    ENTER();
+
+    memset(preq_ssid_bssid, 0, sizeof(mlan_ssid_bssid));
+
+    i = wlan_find_best_network_in_list(pmpriv);
+
+    if (i >= 0) {
+        preq_bss = &pmadapter->pscan_table[i];
+        memcpy(&preq_ssid_bssid->ssid, &preq_bss->ssid,
+               sizeof(mlan_802_11_ssid));
+        memcpy((t_u8 *) & preq_ssid_bssid->bssid,
+               (t_u8 *) & preq_bss->mac_address, MLAN_MAC_ADDR_LENGTH);
+
+        /* Make sure we are in the right mode */
+        if (pmpriv->bss_mode == MLAN_BSS_MODE_AUTO)
+            pmpriv->bss_mode = preq_bss->bss_mode;
+    }
+
+    if (!preq_ssid_bssid->ssid.ssid_len) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    PRINTM(MINFO, "Best network found = [%s], "
+           "[%02x:%02x:%02x:%02x:%02x:%02x]\n",
+           preq_ssid_bssid->ssid.ssid,
+           preq_ssid_bssid->bssid[0], preq_ssid_bssid->bssid[1],
+           preq_ssid_bssid->bssid[2], preq_ssid_bssid->bssid[3],
+           preq_ssid_bssid->bssid[4], preq_ssid_bssid->bssid[5]);
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Send a scan command for all available channels filtered on a spec
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pioctl_buf   A pointer to MLAN IOCTl Request buffer
+ *  @param preq_ssid    A pointer to AP's ssid returned
+ *
+ *  @return             MLAN_STATUS_SUCCESS--success, otherwise--fail
+ */
+mlan_status
+wlan_scan_specific_ssid(IN mlan_private * pmpriv,
+                        IN t_void * pioctl_buf, IN mlan_802_11_ssid * preq_ssid)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_callbacks *pcb = (mlan_callbacks *) & pmpriv->adapter->callbacks;
+    wlan_user_scan_cfg *pscan_cfg;
+
+    ENTER();
+
+    if (!preq_ssid) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    wlan_scan_delete_ssid_table_entry(pmpriv, preq_ssid);
+
+    ret = pcb->moal_malloc(sizeof(wlan_user_scan_cfg), (t_u8 **) & pscan_cfg);
+
+    if (ret != MLAN_STATUS_SUCCESS || !pscan_cfg) {
+        PRINTM(MERROR, "Memory allocation for pscan_cfg failed!\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    memset(pscan_cfg, 0x00, sizeof(wlan_user_scan_cfg));
+
+    memcpy(pscan_cfg->ssid_list[0].ssid, preq_ssid->ssid, preq_ssid->ssid_len);
+    pscan_cfg->keep_previous_scan = MTRUE;
+
+    ret = wlan_scan_networks(pmpriv, pioctl_buf, pscan_cfg);
+
+    if (pscan_cfg)
+        pcb->moal_mfree((t_u8 *) pscan_cfg);
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function append the vendor specific IE TLV
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param vsie_mask    VSIE bit mask
+ *  @param ppbuffer     A Pointer to command buffer pointer
+ *
+ *  @return bytes added to the buffer       
+ */
+int
+wlan_cmd_append_vsie_tlv(IN mlan_private * pmpriv,
+                         IN t_u16 vsie_mask, OUT t_u8 ** ppbuffer)
+{
+    int id, ret_len = 0;
+    MrvlIETypes_VendorParamSet_t *pvs_param_set;
+
+    ENTER();
+
+    /* Null Checks */
+    if (ppbuffer == 0) {
+        LEAVE();
+        return 0;
+    }
+    if (*ppbuffer == 0) {
+        LEAVE();
+        return 0;
+    }
+
+    /**
+     * Traverse through the saved vendor specific IE array and append
+     * the selected(scan/assoc/adhoc) IE as TLV to the command
+     */
+    for (id = 0; id < MLAN_MAX_VSIE_NUM; id++) {
+        if (pmpriv->vs_ie[id].mask & vsie_mask) {
+            pvs_param_set = (MrvlIETypes_VendorParamSet_t *) * ppbuffer;
+            pvs_param_set->header.type = wlan_cpu_to_le16(TLV_TYPE_PASSTHROUGH);
+            pvs_param_set->header.len =
+                (((t_u16) pmpriv->vs_ie[id].ie[1]) & 0x00FF) + 2;
+            memcpy(pvs_param_set->ie, pmpriv->vs_ie[id].ie,
+                   pvs_param_set->header.len);
+            HEXDUMP("VENDOR_SPEC_IE", (t_u8 *) pvs_param_set,
+                    sizeof(MrvlIEtypesHeader_t) + pvs_param_set->header.len);
+            *ppbuffer +=
+                pvs_param_set->header.len + sizeof(MrvlIEtypesHeader_t);
+            ret_len += pvs_param_set->header.len + sizeof(MrvlIEtypesHeader_t);
+            pvs_param_set->header.len =
+                wlan_cpu_to_le16(pvs_param_set->header.len);
+        }
+    }
+
+    LEAVE();
+    return ret_len;
+}
+
+/**
+ *  @brief Save a beacon buffer of the current bss descriptor
+ *  Save the current beacon buffer to restore in the following cases that 
+ *  makes the bcn_buf not to contain the current ssid's beacon buffer.
+ *    - the current ssid was not found somehow in the last scan. 
+ *    - the current ssid was the last entry of the scan table and overloaded. 
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *
+ *  @return             n/a
+ */
+t_void
+wlan_save_curr_bcn(IN mlan_private * pmpriv)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_callbacks *pcb = (pmlan_callbacks) & pmadapter->callbacks;
+    BSSDescriptor_t *pcurr_bss = &pmpriv->curr_bss_params.bss_descriptor;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    /* save the beacon buffer if it is not saved or updated */
+    if ((pmpriv->pcurr_bcn_buf == MNULL) ||
+        (pmpriv->curr_bcn_size != pcurr_bss->beacon_buf_size) ||
+        (memcmp(pmpriv->pcurr_bcn_buf, pcurr_bss->pbeacon_buf,
+                pcurr_bss->beacon_buf_size))) {
+
+        if (pmpriv->pcurr_bcn_buf) {
+            pcb->moal_mfree(pmpriv->pcurr_bcn_buf);
+            pmpriv->pcurr_bcn_buf = MNULL;
+        }
+
+        pmpriv->curr_bcn_size = pcurr_bss->beacon_buf_size;
+        ret = pcb->moal_malloc(pcurr_bss->beacon_buf_size,
+                               &pmpriv->pcurr_bcn_buf);
+
+        if ((ret == MLAN_STATUS_SUCCESS) && pmpriv->pcurr_bcn_buf) {
+            memcpy(pmpriv->pcurr_bcn_buf, pcurr_bss->pbeacon_buf,
+                   pcurr_bss->beacon_buf_size);
+            PRINTM(MINFO, "current beacon saved %d\n", pmpriv->curr_bcn_size);
+        }
+    }
+}
+
+/**
+ *  @brief Restore a beacon buffer of the current bss descriptor
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *
+ *  @return             n/a
+ */
+t_void
+wlan_restore_curr_bcn(IN mlan_private * pmpriv)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_callbacks *pcb = (pmlan_callbacks) & pmadapter->callbacks;
+    BSSDescriptor_t *pcurr_bss = &pmpriv->curr_bss_params.bss_descriptor;
+
+    if (pmpriv->pcurr_bcn_buf &&
+        ((pmadapter->pbcn_buf_end + pmpriv->curr_bcn_size) <
+         (pmadapter->bcn_buf + sizeof(pmadapter->bcn_buf)))) {
+
+        pcb->moal_spin_lock(pmpriv->curr_bcn_buf_lock);
+
+        /* restore the current beacon buffer */
+        memcpy(pmadapter->pbcn_buf_end, pmpriv->pcurr_bcn_buf,
+               pmpriv->curr_bcn_size);
+        pcurr_bss->pbeacon_buf = pmadapter->pbcn_buf_end;
+        pcurr_bss->beacon_buf_size = pmpriv->curr_bcn_size;
+        pmadapter->pbcn_buf_end += pmpriv->curr_bcn_size;
+
+        /* adjust the pointers in the current bss descriptor */
+        if (pcurr_bss->pwpa_ie) {
+            pcurr_bss->pwpa_ie = (IEEEtypes_VendorSpecific_t *)
+                (pcurr_bss->pbeacon_buf + pcurr_bss->wpa_offset);
+        }
+
+        if (pcurr_bss->prsn_ie) {
+            pcurr_bss->prsn_ie = (IEEEtypes_Generic_t *)
+                (pcurr_bss->pbeacon_buf + pcurr_bss->rsn_offset);
+        }
+
+        if (pcurr_bss->pht_cap) {
+            pcurr_bss->pht_cap = (IEEEtypes_HTCap_t *)
+                (pcurr_bss->pbeacon_buf + pcurr_bss->ht_cap_offset);
+        }
+
+        if (pcurr_bss->pht_info) {
+            pcurr_bss->pht_info = (IEEEtypes_HTInfo_t *)
+                (pcurr_bss->pbeacon_buf + pcurr_bss->ht_info_offset);
+        }
+
+        if (pcurr_bss->pbss_co_2040) {
+            pcurr_bss->pbss_co_2040 = (IEEEtypes_2040BSSCo_t *)
+                (pcurr_bss->pbeacon_buf + pcurr_bss->bss_co_2040_offset);
+        }
+
+        if (pcurr_bss->pext_cap) {
+            pcurr_bss->pext_cap = (IEEEtypes_ExtCap_t *)
+                (pcurr_bss->pbeacon_buf + pcurr_bss->ext_cap_offset);
+        }
+
+        if (pcurr_bss->poverlap_bss_scan_param) {
+            pcurr_bss->poverlap_bss_scan_param =
+                (IEEEtypes_OverlapBSSScanParam_t *)
+                (pcurr_bss->pbeacon_buf + pcurr_bss->overlap_bss_offset);
+        }
+
+        pcb->moal_spin_unlock(pmpriv->curr_bcn_buf_lock);
+
+        PRINTM(MINFO, "current beacon restored %d\n", pmpriv->curr_bcn_size);
+    } else {
+        PRINTM(MWARN, "curr_bcn_buf not saved or bcn_buf has no space\n");
+    }
+}
+
+/**
+ *  @brief Free a beacon buffer of the current bss descriptor
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *
+ *  @return             n/a
+ */
+t_void
+wlan_free_curr_bcn(IN mlan_private * pmpriv)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_callbacks *pcb = (pmlan_callbacks) & pmadapter->callbacks;
+
+    if (pmpriv->pcurr_bcn_buf) {
+        pcb->moal_mfree(pmpriv->pcurr_bcn_buf);
+        pmpriv->pcurr_bcn_buf = MNULL;
+    }
+}
diff --git a/wlan_src/mlan/mlan_sdio.c b/wlan_src/mlan/mlan_sdio.c
new file mode 100755
index 0000000..0de4d42
--- /dev/null
+++ b/wlan_src/mlan/mlan_sdio.c
@@ -0,0 +1,1420 @@
+/** @file mlan_sdio.c
+ *
+ *  @brief This file contains SDIO specific code
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    10/27/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_init.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+		Local Variables
+********************************************************/
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/********************************************************
+		Local Functions
+********************************************************/
+/** 
+ *  @brief This function initialize the SDIO port
+ *  
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *  @return 	   	  MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_sdio_init_ioport(mlan_adapter * pmadapter)
+{
+    t_u32 reg;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    pmadapter->ioport = 0;
+
+    /* Read the IO port */
+    if (MLAN_STATUS_SUCCESS ==
+        pcb->moal_read_reg(pmadapter->pmoal_handle, IO_PORT_0_REG, &reg))
+        pmadapter->ioport |= (reg & 0xff);
+    else
+        return MLAN_STATUS_FAILURE;
+
+    if (MLAN_STATUS_SUCCESS ==
+        pcb->moal_read_reg(pmadapter->pmoal_handle, IO_PORT_1_REG, &reg))
+        pmadapter->ioport |= ((reg & 0xff) << 8);
+    else
+        return MLAN_STATUS_FAILURE;
+
+    if (MLAN_STATUS_SUCCESS ==
+        pcb->moal_read_reg(pmadapter->pmoal_handle, IO_PORT_2_REG, &reg))
+        pmadapter->ioport |= ((reg & 0xff) << 16);
+    else
+        return MLAN_STATUS_FAILURE;
+
+    PRINTM(MINFO, "SDIO FUNC1 IO port: 0x%x\n", pmadapter->ioport);
+
+#define SDIO_INT_MASK       0x3F
+    /* Set Host interrupt reset to read to clear */
+    if (MLAN_STATUS_SUCCESS ==
+        pcb->moal_read_reg(pmadapter->pmoal_handle, HOST_INT_RSR_REG, &reg)) {
+        pcb->moal_write_reg(pmadapter->pmoal_handle, HOST_INT_RSR_REG,
+                            reg | SDIO_INT_MASK);
+    } else
+        return MLAN_STATUS_FAILURE;
+
+    /* Dnld/Upld ready set to auto reset */
+    if (MLAN_STATUS_SUCCESS ==
+        pcb->moal_read_reg(pmadapter->pmoal_handle, CARD_MISC_CFG_REG, &reg)) {
+        pcb->moal_write_reg(pmadapter->pmoal_handle, CARD_MISC_CFG_REG,
+                            reg | AUTO_RE_ENABLE_INT);
+    } else
+        return MLAN_STATUS_FAILURE;
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function gets available SDIO port for reading cmd/data
+ *  
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *  @param pport      A pointer to port number
+ *  @return 	   	  MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_get_rd_port(mlan_adapter * pmadapter, t_u8 * pport)
+{
+    t_u16 rd_bitmap = pmadapter->mp_rd_bitmap;
+
+    PRINTM(MDATA, "wlan_get_rd_port: mp_rd_bitmap=0x%04x\n", rd_bitmap);
+
+    if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
+        return MLAN_STATUS_FAILURE;
+
+    if (pmadapter->mp_rd_bitmap & CTRL_PORT_MASK) {
+        pmadapter->mp_rd_bitmap &= (t_u16) (~CTRL_PORT_MASK);
+        *pport = CTRL_PORT;
+        PRINTM(MDATA, "wlan_get_rd_port: port=%d mp_rd_bitmap=0x%04x\n", *pport,
+               pmadapter->mp_rd_bitmap);
+    } else {
+        if (pmadapter->mp_rd_bitmap & (1 << pmadapter->curr_rd_port)) {
+            pmadapter->mp_rd_bitmap &=
+                (t_u16) (~(1 << pmadapter->curr_rd_port));
+            *pport = pmadapter->curr_rd_port;
+
+            if (++pmadapter->curr_rd_port == MAX_PORT)
+                pmadapter->curr_rd_port = 1;
+        } else {
+            return MLAN_STATUS_FAILURE;
+        }
+
+        PRINTM(MDATA, "port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
+               *pport, rd_bitmap, pmadapter->mp_rd_bitmap);
+    }
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function gets available SDIO port for writing data
+ *  
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *  @param pport      A pointer to port number
+ *  @return 	   	  MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_get_wr_port_data(mlan_adapter * pmadapter, t_u8 * pport)
+{
+    t_u16 wr_bitmap = pmadapter->mp_wr_bitmap;
+
+    PRINTM(MDATA, "wlan_get_wr_port_data: mp_wr_bitmap=0x%04x\n", wr_bitmap);
+
+    if (!(wr_bitmap & pmadapter->mp_data_port_mask))
+        return MLAN_STATUS_FAILURE;
+
+    if (pmadapter->mp_wr_bitmap & (1 << pmadapter->curr_wr_port)) {
+        pmadapter->mp_wr_bitmap &= (t_u16) (~(1 << pmadapter->curr_wr_port));
+        *pport = pmadapter->curr_wr_port;
+        if (++pmadapter->curr_wr_port == pmadapter->mp_end_port)
+            pmadapter->curr_wr_port = 1;
+    } else {
+        pmadapter->data_sent = MTRUE;
+        return MLAN_STATUS_RESOURCE;
+    }
+
+    PRINTM(MDATA, "port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n",
+           *pport, wr_bitmap, pmadapter->mp_wr_bitmap);
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function polls the card status register.
+ *  
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *  @param bits    	  the bit mask
+ *  @return 	   	  MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_sdio_poll_card_status(mlan_adapter * pmadapter, t_u8 bits)
+{
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_u32 tries;
+    t_u32 cs = 0;
+
+    for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+        if (pcb->moal_read_reg(pmadapter->pmoal_handle, CARD_STATUS_REG, &cs) !=
+            MLAN_STATUS_SUCCESS)
+            break;
+        else if ((cs & bits) == bits)
+            return MLAN_STATUS_SUCCESS;
+        wlan_udelay(pmadapter, 10);
+    }
+
+    PRINTM(MWARN, "wlan_sdio_poll_card_status failed, tries = %d\n", tries);
+    return MLAN_STATUS_FAILURE;
+}
+
+/** 
+ *  @brief This function reads firmware status registers
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param dat	   A pointer to keep returned data
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_sdio_read_fw_status(mlan_adapter * pmadapter, t_u16 * dat)
+{
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_u32 fws0 = 0, fws1 = 0;
+
+    ENTER();
+    if (MLAN_STATUS_SUCCESS !=
+        pcb->moal_read_reg(pmadapter->pmoal_handle, CARD_FW_STATUS0_REG, &fws0))
+        return MLAN_STATUS_FAILURE;
+
+    if (MLAN_STATUS_SUCCESS !=
+        pcb->moal_read_reg(pmadapter->pmoal_handle, CARD_FW_STATUS1_REG, &fws1))
+        return MLAN_STATUS_FAILURE;
+
+    *dat = (fws1 << 8) | fws0;
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**  @brief This function disables the host interrupts mask.
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param mask	   the interrupt mask
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_sdio_disable_host_int_mask(pmlan_adapter pmadapter, t_u8 mask)
+{
+    t_u32 host_int_mask = 0;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    ENTER();
+
+    /* Read back the host_int_mask register */
+    if (MLAN_STATUS_SUCCESS !=
+        pcb->moal_read_reg(pmadapter->pmoal_handle, HOST_INT_MASK_REG,
+                           &host_int_mask)) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Update with the mask and write back to the register */
+    host_int_mask &= ~mask;
+
+    if (MLAN_STATUS_SUCCESS !=
+        pcb->moal_write_reg(pmadapter->pmoal_handle, HOST_INT_MASK_REG,
+                            host_int_mask)) {
+        PRINTM(MWARN, "Disable host interrupt failed\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function enables the host interrupts mask
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param mask	   the interrupt mask
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_sdio_enable_host_int_mask(pmlan_adapter pmadapter, t_u8 mask)
+{
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    ENTER();
+
+    /* Simply write the mask to the register */
+    if (MLAN_STATUS_SUCCESS !=
+        pcb->moal_write_reg(pmadapter->pmoal_handle, HOST_INT_MASK_REG, mask)) {
+        PRINTM(MWARN, "Enable host interrupt failed\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function reads data from the card.
+ *  
+ *  @param pmadapter 	A pointer to mlan_adapter structure
+ *  @param type	   	A pointer to keep type as data or command
+ *  @param nb		A pointer to keep the data/cmd length returned in buffer
+ *  @param pmbuf 	A pointer to the SDIO data/cmd buffer
+ *  @param npayload	the length of data/cmd buffer
+ *  @param ioport	the SDIO ioport
+ *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_sdio_card_to_host(mlan_adapter * pmadapter,
+                       t_u32 * type, t_u32 * nb, pmlan_buffer pmbuf,
+                       t_u32 npayload, t_u32 ioport)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    ENTER();
+
+    if (!pmbuf) {
+        PRINTM(MWARN, "pmbuf NULL pointer received!\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    ret = pcb->moal_read_data_sync(pmadapter->pmoal_handle, pmbuf, ioport, 0);
+
+    if (ret != MLAN_STATUS_SUCCESS) {
+        PRINTM(MERROR, "card_to_host, read iomem failed: %d\n", ret);
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+    *nb = wlan_le16_to_cpu(*(t_u16 *) (pmbuf->pbuf + pmbuf->data_offset));
+    if (*nb > npayload) {
+        PRINTM(MERROR, "invalid packet, *nb=%d, npayload=%d\n", *nb, npayload);
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    DBG_HEXDUMP(MDAT_D, "SDIO Blk Rd", pmbuf->pbuf,
+                MIN(npayload, MAX_DATA_DUMP_LEN));
+
+    *type = wlan_le16_to_cpu(*(t_u16 *) (pmbuf->pbuf + pmbuf->data_offset + 2));
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/********************************************************
+		Global functions
+********************************************************/
+
+/**
+ *  @brief  This function downloads FW blocks to device
+ *
+ *  @param pmadapter	A pointer to mlan_adapter
+ *  @param pmfw			A pointer to firmware image
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_prog_fw_w_helper(IN pmlan_adapter pmadapter, IN pmlan_fw_image pmfw)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_u8 *firmware = pmfw->pfw_buf;
+    t_u32 firmwarelen = pmfw->fw_len;
+    t_u32 offset = 0;
+    t_u32 base0, base1;
+    t_void *tmpfwbuf = MNULL;
+    t_u32 tmpfwbufsz;
+    t_u8 *fwbuf;
+    mlan_buffer mbuf;
+    t_u16 len = 0;
+    t_u32 txlen = 0, tx_blocks = 0, tries = 0;
+    t_u32 i = 0;
+
+    ENTER();
+
+    if (!firmwarelen) {
+        PRINTM(MMSG, "No firmware image found! Terminating download\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    PRINTM(MINFO, "Downloading FW image (%d bytes)\n", firmwarelen);
+
+    tmpfwbufsz = ALIGN_SZ(WLAN_UPLD_SIZE, HEADER_ALIGNMENT);
+    ret = pcb->moal_malloc(tmpfwbufsz, (t_u8 **) & tmpfwbuf);
+    if ((ret != MLAN_STATUS_SUCCESS) || !tmpfwbuf) {
+        PRINTM(MERROR,
+               "Unable to allocate buffer for firmware. Terminating download\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    memset(tmpfwbuf, 0, tmpfwbufsz);
+    /* Ensure 8-byte aligned firmware buffer */
+    fwbuf = (t_u8 *) ALIGN_ADDR(tmpfwbuf, HEADER_ALIGNMENT);
+
+    /* Perform firmware data transfer */
+    do {
+        /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */
+        ret =
+            wlan_sdio_poll_card_status(pmadapter,
+                                       CARD_IO_READY | DN_LD_CARD_RDY);
+        if (ret != MLAN_STATUS_SUCCESS) {
+            PRINTM(MFATAL, "FW download with helper poll status timeout @ %d\n",
+                   offset);
+            goto done;
+        }
+
+        /* More data? */
+        if (offset >= firmwarelen)
+            break;
+
+        for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+            if ((ret = pcb->moal_read_reg(pmadapter->pmoal_handle,
+                                          HOST_F1_RD_BASE_0,
+                                          &base0)) != MLAN_STATUS_SUCCESS) {
+                PRINTM(MWARN,
+                       "Dev BASE0 register read failed:"
+                       " base0=0x%04X(%d). Terminating download\n", base0,
+                       base0);
+                goto done;
+            }
+            if ((ret = pcb->moal_read_reg(pmadapter->pmoal_handle,
+                                          HOST_F1_RD_BASE_1,
+                                          &base1)) != MLAN_STATUS_SUCCESS) {
+                PRINTM(MWARN,
+                       "Dev BASE1 register read failed:"
+                       " base1=0x%04X(%d). Terminating download\n", base1,
+                       base1);
+                goto done;
+            }
+            len = ((base1 & 0xff) << 8) | (base0 & 0xff);
+
+            if (len)
+                break;
+            wlan_udelay(pmadapter, 10);
+        }
+
+        if (!len)
+            break;
+        else if (len > WLAN_UPLD_SIZE) {
+            PRINTM(MFATAL, "FW download failure @ %d, invalid length %d\n",
+                   offset, len);
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+
+        txlen = len;
+
+        if (len & MBIT(0)) {
+            i++;
+            if (i > MAX_WRITE_IOMEM_RETRY) {
+                PRINTM(MFATAL,
+                       "FW download failure @ %d, over max retry count\n",
+                       offset);
+                ret = MLAN_STATUS_FAILURE;
+                goto done;
+            }
+            PRINTM(MERROR, "FW CRC error indicated by the helper:"
+                   " len = 0x%04X, txlen = %d\n", len, txlen);
+            len &= ~MBIT(0);
+            /* Setting this to 0 to resend from same offset */
+            txlen = 0;
+        } else {
+            i = 0;
+
+            /* Set blocksize to transfer - checking for last block */
+            if (firmwarelen - offset < txlen) {
+                txlen = firmwarelen - offset;
+            }
+            PRINTM(MINFO, ".");
+
+            tx_blocks =
+                (txlen + MLAN_SDIO_BLOCK_SIZE_FW_DNLD -
+                 1) / MLAN_SDIO_BLOCK_SIZE_FW_DNLD;
+
+            /* Copy payload to buffer */
+            memmove(fwbuf, &firmware[offset], txlen);
+        }
+
+        /* Send data */
+        memset(&mbuf, 0, sizeof(mlan_buffer));
+        mbuf.pbuf = (t_u8 *) fwbuf;
+        mbuf.data_len = tx_blocks * MLAN_SDIO_BLOCK_SIZE_FW_DNLD;
+
+        ret =
+            pcb->moal_write_data_sync(pmadapter->pmoal_handle, &mbuf,
+                                      pmadapter->ioport, 0);
+        if (ret != MLAN_STATUS_SUCCESS) {
+            PRINTM(MERROR, "FW download, write iomem (%d) failed @ %d\n", i,
+                   offset);
+            if (pcb->
+                moal_write_reg(pmadapter->pmoal_handle, CONFIGURATION_REG,
+                               0x04) != MLAN_STATUS_SUCCESS) {
+                PRINTM(MERROR, "write CFG reg failed\n");
+            }
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+
+        offset += txlen;
+    } while (MTRUE);
+
+    PRINTM(MINFO, "\nFW download over, size %d bytes\n", offset);
+
+    ret = MLAN_STATUS_SUCCESS;
+  done:
+    if (tmpfwbuf)
+        pcb->moal_mfree((t_u8 *) tmpfwbuf);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function checks if the interface is ready to download
+ *  or not while other download interface is present
+ *  
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *  @return           MLAN_STATUS_SUCCESS if the calling interface
+ *          	      is the winner, otherwise MLAN_STATUS_FAILURE
+ * 
+ */
+mlan_status
+wlan_check_winner_status(mlan_adapter * pmadapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u32 winner_status;
+    pmlan_callbacks pcb;
+
+    ENTER();
+
+    pcb = &pmadapter->callbacks;
+    winner_status = 0;
+
+    if (MLAN_STATUS_SUCCESS !=
+        pcb->moal_read_reg(pmadapter->pmoal_handle, CARD_FW_STATUS0_REG,
+                           &winner_status))
+        return MLAN_STATUS_FAILURE;
+
+    if (winner_status != 0)
+        ret = MLAN_STATUS_FAILURE;
+    else
+        ret = MLAN_STATUS_SUCCESS;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function checks if the firmware is ready to accept
+ *  command or not.
+ *  
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *  @param pollnum    Maximum polling number
+ *  @return           MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_check_fw_status(mlan_adapter * pmadapter, t_u32 pollnum)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 firmwarestat;
+    t_u32 tries;
+
+    ENTER();
+
+    /* Wait for firmware initialization event */
+    for (tries = 0; tries < pollnum; tries++) {
+        if (MLAN_STATUS_SUCCESS !=
+            (ret = wlan_sdio_read_fw_status(pmadapter, &firmwarestat)))
+            continue;
+        if (firmwarestat == FIRMWARE_READY) {
+            ret = MLAN_STATUS_SUCCESS;
+            break;
+        } else {
+            wlan_mdelay(pmadapter, 100);
+            ret = MLAN_STATUS_FAILURE;
+        }
+    }
+
+    if (ret != MLAN_STATUS_SUCCESS)
+        goto done;
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief  This function downloads firmware to card
+ *
+ *  @param pmadapter	A pointer to mlan_adapter
+ *  @param pmfw			A pointer to firmware image
+ *
+ *  @return		MLAN_STATUS_SUCCESS or error code
+ */
+mlan_status
+wlan_dnld_fw(IN pmlan_adapter pmadapter, IN pmlan_fw_image pmfw)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* Download the firmware image via helper */
+    ret = wlan_prog_fw_w_helper(pmadapter, pmfw);
+    if (ret != MLAN_STATUS_SUCCESS) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function probes the driver
+ *  
+ *  @param pmadapter  A pointer to mlan_adapter structure
+ *  @return 	      MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_sdio_probe(pmlan_adapter pmadapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u32 sdio_ireg = 0;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    /* 
+     * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
+     * from the bootloader. If we don't do this we get a interrupt
+     * as soon as we register the irq. 
+     */
+    pcb->moal_read_reg(pmadapter->pmoal_handle, HOST_INTSTATUS_REG, &sdio_ireg);
+
+    /* Disable host interrupt mask register for SDIO */
+    ret = wlan_disable_host_int(pmadapter);
+    if (ret != MLAN_STATUS_SUCCESS)
+        return MLAN_STATUS_FAILURE;
+
+    /* Get SDIO ioport */
+    ret = wlan_sdio_init_ioport(pmadapter);
+
+    return ret;
+}
+
+/** 
+ *  @brief This function gets interrupt status.
+ *  
+ *  @param adapter	A pointer to mlan_adapter structure
+ *  @return 	    None
+ */
+t_void
+mlan_interrupt(t_void * adapter)
+{
+    mlan_adapter *pmadapter = (mlan_adapter *) adapter;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    mlan_buffer mbuf;
+    t_u32 sdio_ireg = 0;
+
+    ENTER();
+
+    memset(&mbuf, 0, sizeof(mlan_buffer));
+    mbuf.pbuf = pmadapter->mp_regs;
+    mbuf.data_len = MAX_MP_REGS;
+
+    if (MLAN_STATUS_SUCCESS !=
+        pcb->moal_read_data_sync(pmadapter->pmoal_handle, &mbuf,
+                                 REG_PORT | MLAN_SDIO_BYTE_MODE_MASK, 0)) {
+        PRINTM(MWARN, "moal_read_data_sync: read registers failed\n");
+        goto done;
+    }
+
+    DBG_HEXDUMP(MDAT_D, "SDIO MP Registers", pmadapter->mp_regs, MAX_MP_REGS);
+    sdio_ireg = pmadapter->mp_regs[HOST_INTSTATUS_REG];
+    if (sdio_ireg) {
+        /* 
+         * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+         * Clear the interrupt status register
+         */
+        PRINTM(MINTR, "sdio_ireg = 0x%x\n", sdio_ireg);
+        pmadapter->sdio_ireg |= sdio_ireg;
+    }
+  done:
+    LEAVE();
+}
+
+/** 
+ *  @brief This function disables the host interrupts.
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_disable_host_int(pmlan_adapter pmadapter)
+{
+    mlan_status ret;
+
+    ENTER();
+    ret = wlan_sdio_disable_host_int_mask(pmadapter, HIM_DISABLE);
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function enables the host interrupts.
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_enable_host_int(pmlan_adapter pmadapter)
+{
+    mlan_status ret;
+
+    ENTER();
+    ret = wlan_sdio_enable_host_int_mask(pmadapter, HIM_ENABLE);
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function decodes the rx packet & 
+ *  calls corresponding handlers according to the packet type
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param pmbuf      A pointer to the SDIO data/cmd buffer
+ *  @param upld_typ  Type of rx packet
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_decode_rx_packet(mlan_adapter * pmadapter, mlan_buffer * pmbuf,
+                      t_u32 upld_typ)
+{
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_u8 *cmdBuf;
+    t_u32 event;
+
+    switch (upld_typ) {
+    case MLAN_TYPE_DATA:
+        PRINTM(MINFO, "--- Rx: Data packet ---\n");
+        pmbuf->data_len = (pmadapter->upld_len - INTF_HEADER_LEN);
+        pmbuf->data_offset += INTF_HEADER_LEN;
+        wlan_handle_rx_packet(pmadapter, pmbuf);
+        break;
+
+    case MLAN_TYPE_CMD:
+        PRINTM(MINFO, "--- Rx: Cmd Response ---\n");
+        DBG_HEXDUMP(MDAT_D, "Cmd RESP BUFFER", pmbuf->pbuf,
+                    pmadapter->upld_len);
+        /* take care of curr_cmd = NULL case */
+        if (!pmadapter->curr_cmd) {
+            cmdBuf = pmadapter->upld_buf;
+            if (pmadapter->ps_state == PS_STATE_SLEEP_CFM) {
+                wlan_process_sleep_confirm_resp(pmadapter,
+                                                pmbuf->pbuf +
+                                                pmbuf->data_offset +
+                                                INTF_HEADER_LEN,
+                                                pmadapter->upld_len -
+                                                INTF_HEADER_LEN);
+            }
+            pmadapter->upld_len -= INTF_HEADER_LEN;
+            memcpy(cmdBuf, pmbuf->pbuf + pmbuf->data_offset + INTF_HEADER_LEN,
+                   MIN(MRVDRV_SIZE_OF_CMD_BUFFER,
+                       pmadapter->upld_len - INTF_HEADER_LEN));
+            pcb->moal_free_mlan_buffer(pmbuf);
+        } else {
+            pmadapter->cmd_resp_received = MTRUE;
+            pmadapter->upld_len -= INTF_HEADER_LEN;
+            pmbuf->data_len -= INTF_HEADER_LEN;
+            pmbuf->data_offset += INTF_HEADER_LEN;
+            pmadapter->curr_cmd->respbuf = pmbuf;
+        }
+        break;
+
+    case MLAN_TYPE_EVENT:
+        PRINTM(MINFO, "--- Rx: Event ---\n");
+
+        event = *(t_u32 *) & pmbuf->pbuf[4];
+        pmadapter->event_cause = wlan_le32_to_cpu(event);
+        if ((pmadapter->upld_len > MLAN_EVENT_HEADER_LEN) &&
+            ((pmadapter->upld_len - MLAN_EVENT_HEADER_LEN) < MAX_EVENT_SIZE)) {
+            memcpy(pmadapter->event_body, pmbuf->pbuf + MLAN_EVENT_HEADER_LEN,
+                   pmadapter->upld_len - MLAN_EVENT_HEADER_LEN);
+        }
+
+        /* event cause has been saved to adapter->event_cause */
+        pmadapter->event_received = MTRUE;
+        pmbuf->data_len = pmadapter->upld_len;
+        pmadapter->pmlan_buffer_event = pmbuf;
+
+        /* remove SDIO header */
+        pmbuf->data_offset += INTF_HEADER_LEN;
+        pmbuf->data_len -= INTF_HEADER_LEN;
+        break;
+
+    default:
+        PRINTM(MERROR, "SDIO unknown upload type = 0x%x\n", upld_typ);
+        pcb->moal_free_mlan_buffer(pmbuf);
+        break;
+    }
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+/** 
+ *  @brief This function receives data from the card in aggregate mode.
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param pmbuf      A pointer to the SDIO data/cmd buffer
+ *  @param port      Current port on which packet needs to be rxed
+ *  @param rx_len    Length of received packet
+ *  @return 	     MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_sdio_card_to_host_mp_aggr(mlan_adapter * pmadapter, mlan_buffer
+                               * pmbuf, t_u8 port, t_u16 rx_len)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_s32 f_do_rx_aggr = 0;
+    t_s32 f_do_rx_cur = 0;
+    t_s32 f_aggr_cur = 0;
+    mlan_buffer mbuf_aggr;
+    mlan_buffer *mbuf_deaggr;
+    t_u32 pind = 0;
+    t_u32 pkt_len, pkt_type = 0;
+    t_u8 *curr_ptr;
+
+    ENTER();
+
+    if (port == CTRL_PORT) {
+        /* Read the command Resp without aggr */
+        PRINTM(MINFO, "card_2_host_mp_aggr: No aggregation for cmd response\n");
+
+        f_do_rx_cur = 1;
+        goto rx_curr_single;
+    }
+
+    if (!pmadapter->mpa_rx.enabled) {
+        PRINTM(MINFO, "card_2_host_mp_aggr: rx aggregation disabled !\n");
+
+        f_do_rx_cur = 1;
+        goto rx_curr_single;
+    }
+
+    if (pmadapter->mp_rd_bitmap & (~((t_u16) CTRL_PORT_MASK))) {
+        /* Some more data RX pending */
+        PRINTM(MINFO, "card_2_host_mp_aggr: Not last packet\n");
+
+        if (MP_RX_AGGR_IN_PROGRESS(pmadapter)) {
+            if (MP_RX_AGGR_BUF_HAS_ROOM(pmadapter, rx_len)) {
+                f_aggr_cur = 1;
+            } else {
+                /* No room in Aggr buf, do rx aggr now */
+                f_do_rx_aggr = 1;
+                f_do_rx_cur = 1;
+            }
+        } else {
+            /* Rx aggr not in progress */
+            f_aggr_cur = 1;
+        }
+
+    } else {
+        /* No more data RX pending */
+        PRINTM(MINFO, "card_2_host_mp_aggr: Last packet\n");
+
+        if (MP_RX_AGGR_IN_PROGRESS(pmadapter)) {
+            f_do_rx_aggr = 1;
+            if (MP_RX_AGGR_BUF_HAS_ROOM(pmadapter, rx_len)) {
+                f_aggr_cur = 1;
+            } else {
+                /* No room in Aggr buf, do rx aggr now */
+                f_do_rx_cur = 1;
+            }
+        } else {
+            f_do_rx_cur = 1;
+        }
+
+    }
+
+    if (f_aggr_cur) {
+        PRINTM(MINFO, "Current packet aggregation.\n");
+        /* Curr pkt can be aggregated */
+        MP_RX_AGGR_SETUP(pmadapter, pmbuf, port, rx_len);
+
+        if (MP_RX_AGGR_PKT_LIMIT_REACHED(pmadapter) ||
+            MP_RX_AGGR_PORT_LIMIT_REACHED(pmadapter)) {
+            PRINTM(MINFO,
+                   "card_2_host_mp_aggr: Aggregation Packet limit reached\n");
+            /* No more pkts allowed in Aggr buf, rx it */
+            f_do_rx_aggr = 1;
+        }
+
+    }
+
+    if (f_do_rx_aggr) {
+        /* do aggr RX now */
+        PRINTM(MINFO, "do_rx_aggr: num of packets: %d\n",
+               pmadapter->mpa_rx.pkt_cnt);
+
+        memset(&mbuf_aggr, 0, sizeof(mlan_buffer));
+
+        mbuf_aggr.pbuf = (t_u8 *) pmadapter->mpa_rx.buf;
+        mbuf_aggr.data_len = pmadapter->mpa_rx.buf_len;
+        if (MLAN_STATUS_SUCCESS !=
+            pcb->moal_read_data_sync(pmadapter->pmoal_handle, &mbuf_aggr,
+                                     (pmadapter->ioport | 0x1000 |
+                                      (pmadapter->mpa_rx.ports << 4)) +
+                                     pmadapter->mpa_rx.start_port, 0)) {
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+
+        curr_ptr = pmadapter->mpa_rx.buf;
+
+        for (pind = 0; pind < pmadapter->mpa_rx.pkt_cnt; pind++) {
+
+            /* get curr PKT len & type */
+            pkt_len = wlan_le16_to_cpu(*(t_u16 *) & curr_ptr[0]);
+            pkt_type = wlan_le16_to_cpu(*(t_u16 *) & curr_ptr[2]);
+
+            PRINTM(MINFO, "RX: [%d] pktlen: %d pkt_type: 0x%x\n", pind,
+                   pkt_len, pkt_type);
+
+            /* copy pkt to deaggr buf */
+            mbuf_deaggr = pmadapter->mpa_rx.mbuf_arr[pind];
+            if ((pkt_type == MLAN_TYPE_DATA) &&
+                (pkt_len <= pmadapter->mpa_rx.len_arr[pind])) {
+                memcpy(mbuf_deaggr->pbuf, curr_ptr, pkt_len);
+                pmadapter->upld_len = pkt_len;
+                /* Process de-aggr packet */
+                wlan_decode_rx_packet(pmadapter, mbuf_deaggr, pkt_type);
+            } else {
+                PRINTM(MERROR, "Wrong aggr packet: type=%d, len=%d, max_len=%d",
+                       pkt_type, pkt_len, pmadapter->mpa_rx.len_arr[pind]);
+                pcb->moal_free_mlan_buffer(mbuf_deaggr);
+            }
+            curr_ptr += pmadapter->mpa_rx.len_arr[pind];
+        }
+        MP_RX_AGGR_BUF_RESET(pmadapter);
+    }
+
+  rx_curr_single:
+    if (f_do_rx_cur) {
+        PRINTM(MINFO, "RX: f_do_rx_cur: port: %d rx_len: %d\n", port, rx_len);
+
+        if (MLAN_STATUS_SUCCESS != wlan_sdio_card_to_host(pmadapter, &pkt_type,
+                                                          (t_u32 *) &
+                                                          pmadapter->upld_len,
+                                                          pmbuf, rx_len,
+                                                          pmadapter->ioport +
+                                                          port)) {
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+
+        wlan_decode_rx_packet(pmadapter, pmbuf, pkt_type);
+
+    }
+
+  done:
+    LEAVE();
+    return ret;
+
+}
+#endif
+/** 
+ *  @brief This function checks the interrupt status and handle it accordingly.
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_process_int_status(mlan_adapter * pmadapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_u8 sdio_ireg = pmadapter->sdio_ireg;
+    mlan_buffer *pmbuf = MNULL;
+    t_u8 *tmp_buf = MNULL;
+    t_u8 port = CTRL_PORT;
+    t_u32 len_reg_l, len_reg_u;
+    t_u32 rx_blocks;
+    t_u16 rx_len;
+#ifndef SDIO_MULTI_PORT_RX_AGGR
+    t_u32 upld_typ = 0;
+#endif
+
+    ENTER();
+
+    if (!pmadapter->sdio_ireg)
+        goto done;
+
+    if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
+        pmadapter->mp_wr_bitmap =
+            ((t_u16) pmadapter->mp_regs[WR_BITMAP_U]) << 8;
+        pmadapter->mp_wr_bitmap |= (t_u16) pmadapter->mp_regs[WR_BITMAP_L];
+        PRINTM(MINTR, "DNLD: wr_bitmap=0x%04x\n", pmadapter->mp_wr_bitmap);
+        if (pmadapter->data_sent &&
+            (pmadapter->mp_wr_bitmap & pmadapter->mp_data_port_mask)) {
+            PRINTM(MINFO, " <--- Tx DONE Interrupt --->\n");
+            pmadapter->data_sent = MFALSE;
+        }
+    }
+
+    /* As firmware will not generate download ready interrupt if the port
+       updated is command port only, cmd_sent should be done for any SDIO
+       interrupt. */
+    if (pmadapter->cmd_sent == MTRUE) {
+        /* Check if firmware has attach buffer at command port and update just
+           that in wr_bit_map. */
+        pmadapter->mp_wr_bitmap |=
+            (t_u16) pmadapter->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
+        if (pmadapter->mp_wr_bitmap & CTRL_PORT_MASK)
+            pmadapter->cmd_sent = MFALSE;
+
+    }
+
+    PRINTM(MINFO, "cmd_sent=%d data_sent=%d\n",
+           pmadapter->cmd_sent, pmadapter->data_sent);
+    if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
+        pmadapter->mp_rd_bitmap =
+            ((t_u16) pmadapter->mp_regs[RD_BITMAP_U]) << 8;
+        pmadapter->mp_rd_bitmap |= (t_u16) pmadapter->mp_regs[RD_BITMAP_L];
+        PRINTM(MINTR, "UPLD: rd_bitmap=0x%04x\n", pmadapter->mp_rd_bitmap);
+
+        while (MTRUE) {
+            ret = wlan_get_rd_port(pmadapter, &port);
+            if (ret != MLAN_STATUS_SUCCESS) {
+                PRINTM(MINFO, "no more rd_port available\n");
+                break;
+            }
+            len_reg_l = RD_LEN_P0_L + (port << 1);
+            len_reg_u = RD_LEN_P0_U + (port << 1);
+            rx_len = ((t_u16) pmadapter->mp_regs[len_reg_u]) << 8;
+            rx_len |= (t_u16) pmadapter->mp_regs[len_reg_l];
+            PRINTM(MINFO, "RX: port=%d rx_len=%u\n", port, rx_len);
+            rx_blocks =
+                (rx_len + MLAN_SDIO_BLOCK_SIZE - 1) / MLAN_SDIO_BLOCK_SIZE;
+            if (rx_len <= INTF_HEADER_LEN ||
+                (rx_blocks * MLAN_SDIO_BLOCK_SIZE) > ALLOC_BUF_SIZE) {
+                PRINTM(MERROR, "invalid rx_len=%d\n", rx_len);
+                ret = MLAN_STATUS_FAILURE;
+                goto done;
+            }
+            rx_len = rx_blocks * MLAN_SDIO_BLOCK_SIZE;
+            if (MLAN_STATUS_SUCCESS !=
+                pcb->moal_alloc_mlan_buffer(rx_len + HEADER_ALIGNMENT,
+                                            &pmbuf)) {
+                PRINTM(MWARN, "Failed to allocate 'mlan_buffer'\n");
+                ret = MLAN_STATUS_FAILURE;
+                goto done;
+            }
+            tmp_buf =
+                (t_u8 *) ALIGN_ADDR(pmbuf->pbuf + pmbuf->data_offset,
+                                    HEADER_ALIGNMENT);
+            pmbuf->data_offset += tmp_buf - (pmbuf->pbuf + pmbuf->data_offset);
+            pmbuf->data_len = rx_len;
+            PRINTM(MINFO, "rx_len = %d\n", rx_len);
+
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+            if (MLAN_STATUS_SUCCESS !=
+                wlan_sdio_card_to_host_mp_aggr(pmadapter, pmbuf, port,
+                                               rx_len)) {
+#else
+            /* Transfer data from card */
+            if (MLAN_STATUS_SUCCESS !=
+                wlan_sdio_card_to_host(pmadapter, &upld_typ,
+                                       (t_u32 *) & pmadapter->upld_len, pmbuf,
+                                       rx_len, pmadapter->ioport + port)) {
+#endif /* SDIO_MULTI_PORT_RX_AGGR */
+
+                t_u32 cr = 0;
+
+                PRINTM(MERROR, "Card to host failed: int status=0x%x\n",
+                       sdio_ireg);
+                if (MLAN_STATUS_SUCCESS !=
+                    pcb->moal_read_reg(pmadapter->pmoal_handle,
+                                       CONFIGURATION_REG, &cr))
+                    PRINTM(MERROR, "read CFG reg failed\n");
+
+                PRINTM(MINFO, "Config Reg val = %d\n", cr);
+                if (MLAN_STATUS_SUCCESS !=
+                    pcb->moal_write_reg(pmadapter->pmoal_handle,
+                                        CONFIGURATION_REG, (cr | 0x04)))
+                    PRINTM(MERROR, "write CFG reg failed\n");
+
+                PRINTM(MINFO, "write success\n");
+                if (MLAN_STATUS_SUCCESS !=
+                    pcb->moal_read_reg(pmadapter->pmoal_handle,
+                                       CONFIGURATION_REG, &cr))
+                    PRINTM(MERROR, "read CFG reg failed\n");
+
+                PRINTM(MINFO, "Config reg val =%x\n", cr);
+                ret = MLAN_STATUS_FAILURE;
+                pcb->moal_free_mlan_buffer(pmbuf);
+                goto done;
+            }
+#ifndef SDIO_MULTI_PORT_RX_AGGR
+            wlan_decode_rx_packet(pmadapter, pmbuf, upld_typ);
+#endif
+
+        }
+    }
+
+    ret = MLAN_STATUS_SUCCESS;
+  done:
+    pmadapter->sdio_ireg = 0;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function sends data to the card.
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param type	     data or command
+ *  @param pmbuf     A pointer to mlan_buffer (pmbuf->data_len should include SDIO header)
+ *  @param tx_param  A pointer to mlan_tx_param
+ *  @return 	     MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_sdio_host_to_card(mlan_adapter * pmadapter, t_u8 type, mlan_buffer * pmbuf,
+                       mlan_tx_param * tx_param)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_u32 buf_block_len;
+    t_u32 blksz;
+    t_u8 port = CTRL_PORT;
+    t_u32 i = 0;
+    t_u8 *payload = pmbuf->pbuf + pmbuf->data_offset;
+
+    ENTER();
+
+    /* Allocate buffer and copy payload */
+    blksz = MLAN_SDIO_BLOCK_SIZE;
+    buf_block_len = (pmbuf->data_len + blksz - 1) / blksz;
+    *(t_u16 *) & payload[0] = wlan_cpu_to_le16(pmbuf->data_len);
+    *(t_u16 *) & payload[2] = wlan_cpu_to_le16(type);
+
+    /* 
+     * This is SDIO specific header
+     *  t_u16 length,
+     *  t_u16 type (MLAN_TYPE_DATA = 0, MLAN_TYPE_CMD = 1, MLAN_TYPE_EVENT = 3) 
+     */
+    if (type == MLAN_TYPE_DATA) {
+        ret = wlan_get_wr_port_data(pmadapter, &port);
+        if (ret != MLAN_STATUS_SUCCESS) {
+            PRINTM(MERROR, "no wr_port available: %d\n", ret);
+            goto exit;
+        }
+    } else {
+        pmadapter->cmd_sent = MTRUE;
+        /* Type must be MLAN_TYPE_CMD */
+
+        if (pmbuf->data_len <= INTF_HEADER_LEN ||
+            pmbuf->data_len > WLAN_UPLD_SIZE)
+            PRINTM(MWARN,
+                   "wlan_sdio_host_to_card(): Error: payload=%p, nb=%d\n",
+                   payload, pmbuf->data_len);
+    }
+
+    do {
+        /* Transfer data to card */
+        pmbuf->data_len = buf_block_len * blksz;
+
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+        if (tx_param)
+            ret =
+                wlan_host_to_card_mp_aggr(pmadapter, pmbuf, port,
+                                          tx_param->next_pkt_len);
+        else
+            ret = wlan_host_to_card_mp_aggr(pmadapter, pmbuf, port, 0);
+#else
+        ret =
+            pcb->moal_write_data_sync(pmadapter->pmoal_handle, pmbuf,
+                                      pmadapter->ioport + port, 0);
+#endif /* SDIO_MULTI_PORT_TX_AGGR */
+        if (ret != MLAN_STATUS_SUCCESS) {
+            i++;
+            PRINTM(MERROR, "host_to_card, write iomem (%d) failed: %d\n", i,
+                   ret);
+            if (MLAN_STATUS_SUCCESS !=
+                pcb->moal_write_reg(pmadapter->pmoal_handle, CONFIGURATION_REG,
+                                    0x04)) {
+                PRINTM(MERROR, "write CFG reg failed\n");
+            }
+            ret = MLAN_STATUS_FAILURE;
+            if (i > MAX_WRITE_IOMEM_RETRY) {
+                if (type == MLAN_TYPE_CMD)
+                    pmadapter->cmd_sent = MFALSE;
+                if (type == MLAN_TYPE_DATA)
+                    pmadapter->data_sent = MFALSE;
+                goto exit;
+            }
+        } else {
+            if (type == MLAN_TYPE_DATA) {
+                if (!(pmadapter->mp_wr_bitmap & (1 << pmadapter->curr_wr_port)))
+                    pmadapter->data_sent = MTRUE;
+                else
+                    pmadapter->data_sent = MFALSE;
+            }
+            DBG_HEXDUMP(MDAT_D, "SDIO Blk Wr", pmbuf->pbuf + pmbuf->data_offset,
+                        MIN(pmbuf->data_len, MAX_DATA_DUMP_LEN));
+        }
+    } while (ret == MLAN_STATUS_FAILURE);
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+/** 
+ *  @brief This function sends data to the card in SDIO aggregated mode.
+ *  
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param mbuf      A pointer to the SDIO data/cmd buffer
+ *  @param port	     current port for aggregation
+ *  @param next_pkt_len Length of next packet used for multiport aggregation
+ *  @return 	     MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_host_to_card_mp_aggr(mlan_adapter * pmadapter, mlan_buffer * mbuf,
+                          t_u8 port, t_u32 next_pkt_len)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_s32 f_send_aggr_buf = 0;
+    t_s32 f_send_cur_buf = 0;
+    t_s32 f_precopy_cur_buf = 0;
+    t_s32 f_postcopy_cur_buf = 0;
+    mlan_buffer mbuf_aggr;
+
+    ENTER();
+
+    PRINTM(MDAT_D, "host_2_card_mp_aggr: next_pkt_len: %d curr_port:%d\n",
+           next_pkt_len, port);
+
+    if ((!pmadapter->mpa_tx.enabled) || (port == CTRL_PORT)) {
+        PRINTM(MINFO, "host_2_card_mp_aggr: tx aggregation disabled !\n");
+
+        f_send_cur_buf = 1;
+        goto tx_curr_single;
+    }
+
+    if (next_pkt_len) {
+        /* More pkt in TX queue */
+        PRINTM(MINFO, "host_2_card_mp_aggr: More packets in Queue.\n");
+
+        if (MP_TX_AGGR_IN_PROGRESS(pmadapter)) {
+            if (!MP_TX_AGGR_PORT_LIMIT_REACHED(pmadapter) &&
+                MP_TX_AGGR_BUF_HAS_ROOM(pmadapter, mbuf, mbuf->data_len)) {
+                f_precopy_cur_buf = 1;
+
+                if (!(pmadapter->mp_wr_bitmap & (1 << pmadapter->curr_wr_port))
+                    || !MP_TX_AGGR_BUF_HAS_ROOM(pmadapter, mbuf,
+                                                next_pkt_len)) {
+                    f_send_aggr_buf = 1;
+                }
+            } else {
+                /* No room in Aggr buf, send it */
+                f_send_aggr_buf = 1;
+
+                if (MP_TX_AGGR_PORT_LIMIT_REACHED(pmadapter) ||
+                    !(pmadapter->
+                      mp_wr_bitmap & (1 << pmadapter->curr_wr_port))) {
+                    f_send_cur_buf = 1;
+                } else {
+                    f_postcopy_cur_buf = 1;
+                }
+            }
+        } else {
+            if (MP_TX_AGGR_BUF_HAS_ROOM(pmadapter, mbuf, mbuf->data_len) &&
+                (pmadapter->mp_wr_bitmap & (1 << pmadapter->curr_wr_port)))
+                f_precopy_cur_buf = 1;
+            else
+                f_send_cur_buf = 1;
+        }
+    } else {
+        /* Last pkt in TX queue */
+        PRINTM(MINFO, "host_2_card_mp_aggr: Last packet in Tx Queue.\n");
+
+        if (MP_TX_AGGR_IN_PROGRESS(pmadapter)) {
+            /* some packs in Aggr buf already */
+            f_send_aggr_buf = 1;
+
+            if (MP_TX_AGGR_BUF_HAS_ROOM(pmadapter, mbuf, mbuf->data_len)) {
+                f_precopy_cur_buf = 1;
+            } else {
+                /* No room in Aggr buf, send it */
+                f_send_cur_buf = 1;
+            }
+        } else {
+            f_send_cur_buf = 1;
+        }
+    }
+
+    if (f_precopy_cur_buf) {
+        PRINTM(MDATA, "host_2_card_mp_aggr: Precopy current buffer\n");
+        MP_TX_AGGR_BUF_PUT(pmadapter, mbuf, port);
+
+        if (MP_TX_AGGR_PKT_LIMIT_REACHED(pmadapter) ||
+            MP_TX_AGGR_PORT_LIMIT_REACHED(pmadapter)) {
+            PRINTM(MDAT_D,
+                   "host_2_card_mp_aggr: Aggregation Pkt limit reached\n");
+            /* No more pkts allowed in Aggr buf, send it */
+            f_send_aggr_buf = 1;
+        }
+    }
+
+    if (f_send_aggr_buf) {
+        PRINTM(MDATA, "host_2_card_mp_aggr: Send aggregation buffer."
+               "%d %d\n", pmadapter->mpa_tx.start_port,
+               pmadapter->mpa_tx.ports);
+
+        memset(&mbuf_aggr, 0, sizeof(mlan_buffer));
+
+        mbuf_aggr.pbuf = (t_u8 *) pmadapter->mpa_tx.buf;
+        mbuf_aggr.data_len = pmadapter->mpa_tx.buf_len;
+        ret = pcb->moal_write_data_sync(pmadapter->pmoal_handle, &mbuf_aggr,
+                                        (pmadapter->ioport | 0x1000 |
+                                         (pmadapter->mpa_tx.ports << 4)) +
+                                        pmadapter->mpa_tx.start_port, 0);
+
+        MP_TX_AGGR_BUF_RESET(pmadapter);
+    }
+
+  tx_curr_single:
+    if (f_send_cur_buf) {
+        PRINTM(MDATA, "host_2_card_mp_aggr: Send current buffer %d\n", port);
+        ret = pcb->moal_write_data_sync(pmadapter->pmoal_handle, mbuf,
+                                        pmadapter->ioport + port, 0);
+    }
+
+    if (f_postcopy_cur_buf) {
+        PRINTM(MDATA, "host_2_card_mp_aggr: Postcopy current buffer\n");
+        MP_TX_AGGR_BUF_PUT(pmadapter, mbuf, port);
+    }
+
+    LEAVE();
+    return ret;
+}
+#endif /* SDIO_MULTI_PORT_TX_AGGR */
+
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+/** 
+ *  @brief This function allocates buffer for the SDIO aggregation buffer 
+ *  		related members of adapter structure 
+ *  
+ *  @param pmadapter       A pointer to mlan_adapter structure
+ *  @param mpa_tx_buf_size Tx buffer size to allocate
+ *  @param mpa_rx_buf_size Rx buffer size to allocate
+ *
+ *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_alloc_sdio_mpa_buffers(IN mlan_adapter * pmadapter,
+                            t_u32 mpa_tx_buf_size, t_u32 mpa_rx_buf_size)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+    ret =
+        pcb->moal_malloc(mpa_tx_buf_size + HEADER_ALIGNMENT,
+                         (t_u8 **) & pmadapter->mpa_tx.head_ptr);
+    if (ret != MLAN_STATUS_SUCCESS || !pmadapter->mpa_tx.head_ptr) {
+        PRINTM(MERROR, "Could not allocate buffer for SDIO MP TX aggr\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto error;
+    }
+    pmadapter->mpa_tx.buf =
+        (t_u8 *) ALIGN_ADDR(pmadapter->mpa_tx.head_ptr, HEADER_ALIGNMENT);
+    pmadapter->mpa_tx.buf_size = mpa_tx_buf_size;
+#endif /* SDIO_MULTI_PORT_TX_AGGR */
+
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+    ret =
+        pcb->moal_malloc(mpa_rx_buf_size + HEADER_ALIGNMENT,
+                         (t_u8 **) & pmadapter->mpa_rx.head_ptr);
+    if (ret != MLAN_STATUS_SUCCESS || !pmadapter->mpa_rx.head_ptr) {
+        PRINTM(MERROR, "Could not allocate buffer for SDIO MP RX aggr\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto error;
+    }
+    pmadapter->mpa_rx.buf =
+        (t_u8 *) ALIGN_ADDR(pmadapter->mpa_rx.head_ptr, HEADER_ALIGNMENT);
+    pmadapter->mpa_rx.buf_size = mpa_rx_buf_size;
+#endif /* SDIO_MULTI_PORT_RX_AGGR */
+  error:
+    if (ret != MLAN_STATUS_SUCCESS) {
+        wlan_free_sdio_mpa_buffers(pmadapter);
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function frees buffers for the SDIO aggregation
+ *  
+ *  @param pmadapter       A pointer to mlan_adapter structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_free_sdio_mpa_buffers(IN mlan_adapter * pmadapter)
+{
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+    if (pmadapter->mpa_tx.buf) {
+        pcb->moal_mfree((t_u8 *) pmadapter->mpa_tx.head_ptr);
+        pmadapter->mpa_tx.head_ptr = MNULL;
+        pmadapter->mpa_tx.buf = MNULL;
+        pmadapter->mpa_tx.buf_size = 0;
+    }
+#endif /* SDIO_MULTI_PORT_TX_AGGR */
+
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+    if (pmadapter->mpa_rx.buf) {
+        pcb->moal_mfree((t_u8 *) pmadapter->mpa_rx.head_ptr);
+        pmadapter->mpa_rx.head_ptr = MNULL;
+        pmadapter->mpa_rx.buf = MNULL;
+        pmadapter->mpa_rx.buf_size = 0;
+    }
+#endif /* SDIO_MULTI_PORT_RX_AGGR */
+
+    return MLAN_STATUS_SUCCESS;
+}
+#endif /* SDIO_MULTI_PORT_TX_AGGR || SDIO_MULTI_PORT_RX_AGGR */
diff --git a/wlan_src/mlan/mlan_sdio.h b/wlan_src/mlan/mlan_sdio.h
new file mode 100755
index 0000000..cf46277
--- /dev/null
+++ b/wlan_src/mlan/mlan_sdio.h
@@ -0,0 +1,323 @@
+/** @file mlan_sdio.h
+ * 
+ *  @brief This file contains definitions for SDIO interface.
+ *  
+ *  Copyright (C) 2008-2009, Marvell International Ltd.
+ *  All Rights Reserved
+ */
+/****************************************************
+Change log:
+****************************************************/
+
+#ifndef	_MLAN_SDIO_H
+#define	_MLAN_SDIO_H
+
+/** Block mode */
+#define BLOCK_MODE	1
+/** Fixed address mode */
+#define FIXED_ADDRESS	0
+
+/** Control register for BUS interface */
+#define BUS_INTERFACE_CONTROL_REG 	0x07
+
+/** Asynchronous interrupt mode */
+#define ASYNC_INT_MODE			0x20
+
+/** Port for registers */
+#define REG_PORT			0
+/** LSB of read bitmap */
+#define RD_BITMAP_L			0x04
+/** MSB of read bitmap */
+#define RD_BITMAP_U			0x05
+/** LSB of write bitmap */
+#define WR_BITMAP_L			0x06
+/** MSB of write bitmap */
+#define WR_BITMAP_U			0x07
+/** LSB of read length for port 0 */
+#define RD_LEN_P0_L			0x08
+/** MSB of read length for port 0 */
+#define RD_LEN_P0_U			0x09
+/** Ctrl port */
+#define CTRL_PORT			0
+/** Ctrl port mask */
+#define CTRL_PORT_MASK			0x0001
+/** Data port mask */
+#define DATA_PORT_MASK			0xfffe
+/** Misc. Config Register : Auto Re-enable interrupts */
+#define AUTO_RE_ENABLE_INT             	MBIT(4)
+
+/* Host Control Registers */
+/** Host Control Registers : I/O port 0 */
+#define IO_PORT_0_REG			0x78
+/** Host Control Registers : I/O port 1 */
+#define IO_PORT_1_REG			0x79
+/** Host Control Registers : I/O port 2 */
+#define IO_PORT_2_REG			0x7A
+
+/** Host Control Registers : Configuration */
+#define CONFIGURATION_REG		0x00
+/** Host Control Registers : Host without Command 53 finish host*/
+#define HOST_TO_CARD_EVENT       (0x1U << 3)
+/** Host Control Registers : Host without Command 53 finish host */
+#define HOST_WO_CMD53_FINISH_HOST	(0x1U << 2)
+/** Host Control Registers : Host power up */
+#define HOST_POWER_UP			(0x1U << 1)
+/** Host Control Registers : Host power down */
+#define HOST_POWER_DOWN			(0x1U << 0)
+
+/** Host Control Registers : Host interrupt mask */
+#define HOST_INT_MASK_REG		0x02
+/** Host Control Registers : Upload host interrupt mask */
+#define UP_LD_HOST_INT_MASK		(0x1U)
+/** Host Control Registers : Download host interrupt mask */
+#define DN_LD_HOST_INT_MASK		(0x2U)
+/** Enable Host interrupt mask */
+#define HIM_ENABLE			(UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
+/** Disable Host interrupt mask */
+#define	HIM_DISABLE			0xff
+
+/** Host Control Registers : Host interrupt status */
+#define HOST_INTSTATUS_REG		0x03
+/** Host Control Registers : Upload host interrupt status */
+#define UP_LD_HOST_INT_STATUS		(0x1U)
+/** Host Control Registers : Download host interrupt status */
+#define DN_LD_HOST_INT_STATUS		(0x2U)
+
+/** Host Control Registers : Host interrupt RSR */
+#define HOST_INT_RSR_REG		0x01
+/** Host Control Registers : Upload host interrupt RSR */
+#define UP_LD_HOST_INT_RSR		(0x1U)
+
+/** Host Control Registers : Host interrupt status */
+#define HOST_INT_STATUS_REG		0x28
+/** Host Control Registers : Upload CRC error */
+#define UP_LD_CRC_ERR			(0x1U << 2)
+/** Host Control Registers : Upload restart */
+#define UP_LD_RESTART              	(0x1U << 1)
+/** Host Control Registers : Download restart */
+#define DN_LD_RESTART              	(0x1U << 0)
+
+/* Card Control Registers */
+/** Card Control Registers : Read SQ base address A0 register */
+#define SQ_READ_BASE_ADDRESS_A0_REG  	0x40
+/** Card Control Registers : Read SQ base address A1 register */
+#define SQ_READ_BASE_ADDRESS_A1_REG  	0x41
+/** Card Control Registers : Read SQ base address A2 register */
+#define SQ_READ_BASE_ADDRESS_A2_REG  	0x42
+/** Card Control Registers : Read SQ base address A3 register */
+#define SQ_READ_BASE_ADDRESS_A3_REG  	0x43
+/** Card Control Registers : Read SQ base address B0 register */
+#define SQ_READ_BASE_ADDRESS_B0_REG  	0x44
+/** Card Control Registers : Read SQ base address B1 register */
+#define SQ_READ_BASE_ADDRESS_B1_REG  	0x45
+/** Card Control Registers : Read SQ base address B2 register */
+#define SQ_READ_BASE_ADDRESS_B2_REG  	0x46
+/** Card Control Registers : Read SQ base address B3 register */
+#define SQ_READ_BASE_ADDRESS_B3_REG  	0x47
+
+/** Card Control Registers : Card status register */
+#define CARD_STATUS_REG              	0x30
+/** Card Control Registers : Card I/O ready */
+#define CARD_IO_READY              	(0x1U << 3)
+/** Card Control Registers : CIS card ready */
+#define CIS_CARD_RDY                 	(0x1U << 2)
+/** Card Control Registers : Upload card ready */
+#define UP_LD_CARD_RDY               	(0x1U << 1)
+/** Card Control Registers : Download card ready */
+#define DN_LD_CARD_RDY               	(0x1U << 0)
+
+/** Card Control Registers : Host interrupt mask register */
+#define HOST_INTERRUPT_MASK_REG      	0x34
+/** Card Control Registers : Host power interrupt mask */
+#define HOST_POWER_INT_MASK          	(0x1U << 3)
+/** Card Control Registers : Abort card interrupt mask */
+#define ABORT_CARD_INT_MASK          	(0x1U << 2)
+/** Card Control Registers : Upload card interrupt mask */
+#define UP_LD_CARD_INT_MASK          	(0x1U << 1)
+/** Card Control Registers : Download card interrupt mask */
+#define DN_LD_CARD_INT_MASK          	(0x1U << 0)
+
+/** Card Control Registers : Card interrupt status register */
+#define CARD_INTERRUPT_STATUS_REG    	0x38
+/** Card Control Registers : Power up interrupt */
+#define POWER_UP_INT                 	(0x1U << 4)
+/** Card Control Registers : Power down interrupt */
+#define POWER_DOWN_INT               	(0x1U << 3)
+
+/** Card Control Registers : Card interrupt RSR register */
+#define CARD_INTERRUPT_RSR_REG       	0x3c
+/** Card Control Registers : Power up RSR */
+#define POWER_UP_RSR                 	(0x1U << 4)
+/** Card Control Registers : Power down RSR */
+#define POWER_DOWN_RSR               	(0x1U << 3)
+
+/** Card Control Registers : Debug 0 register */
+#define DEBUG_0_REG                  	0x70
+/** Card Control Registers : SD test BUS 0 */
+#define SD_TESTBUS0                  	(0x1U)
+/** Card Control Registers : Debug 1 register */
+#define DEBUG_1_REG                  	0x71
+/** Card Control Registers : SD test BUS 1 */
+#define SD_TESTBUS1                  	(0x1U)
+/** Card Control Registers : Debug 2 register */
+#define DEBUG_2_REG                  	0x72
+/** Card Control Registers : SD test BUS 2 */
+#define SD_TESTBUS2                  	(0x1U)
+/** Card Control Registers : Debug 3 register */
+#define DEBUG_3_REG                  	0x73
+/** Card Control Registers : SD test BUS 3 */
+#define SD_TESTBUS3                  	(0x1U)
+/** Card Control Registers : Card OCR 0 register */
+#define CARD_OCR_0_REG               	0x68
+/** Card Control Registers : Card OCR 1 register */
+#define CARD_OCR_1_REG               	0x69
+/** Card Control Registers : Card OCR 3 register */
+#define CARD_OCR_3_REG               	0x6A
+/** Card Control Registers : Card config register */
+#define CARD_CONFIG_REG              	0x6B
+/** Card Control Registers : Miscellaneous Configuration Register */
+#define CARD_MISC_CFG_REG              	0x6C
+/** Card Control Registers : Card revision register */
+#define CARD_REVISION_REG            	0x5c
+/** Card Control Registers : Command 53 finish G BUS */
+#define CMD53_FINISH_GBUS            	(0x1U << 1)
+/** Card Control Registers : SD negative edge */
+#define SD_NEG_EDGE                  	(0x1U << 0)
+
+/* Special registers in function 0 of the SDxx card */
+/** Special register in function 0 of the SDxxx card : Scratch 0 */
+#define	SCRATCH_0_REG			0x80fe
+/** Special register in function 0 of the SDxxx card : Scratch 1 */
+#define	SCRATCH_1_REG			0x80ff
+/** Host F1 read base 0 */
+#define HOST_F1_RD_BASE_0		0x0040
+/** Host F1 read base 1 */
+#define HOST_F1_RD_BASE_1		0x0041
+/** Host F1 card ready */
+#define HOST_F1_CARD_RDY		0x0020
+
+/** Chip Id Register 0 */
+#define CARD_CHIP_ID_0_REG		0x801c
+/** Chip Id Register 1 */
+#define CARD_CHIP_ID_1_REG		0x801d
+/** Firmware status 0 register */
+#define CARD_FW_STATUS0_REG		0x60
+/** Firmware status 1 register */
+#define CARD_FW_STATUS1_REG		0x61
+/** Rx length register */
+#define CARD_RX_LEN_REG			0x62
+/** Rx unit register */
+#define CARD_RX_UNIT_REG		0x63
+
+/** Event header Len*/
+#define MLAN_EVENT_HEADER_LEN           8
+
+#define MAX_BYTE_MODE_SIZE             512
+
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+
+/** SDIO Tx aggregation in progress ? */
+#define MP_TX_AGGR_IN_PROGRESS(a) (a->mpa_tx.pkt_cnt>0)
+
+/** SDIO Tx aggregation buffer room for next packet ? */
+#define MP_TX_AGGR_BUF_HAS_ROOM(a,mbuf, len) ((a->mpa_tx.buf_len+len)<= a->mpa_tx.buf_size)
+
+/** Copy current packet (SDIO Tx aggregation buffer) to SDIO buffer */
+#define MP_TX_AGGR_BUF_PUT(a, mbuf, port) do{                   \
+    pmadapter->callbacks.moal_memmove(&a->mpa_tx.buf[a->mpa_tx.buf_len],mbuf->pbuf+mbuf->data_offset,mbuf->data_len);\
+    a->mpa_tx.buf_len += mbuf->data_len;                        \
+    if(!a->mpa_tx.pkt_cnt){                                     \
+        a->mpa_tx.start_port = port;                            \
+    }                                                           \
+    if(a->mpa_tx.start_port<=port){                             \
+        a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt)); 			\
+    }else{                                                      \
+          a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+(MAX_PORT - a->mp_end_port)));           \
+    }                                                           \
+    a->mpa_tx.pkt_cnt++;                                        \
+}while(0);
+
+/** SDIO Tx aggregation limit ? */
+#define MP_TX_AGGR_PKT_LIMIT_REACHED(a) (a->mpa_tx.pkt_cnt==a->mpa_tx.pkt_aggr_limit)
+
+/** SDIO Tx aggregation port limit ? */
+#define MP_TX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_wr_port < \
+			a->mpa_tx.start_port) && (((MAX_PORT - \
+			a->mpa_tx.start_port) + a->curr_wr_port) >= \
+				SDIO_MP_AGGR_DEF_PKT_LIMIT))
+
+/** Reset SDIO Tx aggregation buffer parameters */
+#define MP_TX_AGGR_BUF_RESET(a) do{         \
+   a->mpa_tx.pkt_cnt = 0;                   \
+   a->mpa_tx.buf_len = 0;                   \
+   a->mpa_tx.ports = 0;                     \
+   a->mpa_tx.start_port = 0;                \
+} while(0);
+
+#endif /* SDIO_MULTI_PORT_TX_AGGR */
+
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+
+/** SDIO Rx aggregation limit ? */
+#define MP_RX_AGGR_PKT_LIMIT_REACHED(a) (a->mpa_rx.pkt_cnt== a->mpa_rx.pkt_aggr_limit)
+
+/** SDIO Tx aggregation port limit ? */
+#define MP_RX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_rd_port < \
+			a->mpa_rx.start_port) && (((MAX_PORT - \
+			a->mpa_rx.start_port) + a->curr_rd_port) >= \
+			SDIO_MP_AGGR_DEF_PKT_LIMIT))
+
+/** SDIO Rx aggregation in progress ? */
+#define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt>0)
+
+/** SDIO Rx aggregation buffer room for next packet ? */
+#define MP_RX_AGGR_BUF_HAS_ROOM(a,rx_len)   ((a->mpa_rx.buf_len+rx_len)<=a->mpa_rx.buf_size)
+
+/** Prepare to copy current packet from card to SDIO Rx aggregation buffer */
+#define MP_RX_AGGR_SETUP(a, mbuf, port, rx_len) do{    \
+    a->mpa_rx.buf_len += rx_len;                       \
+    if(!a->mpa_rx.pkt_cnt){                            \
+        a->mpa_rx.start_port = port;                   \
+    }                                                  \
+    if(a->mpa_rx.start_port<=port){                    \
+        a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt));   \
+    }else{                                             \
+        a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt+1)); \
+    }                                                  \
+    a->mpa_rx.mbuf_arr[a->mpa_rx.pkt_cnt] = mbuf;      \
+    a->mpa_rx.len_arr[a->mpa_rx.pkt_cnt] = rx_len;     \
+    a->mpa_rx.pkt_cnt++;                               \
+}while(0);
+
+/** Reset SDIO Rx aggregation buffer parameters */
+#define MP_RX_AGGR_BUF_RESET(a) do{         \
+   a->mpa_rx.pkt_cnt = 0;                   \
+   a->mpa_rx.buf_len = 0;                   \
+   a->mpa_rx.ports = 0;                     \
+   a->mpa_rx.start_port = 0;                \
+} while(0);
+
+#endif /* SDIO_MULTI_PORT_RX_AGGR */
+
+/** Disable host interrupt */
+mlan_status wlan_disable_host_int(pmlan_adapter pmadapter);
+/** Enable host interrupt */
+mlan_status wlan_enable_host_int(pmlan_adapter pmadapter);
+/** Probe and initialization function */
+mlan_status wlan_sdio_probe(pmlan_adapter pmadapter);
+/** multi interface download check */
+mlan_status wlan_check_winner_status(mlan_adapter * pmadapter);
+/** Firmware status check */
+mlan_status wlan_check_fw_status(mlan_adapter * pmadapter, t_u32 pollnum);
+/** Process Interrupt Status */
+mlan_status wlan_process_int_status(mlan_adapter * pmadapter);
+/** Transfer data to card */
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+mlan_status wlan_host_to_card_mp_aggr(mlan_adapter * pmadapter,
+                                      mlan_buffer * mbuf, t_u8 port,
+                                      t_u32 next_pkt_len);
+#endif
+mlan_status wlan_sdio_host_to_card(mlan_adapter * pmadapter, t_u8 type,
+                                   mlan_buffer * mbuf,
+                                   mlan_tx_param * tx_param);
+#endif /* _MLAN_SDIO_H */
diff --git a/wlan_src/mlan/mlan_shim.c b/wlan_src/mlan/mlan_shim.c
new file mode 100755
index 0000000..e4cf418
--- /dev/null
+++ b/wlan_src/mlan/mlan_shim.c
@@ -0,0 +1,721 @@
+/** @file mlan_shim.c
+ *  
+ *  @brief This file contains APIs to MOAL module.
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/**
+ *  @mainpage MLAN Driver
+ *
+ *  @section overview_sec Overview
+ *
+ *  The MLAN is an OS independent WLAN driver for Marvell 802.11
+ *  embedded chipset.
+ * 
+ *  @section copyright_sec Copyright
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ */
+
+/********************************************************
+Change log:
+    10/13/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+                Local Variables
+********************************************************/
+/** mlan function table */
+static mlan_operations ops[] = {
+    {
+     /* init cmd handler */
+     mlan_sta_init_cmd,
+     /* ioctl handler */
+     mlan_sta_ioctl,
+     /* cmd handler */
+     mlan_sta_prepare_cmd,
+     /* cmdresp handler */
+     mlan_process_sta_cmdresp,
+     /* rx handler */
+     mlan_process_sta_rx_packet,
+     /* Event handler */
+     mlan_process_sta_event,
+     /* txpd handler */
+     mlan_process_sta_txpd,
+     /* bss type */
+     MLAN_BSS_TYPE_STA,
+     },
+};
+
+/********************************************************
+        Global Variables
+********************************************************/
+
+/**
+ *  MLAN Adapter pointer
+ */
+mlan_adapter *g_pmadapter = MNULL;
+
+/********************************************************
+        Local Functions
+*******************************************************/
+
+/********************************************************
+        Global Functions
+********************************************************/
+
+/**
+ *  @brief This function registers MOAL to MLAN module.
+ *  
+ *  @param pmdevice        A pointer to a mlan_device structure
+ *                         allocated in MOAL
+ *  @param ppmlan_adapter  A pointer to a t_void pointer to store
+ *                         mlan_adapter structure pointer as the context
+ *
+ *  @return                MLAN_STATUS_SUCCESS
+ *                             The registration succeeded.
+ *                         MLAN_STATUS_FAILURE
+ *                             The registration failed.
+ *
+ * mlan_status mlan_register (
+ *   IN pmlan_device     pmdevice,
+ *   OUT t_void          **ppmlan_adapter
+ * );
+ *
+ * Comments
+ *   MOAL constructs mlan_device data structure to pass moal_handle and
+ *   mlan_callback table to MLAN. MLAN returns mlan_adapter pointer to
+ *   the ppmlan_adapter buffer provided by MOAL.
+ * Headers:
+ *   declared in mlan_decl.h
+ * See Also
+ *   mlan_unregister
+ */
+mlan_status
+mlan_register(IN pmlan_device pmdevice, OUT t_void ** ppmlan_adapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_adapter pmadapter = MNULL;
+    pmlan_callbacks pcb = MNULL;
+    t_u8 i = 0;
+    t_u32 j = 0;
+
+    ASSERT(pmdevice);
+    ASSERT(ppmlan_adapter);
+    ASSERT(pmdevice->callbacks.moal_malloc);
+    ASSERT(pmdevice->callbacks.moal_memset);
+    ASSERT(pmdevice->callbacks.moal_memmove);
+
+    /* Allocate memory for adapter structure */
+    if ((pmdevice->callbacks.moal_malloc(sizeof(mlan_adapter),
+                                         (t_u8 **) & pmadapter) !=
+         MLAN_STATUS_SUCCESS)
+        || !pmadapter) {
+        ret = MLAN_STATUS_FAILURE;
+        goto exit_register;
+    }
+    g_pmadapter = pmadapter;
+
+    pmdevice->callbacks.moal_memset(pmadapter, 0, sizeof(mlan_adapter));
+
+    pcb = &pmadapter->callbacks;
+
+    /* Save callback functions */
+    pmdevice->callbacks.moal_memmove(pcb,
+                                     &pmdevice->callbacks,
+                                     sizeof(mlan_callbacks));
+
+    /* Assertion for all callback functions */
+    ASSERT(pcb->moal_init_fw_complete);
+    ASSERT(pcb->moal_shutdown_fw_complete);
+    ASSERT(pcb->moal_send_packet_complete);
+    ASSERT(pcb->moal_recv_complete);
+    ASSERT(pcb->moal_recv_packet);
+    ASSERT(pcb->moal_recv_event);
+    ASSERT(pcb->moal_ioctl_complete);
+    ASSERT(pcb->moal_write_reg);
+    ASSERT(pcb->moal_read_reg);
+    ASSERT(pcb->moal_alloc_mlan_buffer);
+    ASSERT(pcb->moal_free_mlan_buffer);
+    ASSERT(pcb->moal_write_data_sync);
+    ASSERT(pcb->moal_read_data_sync);
+    ASSERT(pcb->moal_mfree);
+    ASSERT(pcb->moal_memcpy);
+    ASSERT(pcb->moal_memcmp);
+    ASSERT(pcb->moal_get_system_time);
+    ASSERT(pcb->moal_init_timer);
+    ASSERT(pcb->moal_free_timer);
+    ASSERT(pcb->moal_start_timer);
+    ASSERT(pcb->moal_stop_timer);
+    ASSERT(pcb->moal_init_lock);
+    ASSERT(pcb->moal_free_lock);
+    ASSERT(pcb->moal_spin_lock);
+    ASSERT(pcb->moal_spin_unlock);
+    ASSERT(pcb->moal_print);
+
+    ENTER();
+
+    /* Save pmoal_handle */
+    pmadapter->pmoal_handle = pmdevice->pmoal_handle;
+    /* card specific probing has been deferred until now .. */
+    if (MLAN_STATUS_SUCCESS != (ret = wlan_sdio_probe(pmadapter))) {
+        ret = MLAN_STATUS_FAILURE;
+        goto error;
+    }
+#ifdef MFG_CMD_SUPPORT
+    pmadapter->mfg_mode = pmdevice->mfg_mode;
+#endif
+
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        pmadapter->priv[i] = MNULL;
+        if (pmdevice->bss_attr[i].active == MTRUE) {
+            /* For valid bss_attr, allocate memory for private structure */
+            if ((pcb->moal_malloc(sizeof(mlan_private),
+                                  (t_u8 **) & pmadapter->priv[i]) !=
+                 MLAN_STATUS_SUCCESS)
+                || !pmadapter->priv[i]) {
+                ret = MLAN_STATUS_FAILURE;
+                goto error;
+            }
+
+            memset(pmadapter->priv[i], 0, sizeof(mlan_private));
+
+            pmadapter->priv[i]->adapter = pmadapter;
+
+            /* Save bss_type, frame_type & bss_priority */
+            pmadapter->priv[i]->bss_type =
+                (t_u8) pmdevice->bss_attr[i].bss_type;
+            pmadapter->priv[i]->frame_type =
+                (t_u8) pmdevice->bss_attr[i].frame_type;
+            pmadapter->priv[i]->bss_priority =
+                (t_u8) pmdevice->bss_attr[i].bss_priority;
+
+            /* Save bss_num */
+            pmadapter->priv[i]->bss_num = i;
+
+            /* init function table */
+            for (j = 0; j < (sizeof(ops) / sizeof(ops[0])); j++) {
+                if (ops[j].bss_type == pmadapter->priv[i]->bss_type) {
+                    memcpy(&pmadapter->priv[i]->ops, &ops[j],
+                           sizeof(mlan_operations));
+                }
+            }
+        }
+    }
+
+    /* Initialize locks */
+    if (pcb->moal_init_lock(&pmadapter->pmlan_lock)
+        != MLAN_STATUS_SUCCESS) {
+        ret = MLAN_STATUS_FAILURE;
+        goto error;
+    }
+
+    if (pcb->moal_init_lock(&pmadapter->pmain_proc_lock)
+        != MLAN_STATUS_SUCCESS) {
+        ret = MLAN_STATUS_FAILURE;
+        goto error;
+    }
+
+    if (pcb->moal_init_lock(&pmadapter->pmlan_cmd_lock)
+        != MLAN_STATUS_SUCCESS) {
+        ret = MLAN_STATUS_FAILURE;
+        goto error;
+    }
+    if (pcb->
+        moal_init_timer(&pmadapter->pmlan_cmd_timer, wlan_cmd_timeout_func,
+                        pmadapter)
+        != MLAN_STATUS_SUCCESS) {
+        ret = MLAN_STATUS_FAILURE;
+        goto error;
+    }
+    /* Return pointer of mlan_adapter to MOAL */
+    *ppmlan_adapter = pmadapter;
+
+    LEAVE();
+    goto exit_register;
+
+  error:
+    PRINTM(MINFO, "Leave mlan_register with error\n");
+    LEAVE();
+    /* Free resources */
+    if (pmadapter->pmlan_cmd_timer)
+        pcb->moal_free_timer(pmadapter->pmlan_cmd_timer);
+    if (pmadapter->pmlan_cmd_lock)
+        pcb->moal_free_lock(pmadapter->pmlan_cmd_lock);
+    if (pmadapter->pmain_proc_lock)
+        pcb->moal_free_lock(pmadapter->pmain_proc_lock);
+    if (pmadapter->pmlan_lock)
+        pcb->moal_free_lock(pmadapter->pmlan_lock);
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        if (pmadapter->priv[i])
+            pcb->moal_mfree((t_u8 *) pmadapter->priv[i]);
+    }
+    pcb->moal_mfree((t_u8 *) pmadapter);
+
+  exit_register:
+    return ret;
+}
+
+/**
+ *  @brief This function unregisters MOAL from MLAN module.
+ *  
+ *  @param pmlan_adapter   A pointer to a mlan_device structure
+ *                         allocated in MOAL
+ *
+ *  @return                MLAN_STATUS_SUCCESS
+ *                             The deregistration succeeded.
+ *                         MLAN_STATUS_FAILURE
+ *                             The deregistration failed.
+ */
+mlan_status
+mlan_unregister(IN t_void * pmlan_adapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
+    pmlan_callbacks pcb;
+    t_s32 i = 0;
+
+    ASSERT(pmlan_adapter);
+
+    ENTER();
+
+    pcb = &pmadapter->callbacks;
+
+    /* Free timers */
+    if (pmadapter->pmlan_cmd_timer)
+        pcb->moal_free_timer(pmadapter->pmlan_cmd_timer);
+
+    /* Free locks */
+    pcb->moal_free_lock(pmadapter->pmlan_cmd_lock);
+    pcb->moal_free_lock(pmadapter->pmain_proc_lock);
+    pcb->moal_free_lock(pmadapter->pmlan_lock);
+
+    /* Free private structures */
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        if (pmadapter->priv[i]) {
+            wlan_free_curr_bcn(pmadapter->priv[i]);
+            pcb->moal_free_lock(pmadapter->priv[i]->curr_bcn_buf_lock);
+            pcb->moal_mfree((t_u8 *) pmadapter->priv[i]);
+        }
+    }
+
+    LEAVE();
+    /* Free mlan_adapter */
+    pcb->moal_mfree((t_u8 *) pmadapter);
+
+    return ret;
+}
+
+/**
+ *  @brief This function downloads the firmware
+ *  
+ *  @param pmlan_adapter   A pointer to a t_void pointer to store
+ *                         mlan_adapter structure pointer
+ *  @param pmfw            A pointer to firmware image
+ *
+ *  @return                MLAN_STATUS_SUCCESS
+ *                             The firmware download succeeded.
+ *                         MLAN_STATUS_FAILURE
+ *                             The firmware download failed.
+ */
+mlan_status
+mlan_dnld_fw(IN t_void * pmlan_adapter, IN pmlan_fw_image pmfw)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
+    t_u32 poll_num = 1;
+
+    ENTER();
+    ASSERT(pmlan_adapter);
+
+    /* Check if firmware is already running */
+    ret = wlan_check_fw_status(pmadapter, poll_num);
+    if (ret == MLAN_STATUS_SUCCESS) {
+        PRINTM(MMSG, "WLAN FW already running! Skip FW download\n");
+        goto done;
+    }
+    poll_num = MAX_FIRMWARE_POLL_TRIES;
+
+    /* Check if other interface is downloading */
+    ret = wlan_check_winner_status(pmadapter);
+    if (ret == MLAN_STATUS_FAILURE) {
+        PRINTM(MMSG,
+               "WLAN winner interface already running! Skip FW download\n");
+        poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
+        goto poll_fw;
+    }
+    if (pmfw) {
+        /* Download helper/firmware */
+        ret = wlan_dnld_fw(pmadapter, pmfw);
+        if (ret != MLAN_STATUS_SUCCESS) {
+            PRINTM(MERROR, "wlan_dnld_fw fail ret=0x%x\n", ret);
+            LEAVE();
+            return ret;
+        }
+    }
+
+  poll_fw:
+    /* Check if the firmware is downloaded successfully or not */
+    ret = wlan_check_fw_status(pmadapter, poll_num);
+    if (ret != MLAN_STATUS_SUCCESS) {
+        PRINTM(MFATAL, "FW failed to be active in time!\n");
+        ret = MLAN_STATUS_FAILURE;
+        LEAVE();
+        return ret;
+    }
+  done:
+
+    /* re-enable host interrupt for mlan after fw dnld is successful */
+    wlan_enable_host_int(pmadapter);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function initializes the firmware
+ *  
+ *  @param pmlan_adapter   A pointer to a t_void pointer to store
+ *                         mlan_adapter structure pointer
+ *
+ *  @return                MLAN_STATUS_SUCCESS
+ *                             The firmware initialization succeeded.
+ *                         MLAN_STATUS_PENDING
+ *                             The firmware initialization is pending.
+ *                         MLAN_STATUS_FAILURE
+ *                             The firmware initialization failed.
+ */
+mlan_status
+mlan_init_fw(IN t_void * pmlan_adapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
+
+    ENTER();
+    ASSERT(pmlan_adapter);
+
+    pmadapter->hw_status = WlanHardwareStatusInitializing;
+
+    /* Initialize firmware, may return PENDING */
+    ret = wlan_init_fw(pmadapter);
+    PRINTM(MINFO, "wlan_init_fw returned ret=0x%x\n", ret);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Shutdown firmware
+ *
+ *  @param pmlan_adapter	A pointer to mlan_adapter structure
+ *
+ *  @return			MLAN_STATUS_SUCCESS
+ *                      		The firmware shutdown call succeeded.
+ *				MLAN_STATUS_PENDING
+ *      	                	The firmware shutdown call is pending.
+ *				MLAN_STATUS_FAILURE
+ *      	                	The firmware shutdown call failed.
+ */
+mlan_status
+mlan_shutdown_fw(IN t_void * pmlan_adapter)
+{
+    mlan_status ret = MLAN_STATUS_PENDING;
+    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
+    mlan_private *priv = MNULL;
+    pmlan_callbacks pcb;
+    t_s32 i = 0;
+
+    ENTER();
+    ASSERT(pmlan_adapter);
+    /* mlan already shutdown */
+    if (pmadapter->hw_status == WlanHardwareStatusNotReady)
+        return MLAN_STATUS_SUCCESS;
+
+    pmadapter->hw_status = WlanHardwareStatusClosing;
+    /* wait for mlan_process to complete */
+    if (pmadapter->mlan_processing) {
+        PRINTM(MWARN, "mlan main processing is still running\n");
+        return ret;
+    }
+
+    /* shut down mlan */
+    PRINTM(MINFO, "Shutdown mlan...\n");
+
+    pcb = &pmadapter->callbacks;
+    /* Clean up Tx/Rx queues and delete BSS priority table */
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        if (pmadapter->priv[i]) {
+            priv = pmadapter->priv[i];
+
+            wlan_clean_txrx(priv);
+            wlan_wmm_cleanup_node(priv);
+            pcb->moal_free_lock(priv->rx_pkt_lock);
+            wlan_delete_bsspriotbl(priv);
+            pcb->moal_free_lock(priv->wmm.ra_list_spinlock);
+        }
+    }
+
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++)
+        util_free_list_head(&pmadapter->bssprio_tbl[i].bssprio_head,
+                            pcb->moal_free_lock);
+
+    if (pcb->moal_spin_lock(pmadapter->pmlan_lock)
+        != MLAN_STATUS_SUCCESS) {
+        ret = MLAN_STATUS_FAILURE;
+        goto exit_shutdown_fw;
+    }
+
+    /* Free adapter structure */
+    wlan_free_adapter(pmadapter);
+
+    if (pcb->moal_spin_unlock(pmadapter->pmlan_lock)
+        != MLAN_STATUS_SUCCESS) {
+        ret = MLAN_STATUS_FAILURE;
+        goto exit_shutdown_fw;
+    }
+
+    /* Notify completion */
+    ret = wlan_shutdown_fw_complete(pmadapter);
+
+  exit_shutdown_fw:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief The main process
+ *
+ *  @param pmlan_adapter	A pointer to mlan_adapter structure
+ *
+ *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+mlan_main_process(IN t_void * pmlan_adapter)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
+    pmlan_callbacks pcb;
+
+    ENTER();
+
+    ASSERT(pmlan_adapter);
+
+    pcb = &pmadapter->callbacks;
+
+    pcb->moal_spin_lock(pmadapter->pmain_proc_lock);
+
+    /* Check if already processing */
+    if (pmadapter->mlan_processing) {
+        pcb->moal_spin_unlock(pmadapter->pmain_proc_lock);
+        goto exit_main_proc;
+    } else {
+        pmadapter->mlan_processing = MTRUE;
+        pcb->moal_spin_unlock(pmadapter->pmain_proc_lock);
+    }
+  process_start:
+    do {
+        /* Is MLAN shutting down or not ready? */
+        if ((pmadapter->hw_status == WlanHardwareStatusClosing) ||
+            (pmadapter->hw_status == WlanHardwareStatusNotReady))
+            break;
+
+        /* Handle pending SDIO interrupts if any */
+        if (pmadapter->sdio_ireg) {
+            if (pmadapter->hs_activated == MTRUE)
+                wlan_process_hs_config(pmadapter);
+            wlan_process_int_status(pmadapter);
+        }
+
+        /* Need to wake up the card ? */
+        if ((pmadapter->ps_state == PS_STATE_SLEEP) &&
+            (pmadapter->pm_wakeup_card_req &&
+             !pmadapter->pm_wakeup_fw_try) &&
+            (util_peek_list
+             (&pmadapter->cmd_pending_q, pcb->moal_spin_lock,
+              pcb->moal_spin_unlock)
+             || !wlan_wmm_lists_empty(pmadapter))) {
+            pmadapter->pm_wakeup_fw_try = MTRUE;
+            wlan_pm_wakeup_card(pmadapter);
+            continue;
+        }
+        if (IS_CARD_RX_RCVD(pmadapter)) {
+            pmadapter->pm_wakeup_fw_try = MFALSE;
+            if (pmadapter->ps_state == PS_STATE_SLEEP)
+                pmadapter->ps_state = PS_STATE_AWAKE;
+        } else {
+            /* We have tried to wakeup the card already */
+            if (pmadapter->pm_wakeup_fw_try)
+                break;
+            if (pmadapter->ps_state != PS_STATE_AWAKE ||
+                (pmadapter->tx_lock_flag == MTRUE))
+                break;
+
+            if (pmadapter->scan_processing || pmadapter->data_sent
+                || wlan_wmm_lists_empty(pmadapter)
+                ) {
+                if (pmadapter->cmd_sent || pmadapter->curr_cmd ||
+                    (!util_peek_list(&pmadapter->cmd_pending_q,
+                                     pcb->moal_spin_lock,
+                                     pcb->moal_spin_unlock))) {
+                    break;
+                }
+            }
+        }
+
+        /* Check for Cmd Resp */
+        if (pmadapter->cmd_resp_received) {
+            pmadapter->cmd_resp_received = MFALSE;
+            wlan_process_cmdresp(pmadapter);
+
+            /* call moal back when init_fw is done */
+            if (pmadapter->hw_status == WlanHardwareStatusInitdone) {
+                pmadapter->hw_status = WlanHardwareStatusReady;
+                wlan_init_fw_complete(pmadapter);
+            }
+        }
+
+        /* Check for event */
+        if (pmadapter->event_received) {
+            pmadapter->event_received = MFALSE;
+            wlan_process_event(pmadapter);
+        }
+
+        /* Check if we need to confirm Sleep Request received previously */
+        if (pmadapter->ps_state == PS_STATE_PRE_SLEEP) {
+
+            if (!pmadapter->cmd_sent && !pmadapter->curr_cmd) {
+                wlan_check_ps_cond(pmadapter);
+            }
+        }
+
+        /* 
+         * The ps_state may have been changed during processing of
+         * Sleep Request event.
+         */
+        if ((pmadapter->ps_state == PS_STATE_SLEEP)
+            || (pmadapter->ps_state == PS_STATE_PRE_SLEEP)
+            || (pmadapter->ps_state == PS_STATE_SLEEP_CFM)
+            || (pmadapter->tx_lock_flag == MTRUE)
+            )
+            continue;
+
+        if (!pmadapter->cmd_sent && !pmadapter->curr_cmd) {
+            if (wlan_exec_next_cmd(pmadapter) == MLAN_STATUS_FAILURE) {
+                ret = MLAN_STATUS_FAILURE;
+                break;
+            }
+        }
+
+        /* TODO: need to check tid eligibility for transfer to avoid dead loop */
+        if (!pmadapter->scan_processing && !pmadapter->data_sent &&
+            !wlan_wmm_lists_empty(pmadapter)) {
+            wlan_wmm_process_tx(pmadapter);
+            if (pmadapter->hs_activated == MTRUE) {
+                pmadapter->is_hs_configured = MFALSE;
+                wlan_host_sleep_activated_event(wlan_get_priv
+                                                (pmadapter, MLAN_BSS_TYPE_ANY),
+                                                MFALSE);
+            }
+        }
+
+        if (pmadapter->delay_null_pkt && !pmadapter->cmd_sent &&
+            !pmadapter->curr_cmd && !IS_COMMAND_PENDING(pmadapter) &&
+            wlan_wmm_lists_empty(pmadapter)) {
+            if (wlan_send_null_packet
+                (wlan_get_priv(pmadapter, MLAN_BSS_TYPE_STA),
+                 MRVDRV_TxPD_POWER_MGMT_NULL_PACKET |
+                 MRVDRV_TxPD_POWER_MGMT_LAST_PACKET)
+                == MLAN_STATUS_SUCCESS) {
+                pmadapter->delay_null_pkt = MFALSE;
+            }
+            break;
+        }
+
+    } while (MTRUE);
+
+    pcb->moal_spin_lock(pmadapter->pmain_proc_lock);
+    if ((pmadapter->sdio_ireg) || IS_CARD_RX_RCVD(pmadapter)) {
+        pcb->moal_spin_unlock(pmadapter->pmain_proc_lock);
+        goto process_start;
+    }
+    pmadapter->mlan_processing = MFALSE;
+    pcb->moal_spin_unlock(pmadapter->pmain_proc_lock);
+
+  exit_main_proc:
+    if (pmadapter->hw_status == WlanHardwareStatusClosing)
+        mlan_shutdown_fw(pmadapter);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Function to send packet
+ *
+ *  @param pmlan_adapter	A pointer to mlan_adapter structure
+ *  @param pmbuf		A pointer to mlan_buffer structure
+ *
+ *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+mlan_send_packet(IN t_void * pmlan_adapter, IN pmlan_buffer pmbuf)
+{
+    mlan_status ret = MLAN_STATUS_PENDING;
+    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
+
+    ENTER();
+    ASSERT(pmlan_adapter && pmbuf);
+
+    ASSERT(pmbuf->bss_num < MLAN_MAX_BSS_NUM);
+
+    {
+        /* Transmit the packet */
+        wlan_wmm_add_buf_txqueue(pmadapter, pmbuf);
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief MLAN ioctl handler
+ *
+ *  @param adapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+mlan_status
+mlan_ioctl(IN t_void * adapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_adapter pmadapter = (pmlan_adapter) adapter;
+    pmlan_private pmpriv = MNULL;
+
+    ENTER();
+
+    if (pioctl_req == MNULL) {
+        PRINTM(MERROR, "MLAN IOCTL information buffer is NULL\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+    if (pioctl_req->action == MLAN_ACT_CANCEL) {
+        wlan_cancel_pending_ioctl(pmadapter, pioctl_req);
+        ret = MLAN_STATUS_SUCCESS;
+        goto exit;
+    }
+    pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    ret = pmpriv->ops.ioctl(adapter, pioctl_req);
+  exit:
+    LEAVE();
+    return ret;
+}
diff --git a/wlan_src/mlan/mlan_sta_cmd.c b/wlan_src/mlan/mlan_sta_cmd.c
new file mode 100755
index 0000000..ce8d23d
--- /dev/null
+++ b/wlan_src/mlan/mlan_sta_cmd.c
@@ -0,0 +1,1839 @@
+/** @file mlan_sta_cmd.c
+ *  
+ *  @brief This file contains the handling of command.
+ *  it prepares command and sends it to firmware when
+ *  it is ready.
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ * 
+ */
+
+/******************************************************
+Change log:
+    10/21/2008: initial version
+******************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_11h.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+                Local Variables
+********************************************************/
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+/** 
+ *  @brief This function prepares command of get_hw_spec.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pcmd         A pointer to HostCmd_DS_COMMAND structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_get_hw_spec(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND * pcmd)
+{
+    HostCmd_DS_GET_HW_SPEC *hw_spec = &pcmd->params.hw_spec;
+
+    ENTER();
+
+    pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_GET_HW_SPEC);
+    pcmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_GET_HW_SPEC) + S_DS_GEN);
+    memcpy(hw_spec->permanent_addr, pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of RSSI info.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pcmd         A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   Command action
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_rssi_info(IN pmlan_private pmpriv,
+                          IN HostCmd_DS_COMMAND * pcmd, IN t_u16 cmd_action)
+{
+    ENTER();
+
+    pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_RSSI_INFO);
+    pcmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RSSI_INFO) + S_DS_GEN);
+    pcmd->params.rssi_info.action = wlan_cpu_to_le16(cmd_action);
+    pcmd->params.rssi_info.ndata = wlan_cpu_to_le16(pmpriv->data_avg_factor);
+    pcmd->params.rssi_info.nbcn = wlan_cpu_to_le16(pmpriv->bcn_avg_factor);
+
+    /* Reset SNR/NF/RSSI values in private structure */
+    pmpriv->data_rssi_last = 0;
+    pmpriv->data_nf_last = 0;
+    pmpriv->data_rssi_avg = 0;
+    pmpriv->data_nf_avg = 0;
+    pmpriv->bcn_rssi_last = 0;
+    pmpriv->bcn_nf_last = 0;
+    pmpriv->bcn_rssi_avg = 0;
+    pmpriv->bcn_nf_avg = 0;
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of mac_control.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pcmd         A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   Command action
+ *  @param pdata_buf    A pointer to command information buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_mac_control(IN pmlan_private pmpriv,
+                     IN HostCmd_DS_COMMAND * pcmd,
+                     IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    HostCmd_DS_MAC_CONTROL *pmac = &pcmd->params.mac_ctrl;
+    t_u16 action = *((t_u16 *) pdata_buf);
+
+    ENTER();
+
+    if (cmd_action != HostCmd_ACT_GEN_SET) {
+        PRINTM(MERROR, "wlan_cmd_mac_control(): support SET only.\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    pcmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
+    pcmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_CONTROL) + S_DS_GEN);
+    pmac->action = wlan_cpu_to_le16(action);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of snmp_mib.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param cmd_oid      OID: ENABLE or DISABLE
+ *  @param pdata_buf    A pointer to command information buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_snmp_mib(IN pmlan_private pmpriv,
+                         IN HostCmd_DS_COMMAND * cmd,
+                         IN t_u16 cmd_action,
+                         IN t_u32 cmd_oid, IN t_void * pdata_buf)
+{
+    HostCmd_DS_802_11_SNMP_MIB *psnmp_mib = &cmd->params.smib;
+    t_u32 ul_temp;
+
+    ENTER();
+    PRINTM(MCMND, "SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
+    cmd->size = sizeof(HostCmd_DS_802_11_SNMP_MIB) - 1 + S_DS_GEN;
+
+    if (cmd_action == HostCmd_ACT_GEN_GET) {
+        psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_GET);
+        psnmp_mib->buf_size = wlan_cpu_to_le16(MAX_SNMP_BUF_SIZE);
+        cmd->size += MAX_SNMP_BUF_SIZE;
+    }
+
+    switch (cmd_oid) {
+    case FragThresh_i:
+        psnmp_mib->oid = wlan_cpu_to_le16((t_u16) FragThresh_i);
+        if (cmd_action == HostCmd_ACT_GEN_SET) {
+            psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+            psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+            ul_temp = *((t_u32 *) pdata_buf);
+            *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+            cmd->size += sizeof(t_u16);
+        }
+        break;
+    case RtsThresh_i:
+        psnmp_mib->oid = wlan_cpu_to_le16((t_u16) RtsThresh_i);
+        if (cmd_action == HostCmd_ACT_GEN_SET) {
+            psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+            psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+            ul_temp = *((t_u32 *) pdata_buf);
+            *(t_u16 *) (psnmp_mib->value) = wlan_cpu_to_le16((t_u16) ul_temp);
+            cmd->size += sizeof(t_u16);
+        }
+        break;
+
+    case ShortRetryLim_i:
+        psnmp_mib->oid = wlan_cpu_to_le16((t_u16) ShortRetryLim_i);
+        if (cmd_action == HostCmd_ACT_GEN_SET) {
+            psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+            psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+            ul_temp = (*(t_u32 *) pdata_buf);
+            *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+            cmd->size += sizeof(t_u16);
+        }
+        break;
+    case Dot11D_i:
+        psnmp_mib->oid = wlan_cpu_to_le16((t_u16) Dot11D_i);
+        if (cmd_action == HostCmd_ACT_GEN_SET) {
+            psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+            psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+            ul_temp = *(t_u32 *) pdata_buf;
+            *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+            cmd->size += sizeof(t_u16);
+        }
+        break;
+    case Dot11H_i:
+        psnmp_mib->oid = wlan_cpu_to_le16((t_u16) Dot11H_i);
+        if (cmd_action == HostCmd_ACT_GEN_SET) {
+            psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+            psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+            ul_temp = *(t_u32 *) pdata_buf;
+            *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+            cmd->size += sizeof(t_u16);
+        }
+        break;
+    case WwsMode_i:
+        psnmp_mib->oid = wlan_cpu_to_le16((t_u16) WwsMode_i);
+        if (cmd_action == HostCmd_ACT_GEN_SET) {
+            psnmp_mib->query_type = wlan_cpu_to_le16(HostCmd_ACT_GEN_SET);
+            psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u16));
+            ul_temp = *((t_u32 *) pdata_buf);
+            *((t_u16 *) (psnmp_mib->value)) = wlan_cpu_to_le16((t_u16) ul_temp);
+            cmd->size += sizeof(t_u16);
+        }
+        break;
+
+    default:
+        break;
+    }
+    cmd->size = wlan_cpu_to_le16(cmd->size);
+    PRINTM(MCMND, "SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x, Value=0x%x\n",
+           cmd_action, cmd_oid, wlan_le16_to_cpu(psnmp_mib->buf_size),
+           wlan_le16_to_cpu(*(t_u16 *) psnmp_mib->value));
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of get_log.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_get_log(IN pmlan_private pmpriv, IN HostCmd_DS_COMMAND * cmd)
+{
+    ENTER();
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_GET_LOG) + S_DS_GEN);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of radio_control.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_radio_control(IN pmlan_private pmpriv,
+                              IN HostCmd_DS_COMMAND * cmd, IN t_u16 cmd_action)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    HostCmd_DS_802_11_RADIO_CONTROL *pradio_control = &cmd->params.radio;
+
+    ENTER();
+    cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_RADIO_CONTROL))
+                                 + S_DS_GEN);
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RADIO_CONTROL);
+    pradio_control->action = wlan_cpu_to_le16(cmd_action);
+    pradio_control->control = wlan_cpu_to_le16(pmadapter->radio_on);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of tx_rate_cfg.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_tx_rate_cfg(IN pmlan_private pmpriv,
+                     IN HostCmd_DS_COMMAND * cmd,
+                     IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    HostCmd_DS_TX_RATE_CFG *rate_cfg = &cmd->params.tx_rate_cfg;
+    MrvlRateScope_t *rate_scope;
+    MrvlRateDropPattern_t *rate_drop;
+    t_u16 *pbitmap_rates = (t_u16 *) pdata_buf;
+
+    t_u32 i;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TX_RATE_CFG);
+
+    rate_cfg->action = wlan_cpu_to_le16(cmd_action);
+    rate_cfg->cfg_index = 0;
+
+    rate_scope = (MrvlRateScope_t *) ((t_u8 *) rate_cfg +
+                                      sizeof(HostCmd_DS_TX_RATE_CFG));
+    rate_scope->type = wlan_cpu_to_le16(TLV_TYPE_RATE_SCOPE);
+    rate_scope->length = wlan_cpu_to_le16(sizeof(MrvlRateScope_t) -
+                                          sizeof(MrvlIEtypesHeader_t));
+    if (pbitmap_rates != MNULL) {
+        rate_scope->hr_dsss_rate_bitmap = wlan_cpu_to_le16(pbitmap_rates[0]);
+        rate_scope->ofdm_rate_bitmap = wlan_cpu_to_le16(pbitmap_rates[1]);
+        for (i = 0; i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(t_u16);
+             i++)
+            rate_scope->ht_mcs_rate_bitmap[i] =
+                wlan_cpu_to_le16(pbitmap_rates[2 + i]);
+    } else {
+        rate_scope->hr_dsss_rate_bitmap =
+            wlan_cpu_to_le16(pmpriv->bitmap_rates[0]);
+        rate_scope->ofdm_rate_bitmap =
+            wlan_cpu_to_le16(pmpriv->bitmap_rates[1]);
+        for (i = 0; i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(t_u16);
+             i++)
+            rate_scope->ht_mcs_rate_bitmap[i] =
+                wlan_cpu_to_le16(pmpriv->bitmap_rates[2 + i]);
+    }
+
+    rate_drop = (MrvlRateDropPattern_t *) ((t_u8 *) rate_scope +
+                                           sizeof(MrvlRateScope_t));
+    rate_drop->type = wlan_cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL);
+    rate_drop->length = wlan_cpu_to_le16(sizeof(rate_drop->rate_drop_mode));
+    rate_drop->rate_drop_mode = 0;
+
+    cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TX_RATE_CFG) +
+                                 sizeof(MrvlRateScope_t) +
+                                 sizeof(MrvlRateDropPattern_t));
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of tx_power_cfg.
+ *   
+ *  @param pmpriv      A pointer to mlan_private structure
+ *  @param cmd         A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action  The action: GET or SET
+ *  @param pdata_buf   A pointer to data buffer
+ *
+ *  @return            MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_tx_power_cfg(IN pmlan_private pmpriv,
+                      IN HostCmd_DS_COMMAND * cmd,
+                      IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    MrvlTypes_Power_Group_t *ppg_tlv = MNULL;
+    HostCmd_DS_TXPWR_CFG *ptxp = MNULL;
+    HostCmd_DS_TXPWR_CFG *ptxp_cfg = &cmd->params.txp_cfg;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_TXPWR_CFG);
+    cmd->size = wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_TXPWR_CFG));
+    switch (cmd_action) {
+    case HostCmd_ACT_GEN_SET:
+        ptxp = (HostCmd_DS_TXPWR_CFG *) pdata_buf;
+        if (ptxp->mode) {
+            ppg_tlv =
+                (MrvlTypes_Power_Group_t *) ((t_u32) pdata_buf +
+                                             sizeof(HostCmd_DS_TXPWR_CFG));
+            memmove(ptxp_cfg, pdata_buf,
+                    sizeof(HostCmd_DS_TXPWR_CFG) +
+                    sizeof(MrvlTypes_Power_Group_t) + ppg_tlv->length);
+
+            ppg_tlv = (MrvlTypes_Power_Group_t *) ((t_u8 *) ptxp_cfg +
+                                                   sizeof
+                                                   (HostCmd_DS_TXPWR_CFG));
+            cmd->size +=
+                wlan_cpu_to_le16(sizeof(MrvlTypes_Power_Group_t) +
+                                 ppg_tlv->length);
+            ppg_tlv->type = wlan_cpu_to_le16(ppg_tlv->type);
+            ppg_tlv->length = wlan_cpu_to_le16(ppg_tlv->length);
+        } else {
+            memmove(ptxp_cfg, pdata_buf, sizeof(HostCmd_DS_TXPWR_CFG));
+        }
+        ptxp_cfg->action = wlan_cpu_to_le16(cmd_action);
+        ptxp_cfg->cfg_index = wlan_cpu_to_le16(ptxp_cfg->cfg_index);
+        ptxp_cfg->mode = wlan_cpu_to_le32(ptxp_cfg->mode);
+        break;
+    case HostCmd_ACT_GEN_GET:
+        ptxp_cfg->action = wlan_cpu_to_le16(cmd_action);
+        break;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ * @brief This function prepares command of enhanced ps_mode.
+ *   
+ * @param pmpriv       A pointer to mlan_private structure
+ * @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action   The action: GET or SET
+ * @param pdata_buf    A pointer to data buffer
+ *
+ * @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_opt_ps_mode(IN pmlan_private pmpriv,
+                            IN HostCmd_DS_COMMAND * cmd,
+                            IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    pmlan_adapter pmadapter = pmpriv->adapter;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
+    cmd->size =
+        wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_802_11_PS_MODE_ENH));
+    ((HostCmd_DS_802_11_PS_MODE_ENH *) (&cmd->params.psmode_enh))->action =
+        wlan_cpu_to_le16(cmd_action);
+
+    switch (cmd_action) {
+    case EN_PS:
+        {
+            ps_param *pps_mode = &cmd->params.psmode_enh.params.opt_ps;
+            PRINTM(MCMND, "PS Command: Enter PS\n");
+
+            pps_mode->null_pkt_interval =
+                wlan_cpu_to_le16(pmadapter->null_pkt_interval);
+            pps_mode->multiple_dtims =
+                wlan_cpu_to_le16(pmadapter->multiple_dtim);
+            pps_mode->bcn_miss_timeout =
+                wlan_cpu_to_le16(pmadapter->bcn_miss_time_out);
+            pps_mode->local_listen_interval =
+                wlan_cpu_to_le16(pmadapter->local_listen_interval);
+            pps_mode->adhoc_wake_period =
+                wlan_cpu_to_le16(pmadapter->adhoc_awake_period);
+            pps_mode->delay_to_ps = wlan_cpu_to_le16(pmadapter->delay_to_ps);
+            pps_mode->mode = wlan_cpu_to_le16(pmadapter->enhanced_ps_mode);
+            break;
+        }
+    case DIS_PS:
+        PRINTM(MCMND, "PS Command: Exit PS\n");
+        break;
+    case EN_AUTO_DS:
+        {
+            t_u16 idletime = 0;
+            auto_ds_param *pps_mode = &cmd->params.psmode_enh.params.auto_ds;
+            if (pdata_buf) {
+                idletime = ((mlan_ds_auto_ds *) pdata_buf)->idletime;
+            }
+
+            PRINTM(MCMND, "PS Command: Enter Auto Deep Sleep\n");
+            pps_mode->deep_sleep_timeout = wlan_cpu_to_le16(idletime);
+            break;
+        }
+    case DIS_AUTO_DS:
+        PRINTM(MCMND, "PS Command: Exit Auto Deep Sleep\n");
+        break;
+    case SLEEP_CONFIRM:
+        {
+            sleep_confirm_param *pps_mode =
+                &cmd->params.psmode_enh.params.sleep_cfm;
+            PRINTM(MCMND, "PS Command: Sleep Confirm\n");
+
+            pps_mode->resp_ctrl = wlan_cpu_to_le16(RESP_NEEDED);
+            break;
+        }
+    default:
+        break;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ * @brief This function prepares command of hs_cfg.
+ *   
+ * @param pmpriv       A pointer to mlan_private structure
+ * @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action   The action: GET or SET
+ * @param pdata_buf    A pointer to data buffer
+ *
+ * @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_hs_cfg(IN pmlan_private pmpriv,
+                       IN HostCmd_DS_COMMAND * cmd,
+                       IN t_u16 cmd_action,
+                       IN HostCmd_DS_802_11_HS_CFG_ENH * pdata_buf)
+{
+    pmlan_adapter pmadapter = pmpriv->adapter;
+    HostCmd_DS_802_11_HS_CFG_ENH *phs_cfg = &cmd->params.opt_hs_cfg;
+    t_u16 hs_activate = MFALSE;
+
+    ENTER();
+
+    if (pdata_buf == MNULL) {
+        /* New Activate command */
+        hs_activate = MTRUE;
+    }
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
+
+    if (!hs_activate &&
+        (pdata_buf->params.hs_config.conditions != HOST_SLEEP_CFG_CANCEL)
+        && ((pmadapter->arp_filter_size > 0)
+            && (pmadapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
+        PRINTM(MCMND, "Attach %d bytes ArpFilter to HSCfg cmd\n",
+               pmadapter->arp_filter_size);
+        memcpy(((t_u8 *) phs_cfg) + sizeof(HostCmd_DS_802_11_HS_CFG_ENH),
+               pmadapter->arp_filter, pmadapter->arp_filter_size);
+        cmd->size =
+            (t_u16) wlan_cpu_to_le16(pmadapter->arp_filter_size +
+                                     sizeof(HostCmd_DS_802_11_HS_CFG_ENH) +
+                                     S_DS_GEN);
+    } else
+        cmd->size =
+            wlan_cpu_to_le16(S_DS_GEN + sizeof(HostCmd_DS_802_11_HS_CFG_ENH));
+
+    if (hs_activate) {
+        phs_cfg->action = HS_ACTIVATE;
+        phs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED;
+    } else {
+        phs_cfg->action = HS_CONFIGURE;
+        phs_cfg->params.hs_config.conditions =
+            wlan_cpu_to_le32(pdata_buf->params.hs_config.conditions);
+        phs_cfg->params.hs_config.gpio = pdata_buf->params.hs_config.gpio;
+        phs_cfg->params.hs_config.gap = pdata_buf->params.hs_config.gap;
+        PRINTM(MCMND, "HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n",
+               phs_cfg->params.hs_config.conditions,
+               phs_cfg->params.hs_config.gpio, phs_cfg->params.hs_config.gap);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of mac_address.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_mac_address(IN pmlan_private pmpriv,
+                            IN HostCmd_DS_COMMAND * cmd, IN t_u16 cmd_action)
+{
+    ENTER();
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_MAC_ADDRESS) +
+                                 S_DS_GEN);
+    cmd->result = 0;
+
+    cmd->params.mac_addr.action = wlan_cpu_to_le16(cmd_action);
+
+    if (cmd_action == HostCmd_ACT_GEN_SET) {
+        memcpy(cmd->params.mac_addr.mac_addr, pmpriv->curr_addr,
+               MLAN_MAC_ADDR_LENGTH);
+        // HEXDUMP("SET_CMD: MAC ADDRESS-", priv->CurrentAddr, 6);
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of sleep_period.
+ *
+ * @param pmpriv       A pointer to mlan_private structure
+ * @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action   The action: GET or SET
+ * @param pdata_buf    A pointer to data buffer
+ *
+ * @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_sleep_period(IN pmlan_private pmpriv,
+                             IN HostCmd_DS_COMMAND * cmd,
+                             IN t_u16 cmd_action, IN t_u16 * pdata_buf)
+{
+    HostCmd_DS_802_11_SLEEP_PERIOD *pcmd_sleep_pd = &cmd->params.sleep_pd;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SLEEP_PERIOD);
+    cmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SLEEP_PERIOD) + S_DS_GEN);
+    if (cmd_action == HostCmd_ACT_GEN_SET) {
+        pcmd_sleep_pd->sleep_pd = wlan_cpu_to_le16(*(t_u16 *) pdata_buf);
+    }
+    pcmd_sleep_pd->action = wlan_cpu_to_le16(cmd_action);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function prepares command of sleep_params.
+ *
+ * @param pmpriv       A pointer to mlan_private structure
+ * @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ * @param cmd_action   The action: GET or SET
+ * @param pdata_buf    A pointer to data buffer
+ *
+ * @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_sleep_params(IN pmlan_private pmpriv,
+                             IN HostCmd_DS_COMMAND * cmd,
+                             IN t_u16 cmd_action, IN t_u16 * pdata_buf)
+{
+    HostCmd_DS_802_11_SLEEP_PARAMS *pcmd_sp = &cmd->params.sleep_param;
+    mlan_ds_sleep_params *psp = (mlan_ds_sleep_params *) pdata_buf;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_SLEEP_PARAMS);
+    cmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SLEEP_PARAMS) + S_DS_GEN);
+    if (cmd_action == HostCmd_ACT_GEN_SET) {
+        pcmd_sp->reserved = (t_u16) psp->reserved;
+        pcmd_sp->error = (t_u16) psp->error;
+        pcmd_sp->offset = (t_u16) psp->offset;
+        pcmd_sp->stable_time = (t_u16) psp->stable_time;
+        pcmd_sp->cal_control = (t_u8) psp->cal_control;
+        pcmd_sp->external_sleep_clk = (t_u8) psp->ext_sleep_clk;
+
+        pcmd_sp->reserved = wlan_cpu_to_le16(pcmd_sp->reserved);
+        pcmd_sp->error = wlan_cpu_to_le16(pcmd_sp->error);
+        pcmd_sp->offset = wlan_cpu_to_le16(pcmd_sp->offset);
+        pcmd_sp->stable_time = wlan_cpu_to_le16(pcmd_sp->stable_time);
+    }
+    pcmd_sp->action = wlan_cpu_to_le16(cmd_action);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of mac_multicast_adr.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_mac_multicast_adr(IN pmlan_private pmpriv,
+                           IN HostCmd_DS_COMMAND * cmd,
+                           IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    mlan_multicast_list *pmcast_list = (mlan_multicast_list *) pdata_buf;
+    HostCmd_DS_MAC_MULTICAST_ADR *pmc_addr = &cmd->params.mc_addr;
+
+    ENTER();
+    cmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_MULTICAST_ADR) + S_DS_GEN);
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR);
+
+    pmc_addr->action = wlan_cpu_to_le16(cmd_action);
+    pmc_addr->num_of_adrs =
+        wlan_cpu_to_le16((t_u16) pmcast_list->num_multicast_addr);
+    memcpy(pmc_addr->mac_list, pmcast_list->mac_list,
+           pmcast_list->num_multicast_addr * MLAN_MAC_ADDR_LENGTH);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function prepares command of deauthenticate.
+ *
+ * @param pmpriv       A pointer to mlan_private structure
+ * @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ * @param pdata_buf    A pointer to data buffer
+ *
+ * @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_cmd_802_11_deauthenticate(IN pmlan_private pmpriv,
+                               IN HostCmd_DS_COMMAND * cmd,
+                               IN t_void * pdata_buf)
+{
+    HostCmd_DS_802_11_DEAUTHENTICATE *pdeauth = &cmd->params.deauth;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE);
+    cmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_DEAUTHENTICATE) + S_DS_GEN);
+
+    /* Set AP MAC address */
+    memcpy(pdeauth->mac_addr, (t_u8 *) pdata_buf, MLAN_MAC_ADDR_LENGTH);
+
+    PRINTM(MCMND, "Deauth: %02x:%02x:%02x:%02x:%02x:%02x\n",
+           pdeauth->mac_addr[0], pdeauth->mac_addr[1], pdeauth->mac_addr[2],
+           pdeauth->mac_addr[3], pdeauth->mac_addr[4], pdeauth->mac_addr[5]);
+
+/** Reason code 3 = Station is leaving */
+#define REASON_CODE_STA_LEAVING 3
+    pdeauth->reason_code = wlan_cpu_to_le16(REASON_CODE_STA_LEAVING);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function prepares command of ad_hoc_stop.
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_cmd_802_11_ad_hoc_stop(IN pmlan_private pmpriv,
+                            IN HostCmd_DS_COMMAND * cmd)
+{
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP);
+    cmd->size = wlan_cpu_to_le16(S_DS_GEN);
+
+    if (wlan_11h_is_active(pmpriv))
+        wlan_11h_activate(pmpriv, MFALSE);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** Length of WEP 40 bit key */
+#define WEP_40_BIT_LEN  5
+/** Length of WEP 104 bit key */
+#define WEP_104_BIT_LEN 13
+
+/** 
+ *  @brief This function sets WEP key(s) to key_param_set TLV(s).
+ *  
+ *  @param priv           	A pointer to mlan_private structure
+ *  @param key_param_set    A pointer to MrvlIEtype_KeyParamSet_t structure
+ *  @param key_param_len    A pointer to the length variable
+ *
+ *  @return                 MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_set_keyparamset_wep(mlan_private * priv,
+                         MrvlIEtype_KeyParamSet_t * key_param_set,
+                         t_u16 * key_param_len)
+{
+    int cur_key_param_len = 0;
+    t_u8 i;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* Multi-key_param_set TLV is supported */
+    for (i = 0; i < MRVL_NUM_WEP_KEY; i++) {
+        if ((priv->wep_key[i].key_length == WEP_40_BIT_LEN) ||
+            (priv->wep_key[i].key_length == WEP_104_BIT_LEN)) {
+            key_param_set->type = wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+/** Key_param_set WEP fixed length */
+#define KEYPARAMSET_WEP_FIXED_LEN 8
+            key_param_set->length =
+                wlan_cpu_to_le16((t_u16)
+                                 (priv->wep_key[i].key_length +
+                                  KEYPARAMSET_WEP_FIXED_LEN));
+            key_param_set->key_type_id = wlan_cpu_to_le16(KEY_TYPE_ID_WEP);
+            key_param_set->key_info = wlan_cpu_to_le16
+                (KEY_INFO_WEP_ENABLED | KEY_INFO_WEP_UNICAST |
+                 KEY_INFO_WEP_MCAST);
+            key_param_set->key_len =
+                (t_u16) wlan_cpu_to_le16(priv->wep_key[i].key_length);
+            /* Set WEP key index */
+            key_param_set->key[0] = i;
+            /* Set default Tx key flag */
+            if (i == (priv->wep_key_curr_index & HostCmd_WEP_KEY_INDEX_MASK))
+                key_param_set->key[1] = 1;
+            else
+                key_param_set->key[1] = 0;
+            memmove(&key_param_set->key[2], priv->wep_key[i].key_material,
+                    priv->wep_key[i].key_length);
+
+            cur_key_param_len = priv->wep_key[i].key_length +
+                KEYPARAMSET_WEP_FIXED_LEN + sizeof(MrvlIEtypesHeader_t);
+            *key_param_len += (t_u16) cur_key_param_len;
+            key_param_set =
+                (MrvlIEtype_KeyParamSet_t *) ((t_u8 *) key_param_set +
+                                              cur_key_param_len);
+        } else if (!priv->wep_key[i].key_length) {
+            continue;
+        } else {
+            PRINTM(MERROR, "key%d Length = %d is incorrect\n", (i + 1),
+                   priv->wep_key[i].key_length);
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+    }
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function prepares command of key_material.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param cmd_oid      OID: ENABLE or DISABLE
+ *  @param pdata_buf    A pointer to data buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_802_11_key_material(IN pmlan_private pmpriv,
+                             IN HostCmd_DS_COMMAND * cmd,
+                             IN t_u16 cmd_action,
+                             IN t_u32 cmd_oid, IN t_void * pdata_buf)
+{
+    HostCmd_DS_802_11_KEY_MATERIAL *pkey_material = &cmd->params.key_material;
+    mlan_ds_encrypt_key *pkey = (mlan_ds_encrypt_key *) pdata_buf;
+    t_u16 key_param_len = 0;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    const t_u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
+    pkey_material->action = wlan_cpu_to_le16(cmd_action);
+
+    if (cmd_action == HostCmd_ACT_GEN_GET) {
+        cmd->size = wlan_cpu_to_le16(sizeof(pkey_material->action) + S_DS_GEN);
+        goto done;
+    }
+
+    if (!pkey) {
+        memset(&pkey_material->key_param_set, 0,
+               (MRVL_NUM_WEP_KEY * sizeof(MrvlIEtype_KeyParamSet_t)));
+        ret =
+            wlan_set_keyparamset_wep(pmpriv, &pkey_material->key_param_set,
+                                     &key_param_len);
+        cmd->size =
+            wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
+                             S_DS_GEN);
+        goto done;
+    } else
+        memset(&pkey_material->key_param_set, 0,
+               sizeof(MrvlIEtype_KeyParamSet_t));
+    if (pkey->is_wapi_key) {
+        PRINTM(MINFO, "Set WAPI Key\n");
+        pkey_material->key_param_set.key_type_id =
+            wlan_cpu_to_le16(KEY_TYPE_ID_WAPI);
+        if (cmd_oid == KEY_INFO_ENABLED)
+            pkey_material->key_param_set.key_info =
+                wlan_cpu_to_le16(KEY_INFO_WAPI_ENABLED);
+        else
+            pkey_material->key_param_set.key_info =
+                !(wlan_cpu_to_le16(KEY_INFO_WAPI_ENABLED));
+
+        pkey_material->key_param_set.key[0] = pkey->key_index;
+        if (!pmpriv->sec_info.wapi_key_on)
+            pkey_material->key_param_set.key[1] = 1;
+        else
+            pkey_material->key_param_set.key[1] = 0;    /* set 0 when re-key */
+
+        if (0 != memcmp(pkey->mac_addr, bc_mac, sizeof(bc_mac)))        /* WAPI 
+                                                                           pairwise 
+                                                                           key: 
+                                                                           unicast 
+                                                                         */
+            pkey_material->key_param_set.key_info |=
+                wlan_cpu_to_le16(KEY_INFO_WAPI_UNICAST);
+        else {                  /* WAPI group key: multicast */
+            pkey_material->key_param_set.key_info |=
+                wlan_cpu_to_le16(KEY_INFO_WAPI_MCAST);
+            pmpriv->sec_info.wapi_key_on = MTRUE;
+        }
+
+        pkey_material->key_param_set.type =
+            wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+        pkey_material->key_param_set.key_len = wlan_cpu_to_le16(WAPI_KEY_LEN);
+        memcpy(&pkey_material->key_param_set.key[2], pkey->key_material,
+               pkey->key_len);
+        memcpy(&pkey_material->key_param_set.key[2 + pkey->key_len], pkey->pn,
+               PN_SIZE);
+        pkey_material->key_param_set.length =
+            wlan_cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
+
+        key_param_len =
+            (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
+            sizeof(MrvlIEtypesHeader_t);
+        cmd->size =
+            wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
+                             S_DS_GEN);
+        goto done;
+    }
+    if (pkey->key_len == WPA_AES_KEY_LEN) {
+        PRINTM(MCMND, "WPA_AES\n");
+        pkey_material->key_param_set.key_type_id =
+            wlan_cpu_to_le16(KEY_TYPE_ID_AES);
+        if (cmd_oid == KEY_INFO_ENABLED)
+            pkey_material->key_param_set.key_info =
+                wlan_cpu_to_le16(KEY_INFO_AES_ENABLED);
+        else
+            pkey_material->key_param_set.key_info =
+                !(wlan_cpu_to_le16(KEY_INFO_AES_ENABLED));
+
+        if (pkey->key_index & 0x40000000)       /* AES pairwise key: unicast */
+            pkey_material->key_param_set.key_info |=
+                wlan_cpu_to_le16(KEY_INFO_AES_UNICAST);
+        else                    /* AES group key: multicast */
+            pkey_material->key_param_set.key_info |=
+                wlan_cpu_to_le16(KEY_INFO_AES_MCAST);
+    } else if (pkey->key_len == WPA_TKIP_KEY_LEN) {
+        PRINTM(MCMND, "WPA_TKIP\n");
+        pkey_material->key_param_set.key_type_id =
+            wlan_cpu_to_le16(KEY_TYPE_ID_TKIP);
+        pkey_material->key_param_set.key_info =
+            wlan_cpu_to_le16(KEY_INFO_TKIP_ENABLED);
+
+        if (pkey->key_index & 0x40000000)       /* TKIP pairwise key: unicast */
+            pkey_material->key_param_set.key_info |=
+                wlan_cpu_to_le16(KEY_INFO_TKIP_UNICAST);
+        else                    /* TKIP group key: multicast */
+            pkey_material->key_param_set.key_info |=
+                wlan_cpu_to_le16(KEY_INFO_TKIP_MCAST);
+    }
+
+    if (pkey_material->key_param_set.key_type_id) {
+        pkey_material->key_param_set.type =
+            wlan_cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+        pkey_material->key_param_set.key_len =
+            wlan_cpu_to_le16((t_u16) pkey->key_len);
+        memcpy(pkey_material->key_param_set.key, pkey->key_material,
+               pkey->key_len);
+        pkey_material->key_param_set.length =
+            wlan_cpu_to_le16((t_u16) pkey->key_len + KEYPARAMSET_FIXED_LEN);
+
+        key_param_len =
+            (t_u16) (pkey->key_len + KEYPARAMSET_FIXED_LEN) +
+            sizeof(MrvlIEtypesHeader_t);
+
+        cmd->size =
+            wlan_cpu_to_le16(key_param_len + sizeof(pkey_material->action) +
+                             S_DS_GEN);
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function prepares command of supplicant pmk
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_supplicant_pmk(IN pmlan_private pmpriv,
+                               IN HostCmd_DS_COMMAND * cmd,
+                               IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    MrvlIEtypes_PMK_t *ppmk_tlv = MNULL;
+    MrvlIEtypes_Passphrase_t *ppassphrase_tlv = MNULL;
+    MrvlIEtypes_SsIdParamSet_t *pssid_tlv = MNULL;
+    MrvlIEtypes_Bssid_t *pbssid_tlv = MNULL;
+    HostCmd_DS_802_11_SUPPLICANT_PMK *pesupplicant_psk =
+        &cmd->params.esupplicant_psk;
+    t_u8 *ptlv_buffer = (t_u8 *) pesupplicant_psk->tlv_buffer;
+    mlan_ds_passphrase *psk = (mlan_ds_passphrase *) pdata_buf;
+    t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
+
+    ENTER();
+    /* 
+     * Parse the rest of the buf here
+     *      1)  <ssid="valid ssid"> - This will get the passphrase, AKMP 
+     *          for specified ssid, if none specified then it will get all.
+     *          Eg: iwpriv <mlanX> passphrase 0:ssid=marvell
+     *      2)  <psk="psk">:<passphrase="passphare">:<bssid="00:50:43:ef:23:f3">
+     *          <ssid="valid ssid"> - passphrase and psk cannot be provided to  
+     *          the same SSID, Takes one SSID at a time, If ssid= is present 
+     *          the it should contain a passphrase or psk. If no arguments are
+     *          provided then AKMP=802.1x, and passphrase should be provided
+     *          after association.
+     *          End of each parameter should be followed by a ':'(except for the
+     *          last parameter) as the delimiter. If ':' has to be used in 
+     *          an SSID then a '/' should be preceded to ':' as a escape.
+     *          Eg:iwpriv <mlanX> passphrase 
+     *                    "1:ssid=mrvl AP:psk=abcdefgh:bssid=00:50:43:ef:23:f3"
+     *          iwpriv <mlanX> passphrase 
+     *                 "1:ssid=mrvl/: AP:psk=abcdefgd:bssid=00:50:43:ef:23:f3"
+     *          iwpriv <mlanX> passphrase "1:ssid=mrvlAP:psk=abcdefgd"
+     *      3)  <ssid="valid ssid"> - This will clear the passphrase 
+     *          for specified ssid, if none specified then it will clear all.
+     *          Eg: iwpriv <mlanX> passphrase 2:ssid=marvell
+     */
+
+    /* -1 is for t_u8 TlvBuffer[1] as this should not be included */
+    cmd->size = sizeof(HostCmd_DS_802_11_SUPPLICANT_PMK) + S_DS_GEN - 1;
+    if (psk->ssid.ssid_len) {
+        pssid_tlv = (MrvlIEtypes_SsIdParamSet_t *) ptlv_buffer;
+        pssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_SSID);
+        pssid_tlv->header.len = (t_u16) psk->ssid.ssid_len;
+        memcpy((char *) pssid_tlv->ssid, psk->ssid.ssid, psk->ssid.ssid_len);
+        ptlv_buffer += (pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+        cmd->size += (pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+        pssid_tlv->header.len = wlan_cpu_to_le16(pssid_tlv->header.len);
+    }
+    if (memcmp((t_u8 *) & psk->bssid, zero_mac, sizeof(zero_mac))) {
+        pbssid_tlv = (MrvlIEtypes_Bssid_t *) ptlv_buffer;
+        pbssid_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_BSSID);
+        pbssid_tlv->header.len = MLAN_MAC_ADDR_LENGTH;
+        memcpy(pbssid_tlv->bssid, (t_u8 *) & psk->bssid, MLAN_MAC_ADDR_LENGTH);
+        ptlv_buffer += (pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+        cmd->size += (pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+        pbssid_tlv->header.len = wlan_cpu_to_le16(pbssid_tlv->header.len);
+    }
+    if (psk->psk_type == MLAN_PSK_PASSPHRASE) {
+        ppassphrase_tlv = (MrvlIEtypes_Passphrase_t *) ptlv_buffer;
+        ppassphrase_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_PASSPHRASE);
+        ppassphrase_tlv->header.len =
+            (t_u16) psk->psk.passphrase.passphrase_len;
+        memcpy(ppassphrase_tlv->passphrase, psk->psk.passphrase.passphrase,
+               psk->psk.passphrase.passphrase_len);
+        ptlv_buffer +=
+            (ppassphrase_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+        cmd->size +=
+            (ppassphrase_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+        ppassphrase_tlv->header.len =
+            wlan_cpu_to_le16(ppassphrase_tlv->header.len);
+    }
+    if (psk->psk_type == MLAN_PSK_PMK) {
+        ppmk_tlv = (MrvlIEtypes_PMK_t *) ptlv_buffer;
+        ppmk_tlv->header.type = wlan_cpu_to_le16(TLV_TYPE_PMK);
+        ppmk_tlv->header.len = MLAN_MAX_PMK_LENGTH;
+        memcpy(ppmk_tlv->pmk, psk->psk.pmk.pmk, MLAN_MAX_PMK_LENGTH);
+        ptlv_buffer += (ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+        cmd->size += (ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+        ppmk_tlv->header.len = wlan_cpu_to_le16(ppmk_tlv->header.len);
+    }
+    if ((cmd_action == HostCmd_ACT_GEN_SET) &&
+        ((pssid_tlv || pbssid_tlv) && (!ppmk_tlv && !ppassphrase_tlv))) {
+        PRINTM(MERROR,
+               "Invalid case,ssid/bssid present without pmk or passphrase\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PMK);
+    pesupplicant_psk->action = wlan_cpu_to_le16(cmd_action);
+    pesupplicant_psk->cache_result = 0;
+    cmd->size = wlan_cpu_to_le16(cmd->size);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Handle the supplicant profile command
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_cmd_802_11_supplicant_profile(IN pmlan_private pmpriv,
+                                   IN HostCmd_DS_COMMAND * cmd,
+                                   IN t_u16 cmd_action)
+{
+    HostCmd_DS_802_11_SUPPLICANT_PROFILE *sup_profile =
+        &cmd->params.esupplicant_profile;
+
+    ENTER();
+
+    cmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_SUPPLICANT_PROFILE) +
+                         S_DS_GEN - 1);
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_SUPPLICANT_PROFILE);
+    sup_profile->action = wlan_cpu_to_le16(cmd_action);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of rf_channel.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_cmd_802_11_rf_channel(IN pmlan_private pmpriv,
+                           IN HostCmd_DS_COMMAND * cmd,
+                           IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    HostCmd_DS_802_11_RF_CHANNEL *prf_chan = &cmd->params.rf_channel;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_CHANNEL)
+                                 + S_DS_GEN);
+
+    if (cmd_action == HostCmd_ACT_GEN_SET) {
+        if ((pmpriv->adapter->adhoc_start_band & BAND_A)
+            || (pmpriv->adapter->adhoc_start_band & BAND_AN)
+            )
+            prf_chan->rf_type = HostCmd_SCAN_RADIO_TYPE_A;
+        SET_SECONDARYCHAN(prf_chan->rf_type, pmpriv->adapter->chan_offset);
+        prf_chan->rf_type = wlan_cpu_to_le16(prf_chan->rf_type);
+        prf_chan->current_channel = wlan_cpu_to_le16(*((t_u16 *) pdata_buf));
+    }
+    prf_chan->action = wlan_cpu_to_le16(cmd_action);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of rf_antenna.
+ *  
+ *  @param pmpriv   A pointer to mlan_private structure
+ *  @param cmd      A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *
+ *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_802_11_rf_antenna(IN pmlan_private pmpriv,
+                           IN HostCmd_DS_COMMAND * cmd,
+                           IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    HostCmd_DS_802_11_RF_ANTENNA *pantenna = &cmd->params.antenna;
+
+    ENTER();
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_RF_ANTENNA);
+    cmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_RF_ANTENNA) + S_DS_GEN);
+
+    if (cmd_action == HostCmd_ACT_GEN_SET) {
+        pantenna->action = wlan_cpu_to_le16(HostCmd_ACT_SET_BOTH);
+        pantenna->antenna_mode = wlan_cpu_to_le16(*(t_u16 *) pdata_buf);
+    } else
+        pantenna->action = wlan_cpu_to_le16(HostCmd_ACT_GET_BOTH);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of ibss_coalescing_status.
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   The action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer or MNULL
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_ibss_coalescing_status(IN pmlan_private pmpriv,
+                                IN HostCmd_DS_COMMAND * cmd,
+                                IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    HostCmd_DS_802_11_IBSS_STATUS *pibss_coal = &(cmd->params.ibss_coalescing);
+    t_u16 enable = 0;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS);
+    cmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_IBSS_STATUS) + S_DS_GEN);
+    cmd->result = 0;
+    pibss_coal->action = wlan_cpu_to_le16(cmd_action);
+
+    switch (cmd_action) {
+    case HostCmd_ACT_GEN_SET:
+        if (pdata_buf != MNULL)
+            enable = *(t_u16 *) pdata_buf;
+        pibss_coal->enable = wlan_cpu_to_le16(enable);
+        break;
+
+        /* In other case.. Nothing to do */
+    case HostCmd_ACT_GEN_GET:
+    default:
+        break;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+#ifdef MFG_CMD_SUPPORT
+/** 
+ *  @brief This function sends general command to firmware.
+ *  
+ *  @param pmpriv     	A pointer to mlan_private structure
+ *  @param cmd      	A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf	A pointer to data buffer
+ *  @return         	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_mfg_cmd(IN pmlan_private pmpriv,
+                 IN HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_ds_misc_cmd *pcmd_ptr = (mlan_ds_misc_cmd *) pdata_buf;
+
+    ENTER();
+
+    /* Copy the MFG command to command buffer */
+    memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len);
+    PRINTM(MCMND, "MFG command size = %d\n", pcmd_ptr->len);
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MFG_COMMAND);
+    cmd->size = wlan_cpu_to_le16(cmd->size);
+    cmd->result = 0;
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+#endif /* MFG_CMD_SUPPORT */
+
+/** 
+ *  @brief This function prepares LDO cfg command
+ *  
+ *  @param priv    	A pointer to mlan_private structure
+ *  @param cmd	   	A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action 	The action: GET or SET
+ *  @param pdata_buf 	A pointer to data buffer
+ *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_ldo_cfg(IN pmlan_private pmpriv,
+                 IN HostCmd_DS_COMMAND * cmd,
+                 IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    t_u16 *pmsource = (t_u16 *) pdata_buf;
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_LDO_CONFIG);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_LDO_CFG) + S_DS_GEN);
+
+    cmd->params.ldo_cfg.action = wlan_cpu_to_le16(cmd_action);
+    cmd->params.ldo_cfg.pmsource = wlan_cpu_to_le16(*pmsource);
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares system clock cfg command
+ *  
+ *  @param pmpriv    	A pointer to mlan_private structure
+ *  @param cmd	   	A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action 	The action: GET or SET
+ *  @param pdata_buf 	A pointer to data buffer
+ *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_sysclock_cfg(IN pmlan_private pmpriv,
+                      IN HostCmd_DS_COMMAND * cmd,
+                      IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG *cfg = &cmd->params.sys_clock_cfg;
+    mlan_ds_misc_sys_clock *clk_cfg = (mlan_ds_misc_sys_clock *) pdata_buf;
+    int i = 0;
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG);
+    cmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG) + S_DS_GEN);
+
+    cfg->action = wlan_cpu_to_le16(cmd_action);
+    cfg->cur_sys_clk = wlan_cpu_to_le16(clk_cfg->cur_sys_clk);
+    cfg->sys_clk_type = wlan_cpu_to_le16(clk_cfg->sys_clk_type);
+    cfg->sys_clk_len = wlan_cpu_to_le16(clk_cfg->sys_clk_num) * sizeof(t_u16);
+    for (i = 0; i < clk_cfg->sys_clk_num; i++)
+        cfg->sys_clk[i] = wlan_cpu_to_le16(clk_cfg->sys_clk[i]);
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of reg_access.
+ *  
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   the action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_reg_access(IN HostCmd_DS_COMMAND * cmd,
+                    IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    mlan_ds_reg_rw *reg_rw;
+
+    ENTER();
+
+    reg_rw = (mlan_ds_reg_rw *) pdata_buf;
+    switch (cmd->command) {
+    case HostCmd_CMD_MAC_REG_ACCESS:
+        {
+            HostCmd_DS_MAC_REG_ACCESS *mac_reg;
+            cmd->size =
+                wlan_cpu_to_le16(sizeof(HostCmd_DS_MAC_REG_ACCESS) + S_DS_GEN);
+            mac_reg = (HostCmd_DS_MAC_REG_ACCESS *) & cmd->params.mac_reg;
+            mac_reg->action = wlan_cpu_to_le16(cmd_action);
+            mac_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset);
+            mac_reg->value = wlan_cpu_to_le32(reg_rw->value);
+            break;
+        }
+    case HostCmd_CMD_BBP_REG_ACCESS:
+        {
+            HostCmd_DS_BBP_REG_ACCESS *bbp_reg;
+            cmd->size =
+                wlan_cpu_to_le16(sizeof(HostCmd_DS_BBP_REG_ACCESS) + S_DS_GEN);
+            bbp_reg = (HostCmd_DS_BBP_REG_ACCESS *) & cmd->params.bbp_reg;
+            bbp_reg->action = wlan_cpu_to_le16(cmd_action);
+            bbp_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset);
+            bbp_reg->value = (t_u8) reg_rw->value;
+            break;
+        }
+    case HostCmd_CMD_RF_REG_ACCESS:
+        {
+            HostCmd_DS_RF_REG_ACCESS *rf_reg;
+            cmd->size =
+                wlan_cpu_to_le16(sizeof(HostCmd_DS_RF_REG_ACCESS) + S_DS_GEN);
+            rf_reg = (HostCmd_DS_RF_REG_ACCESS *) & cmd->params.rf_reg;
+            rf_reg->action = wlan_cpu_to_le16(cmd_action);
+            rf_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset);
+            rf_reg->value = (t_u8) reg_rw->value;
+            break;
+        }
+    case HostCmd_CMD_PMIC_REG_ACCESS:
+        {
+            HostCmd_DS_PMIC_REG_ACCESS *pmic_reg;
+            cmd->size =
+                wlan_cpu_to_le16(sizeof(HostCmd_DS_PMIC_REG_ACCESS) + S_DS_GEN);
+            pmic_reg = (HostCmd_DS_PMIC_REG_ACCESS *) & cmd->params.pmic_reg;
+            pmic_reg->action = wlan_cpu_to_le16(cmd_action);
+            pmic_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset);
+            pmic_reg->value = (t_u8) reg_rw->value;
+            break;
+        }
+    case HostCmd_CMD_CAU_REG_ACCESS:
+        {
+            HostCmd_DS_RF_REG_ACCESS *cau_reg;
+            cmd->size =
+                wlan_cpu_to_le16(sizeof(HostCmd_DS_RF_REG_ACCESS) + S_DS_GEN);
+            cau_reg = (HostCmd_DS_RF_REG_ACCESS *) & cmd->params.rf_reg;
+            cau_reg->action = wlan_cpu_to_le16(cmd_action);
+            cau_reg->offset = wlan_cpu_to_le16((t_u16) reg_rw->offset);
+            cau_reg->value = (t_u8) reg_rw->value;
+            break;
+        }
+    case HostCmd_CMD_802_11_EEPROM_ACCESS:
+        {
+            mlan_ds_read_eeprom *rd_eeprom = (mlan_ds_read_eeprom *) pdata_buf;
+            HostCmd_DS_802_11_EEPROM_ACCESS *cmd_eeprom =
+                (HostCmd_DS_802_11_EEPROM_ACCESS *) & cmd->params.eeprom;
+            cmd->size =
+                wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_EEPROM_ACCESS) +
+                                 S_DS_GEN);
+            cmd_eeprom->action = wlan_cpu_to_le16(cmd_action);
+            cmd_eeprom->offset = wlan_cpu_to_le16(rd_eeprom->offset);
+            cmd_eeprom->byte_count = wlan_cpu_to_le16(rd_eeprom->byte_count);
+            cmd_eeprom->value = 0;
+            break;
+        }
+    default:
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    cmd->command = wlan_cpu_to_le16(cmd->command);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prepares command of mem_access.
+ *  
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   the action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_mem_access(IN HostCmd_DS_COMMAND * cmd,
+                    IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    mlan_ds_mem_rw *mem_rw = (mlan_ds_mem_rw *) pdata_buf;
+    HostCmd_DS_MEM_ACCESS *mem_access =
+        (HostCmd_DS_MEM_ACCESS *) & cmd->params.mem;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_MEM_ACCESS);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_MEM_ACCESS) + S_DS_GEN);
+
+    mem_access->action = wlan_cpu_to_le16(cmd_action);
+    mem_access->addr = wlan_cpu_to_le32(mem_rw->addr);
+    mem_access->value = wlan_cpu_to_le32(mem_rw->value);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function prepares inactivity timeout command
+ *  
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   the action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_inactivity_timeout(IN HostCmd_DS_COMMAND * cmd,
+                            IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    pmlan_ds_inactivity_to inac_to;
+    HostCmd_DS_INACTIVITY_TIMEOUT_EXT *cmd_inac_to = &cmd->params.inactivity_to;
+
+    ENTER();
+
+    inac_to = (mlan_ds_inactivity_to *) pdata_buf;
+
+    cmd->size =
+        wlan_cpu_to_le16(sizeof(HostCmd_DS_INACTIVITY_TIMEOUT_EXT) + S_DS_GEN);
+    cmd->command = wlan_cpu_to_le16(cmd->command);
+    cmd_inac_to->action = wlan_cpu_to_le16(cmd_action);
+    if (cmd_action == HostCmd_ACT_GEN_SET) {
+        cmd_inac_to->timeout_unit =
+            wlan_cpu_to_le16((t_u16) inac_to->timeout_unit);
+        cmd_inac_to->unicast_timeout =
+            wlan_cpu_to_le16((t_u16) inac_to->unicast_timeout);
+        cmd_inac_to->mcast_timeout =
+            wlan_cpu_to_le16((t_u16) inac_to->mcast_timeout);
+        cmd_inac_to->ps_entry_timeout =
+            wlan_cpu_to_le16((t_u16) inac_to->ps_entry_timeout);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function prepares command of bca_timeshare.
+ *  
+ *  @param pmpriv		A pointer to mlan_private structure
+ *  @param cmd	   		A pointer to HostCmd_DS_COMMAND structure
+ *  @param cmd_action   the action: GET or SET
+ *  @param pdata_buf    A pointer to data buffer
+ *  @return         MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_cmd_802_11_bca_timeshare(pmlan_private pmpriv,
+                              IN HostCmd_DS_COMMAND * cmd,
+                              IN t_u16 cmd_action, IN t_void * pdata_buf)
+{
+    mlan_ds_bca_ts *pdata_bca_ts = (mlan_ds_bca_ts *) pdata_buf;
+    HostCmd_DS_802_11_BCA_TIMESHARE *bca_ts = &cmd->params.bca_timeshare;
+
+    ENTER();
+
+    cmd->size = wlan_cpu_to_le16((sizeof(HostCmd_DS_802_11_BCA_TIMESHARE)) +
+                                 S_DS_GEN);
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_BCA_CONFIG_TIMESHARE);
+
+    if (cmd_action == HostCmd_ACT_GEN_GET) {
+        memset(bca_ts, 0, sizeof(HostCmd_DS_802_11_BCA_TIMESHARE));
+        bca_ts->action = wlan_cpu_to_le16(cmd_action);
+        bca_ts->traffic_type = wlan_cpu_to_le16(pdata_bca_ts->traffic_type);
+    } else if (cmd_action == HostCmd_ACT_GEN_SET) {
+        bca_ts->action = wlan_cpu_to_le16(cmd_action);
+        bca_ts->traffic_type = wlan_cpu_to_le16(pdata_bca_ts->traffic_type);
+        bca_ts->timeshare_interval =
+            wlan_cpu_to_le32(pdata_bca_ts->timeshare_interval);
+        bca_ts->bt_time = wlan_cpu_to_le32(pdata_bca_ts->bt_time);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/********************************************************
+                Global Functions
+********************************************************/
+
+/** 
+ *  @brief This function prepare the command before sending to firmware.
+ *  
+ *  @param priv       A pointer to mlan_private structure
+ *  @param cmd_no       Command number
+ *  @param cmd_action   Command action: GET or SET
+ *  @param cmd_oid      Cmd oid: treated as sub command
+ *  @param pioctl_buf   A pointer to MLAN IOCTl Request buffer
+ *  @param pdata_buf    A pointer to information buffer
+ *  @param pcmd_buf      A pointer to cmd buf
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+mlan_sta_prepare_cmd(IN t_void * priv,
+                     IN t_u16 cmd_no,
+                     IN t_u16 cmd_action,
+                     IN t_u32 cmd_oid,
+                     IN t_void * pioctl_buf,
+                     IN t_void * pdata_buf, IN t_void * pcmd_buf)
+{
+    HostCmd_DS_COMMAND *cmd_ptr = (HostCmd_DS_COMMAND *) pcmd_buf;
+    mlan_private *pmpriv = (mlan_private *) priv;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    /* Prepare command */
+    switch (cmd_no) {
+    case HostCmd_CMD_GET_HW_SPEC:
+        ret = wlan_cmd_get_hw_spec(pmpriv, cmd_ptr);
+        break;
+    case HostCmd_CMD_MAC_CONTROL:
+        ret = wlan_cmd_mac_control(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_MAC_ADDRESS:
+        ret = wlan_cmd_802_11_mac_address(pmpriv, cmd_ptr, cmd_action);
+        break;
+    case HostCmd_CMD_MAC_MULTICAST_ADR:
+        ret =
+            wlan_cmd_mac_multicast_adr(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_TX_RATE_CFG:
+        ret = wlan_cmd_tx_rate_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_RF_ANTENNA:
+        ret =
+            wlan_cmd_802_11_rf_antenna(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_TXPWR_CFG:
+        ret = wlan_cmd_tx_power_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_PS_MODE_ENH:
+        ret =
+            wlan_cmd_802_11_opt_ps_mode(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_HS_CFG_ENH:
+        ret = wlan_cmd_802_11_hs_cfg(pmpriv, cmd_ptr, cmd_action,
+                                     (HostCmd_DS_802_11_HS_CFG_ENH *)
+                                     pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_SLEEP_PERIOD:
+        ret = wlan_cmd_802_11_sleep_period(pmpriv, cmd_ptr,
+                                           cmd_action, (t_u16 *) pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_SLEEP_PARAMS:
+        ret = wlan_cmd_802_11_sleep_params(pmpriv, cmd_ptr,
+                                           cmd_action, (t_u16 *) pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_SCAN:
+        ret = wlan_cmd_802_11_scan(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_BG_SCAN_QUERY:
+        ret = wlan_cmd_802_11_bg_scan_query(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_ASSOCIATE:
+        ret = wlan_cmd_802_11_associate(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_DEAUTHENTICATE:
+        ret = wlan_cmd_802_11_deauthenticate(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_AD_HOC_START:
+        ret = wlan_cmd_802_11_ad_hoc_start(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_AD_HOC_JOIN:
+        ret = wlan_cmd_802_11_ad_hoc_join(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_AD_HOC_STOP:
+        ret = wlan_cmd_802_11_ad_hoc_stop(pmpriv, cmd_ptr);
+        break;
+    case HostCmd_CMD_802_11_GET_LOG:
+        ret = wlan_cmd_802_11_get_log(pmpriv, cmd_ptr);
+        break;
+    case HostCmd_CMD_RSSI_INFO:
+        ret = wlan_cmd_802_11_rssi_info(pmpriv, cmd_ptr, cmd_action);
+        break;
+    case HostCmd_CMD_802_11_SNMP_MIB:
+        ret =
+            wlan_cmd_802_11_snmp_mib(pmpriv, cmd_ptr, cmd_action, cmd_oid,
+                                     pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_RADIO_CONTROL:
+        ret = wlan_cmd_802_11_radio_control(pmpriv, cmd_ptr, cmd_action);
+        break;
+    case HostCmd_CMD_802_11_TX_RATE_QUERY:
+        cmd_ptr->command = wlan_cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
+        cmd_ptr->size =
+            wlan_cpu_to_le16(sizeof(HostCmd_TX_RATE_QUERY) + S_DS_GEN);
+        pmpriv->tx_rate = 0;
+        ret = MLAN_STATUS_SUCCESS;
+        break;
+    case HostCmd_CMD_VERSION_EXT:
+        cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
+        cmd_ptr->params.verext.version_str_sel =
+            (t_u8) (*((t_u32 *) pdata_buf));
+        memcpy(&cmd_ptr->params, pdata_buf, sizeof(HostCmd_DS_VERSION_EXT));
+        cmd_ptr->size =
+            wlan_cpu_to_le16(sizeof(HostCmd_DS_VERSION_EXT) + S_DS_GEN);
+        ret = MLAN_STATUS_SUCCESS;
+        break;
+    case HostCmd_CMD_802_11_RF_CHANNEL:
+        ret =
+            wlan_cmd_802_11_rf_channel(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_FUNC_INIT:
+        if (pmpriv->adapter->hw_status == WlanHardwareStatusReset)
+            pmpriv->adapter->hw_status = WlanHardwareStatusReady;
+        cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
+        cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
+        break;
+    case HostCmd_CMD_FUNC_SHUTDOWN:
+        pmpriv->adapter->hw_status = WlanHardwareStatusReset;
+        cmd_ptr->command = wlan_cpu_to_le16(cmd_no);
+        cmd_ptr->size = wlan_cpu_to_le16(S_DS_GEN);
+        break;
+    case HostCmd_CMD_11N_ADDBA_REQ:
+        ret = wlan_cmd_11n_addba_req(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_11N_DELBA:
+        ret = wlan_cmd_11n_delba(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_11N_ADDBA_RSP:
+        ret = wlan_cmd_11n_addba_rspgen(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_KEY_MATERIAL:
+        ret =
+            wlan_cmd_802_11_key_material(pmpriv, cmd_ptr, cmd_action, cmd_oid,
+                                         pdata_buf);
+        break;
+    case HostCmd_CMD_SUPPLICANT_PMK:
+        ret =
+            wlan_cmd_802_11_supplicant_pmk(pmpriv, cmd_ptr, cmd_action,
+                                           pdata_buf);
+        break;
+    case HostCmd_CMD_SUPPLICANT_PROFILE:
+        ret = wlan_cmd_802_11_supplicant_profile(pmpriv, cmd_ptr, cmd_action);
+        break;
+    case HostCmd_CMD_802_11D_DOMAIN_INFO:
+        ret = wlan_cmd_802_11d_domain_info(pmpriv, cmd_ptr, cmd_action);
+        break;
+    case HostCmd_CMD_802_11_TPC_ADAPT_REQ:
+    case HostCmd_CMD_802_11_TPC_INFO:
+    case HostCmd_CMD_802_11_CHAN_SW_ANN:
+        ret = wlan_11h_cmd_process(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_RECONFIGURE_TX_BUFF:
+        ret = wlan_cmd_recfg_tx_buf(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_AMSDU_AGGR_CTRL:
+        ret = wlan_cmd_amsdu_aggr_ctrl(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_11N_CFG:
+        ret = wlan_cmd_11n_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_WMM_GET_STATUS:
+        PRINTM(MCMND, "WMM: WMM_GET_STATUS cmd sent\n");
+        cmd_ptr->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_GET_STATUS);
+        cmd_ptr->size =
+            wlan_cpu_to_le16(sizeof(HostCmd_DS_WMM_GET_STATUS) + S_DS_GEN);
+        ret = MLAN_STATUS_SUCCESS;
+        break;
+    case HostCmd_CMD_WMM_ADDTS_REQ:
+        ret = wlan_cmd_wmm_addts_req(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_WMM_DELTS_REQ:
+        ret = wlan_cmd_wmm_delts_req(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_WMM_QUEUE_CONFIG:
+        ret = wlan_cmd_wmm_queue_config(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_WMM_QUEUE_STATS:
+        ret = wlan_cmd_wmm_queue_stats(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_WMM_TS_STATUS:
+        ret = wlan_cmd_wmm_ts_status(pmpriv, cmd_ptr, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
+        ret =
+            wlan_cmd_ibss_coalescing_status(pmpriv, cmd_ptr, cmd_action,
+                                            pdata_buf);
+        break;
+#ifdef MFG_CMD_SUPPORT
+    case HostCmd_CMD_MFG_COMMAND:
+        ret = wlan_cmd_mfg_cmd(pmpriv, cmd_ptr, pdata_buf);
+        break;
+#endif /* MFG_CMD_SUPPORT */
+    case HostCmd_CMD_802_11_LDO_CONFIG:
+        ret = wlan_cmd_ldo_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG:
+        ret = wlan_cmd_sysclock_cfg(pmpriv, cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_MAC_REG_ACCESS:
+    case HostCmd_CMD_BBP_REG_ACCESS:
+    case HostCmd_CMD_RF_REG_ACCESS:
+    case HostCmd_CMD_PMIC_REG_ACCESS:
+    case HostCmd_CMD_CAU_REG_ACCESS:
+    case HostCmd_CMD_802_11_EEPROM_ACCESS:
+        ret = wlan_cmd_reg_access(cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_MEM_ACCESS:
+        ret = wlan_cmd_mem_access(cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_INACTIVITY_TIMEOUT_EXT:
+        ret = wlan_cmd_inactivity_timeout(cmd_ptr, cmd_action, pdata_buf);
+        break;
+    case HostCmd_CMD_802_11_BCA_CONFIG_TIMESHARE:
+        ret =
+            wlan_cmd_802_11_bca_timeshare(pmpriv, cmd_ptr, cmd_action,
+                                          pdata_buf);
+        break;
+    default:
+        PRINTM(MERROR, "PREP_CMD: unknown command- %#x\n", cmd_no);
+        ret = MLAN_STATUS_FAILURE;
+        break;
+    }
+    return ret;
+}
+
+/**
+ *  @brief  This function issues commands to initialize firmware
+ *
+ *  @param priv     	A pointer to mlan_private structure
+ *  @param first_sta	flag for first station
+ *
+ *  @return		MLAN_STATUS_SUCCESS or error code
+ */
+mlan_status
+mlan_sta_init_cmd(IN t_void * priv, IN t_u8 first_sta)
+{
+    pmlan_private pmpriv = (pmlan_private) priv;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 enable = MTRUE;
+    mlan_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
+
+    ENTER();
+
+    if (first_sta == MTRUE) {
+
+        ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_FUNC_INIT,
+                               HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
+        if (ret) {
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+        /* 
+         * Read MAC address from HW
+         */
+        ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_GET_HW_SPEC,
+                               HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
+        if (ret) {
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+
+        /* Reconfigure tx buf size */
+        ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
+                               HostCmd_ACT_GEN_SET, 0, MNULL,
+                               &pmpriv->adapter->tx_buf_size);
+        if (ret) {
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+    }
+
+    /* get tx rate */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_TX_RATE_CFG,
+                           HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
+    if (ret) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    pmpriv->data_rate = 0;
+
+    /* get tx power */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_TXPWR_CFG,
+                           HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
+    if (ret) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    /* set ibss coalescing_status */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
+                           HostCmd_ACT_GEN_SET, 0, MNULL, &enable);
+    if (ret) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
+    amsdu_aggr_ctrl.enable = MLAN_ACT_ENABLE;
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_AMSDU_AGGR_CTRL,
+                           HostCmd_ACT_GEN_SET, 0, MNULL,
+                           (t_void *) & amsdu_aggr_ctrl);
+    if (ret) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    /* MAC Control must be the last command in init_fw */
+    /* set MAC Control */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_MAC_CONTROL,
+                           HostCmd_ACT_GEN_SET, 0, MNULL,
+                           &pmpriv->curr_pkt_filter);
+    if (ret) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    /** set last_init_cmd */
+    pmpriv->adapter->last_init_cmd = HostCmd_CMD_MAC_CONTROL;
+    ret = MLAN_STATUS_PENDING;
+  done:
+    LEAVE();
+    return ret;
+}
diff --git a/wlan_src/mlan/mlan_sta_cmdresp.c b/wlan_src/mlan/mlan_sta_cmdresp.c
new file mode 100755
index 0000000..9873ff9
--- /dev/null
+++ b/wlan_src/mlan/mlan_sta_cmdresp.c
@@ -0,0 +1,1906 @@
+/** @file mlan_sta_cmdresp.c
+ *  
+ *  @brief This file contains the handling of command
+ *  responses generated by firmware.
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    10/21/2008: initial version
+******************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_11h.h"
+
+#include "mlan_sdio.h"
+
+/********************************************************
+                Local Variables
+********************************************************/
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+/** 
+ *  @brief This function handles the command response error
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to command buffer
+ *
+ *  @return             N/A
+ */
+void
+wlan_process_cmdresp_error(mlan_private * pmpriv, HostCmd_DS_COMMAND * resp,
+                           mlan_ioctl_req * pioctl_buf)
+{
+    cmd_ctrl_node *pcmd_node = MNULL;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+
+    ENTER();
+
+    PRINTM(MERROR, "CMD_RESP: cmd %#x error, result=%#x\n", resp->command,
+           resp->result);
+    if (pioctl_buf)
+        pioctl_buf->status_code = MLAN_ERROR_FW_CMDRESP;
+
+    switch (resp->command) {
+    case HostCmd_CMD_802_11_PS_MODE_ENH:
+        {
+            HostCmd_DS_802_11_PS_MODE_ENH *pm = &resp->params.psmode_enh;
+            PRINTM(MERROR,
+                   "PS_MODE_ENH command failed: result=0x%x action=0x%X\n",
+                   resp->result, wlan_le16_to_cpu(pm->action));
+            /* 
+             * We do not re-try enter-ps command in ad-hoc mode.
+             */
+            if (wlan_le16_to_cpu(pm->action) == EN_PS &&
+                pmpriv->bss_mode == MLAN_BSS_MODE_IBSS)
+                pmadapter->ps_mode = Wlan802_11PowerModeCAM;
+        }
+        break;
+    case HostCmd_CMD_802_11_SCAN:
+        /* Cancel all pending scan command */
+        while ((pcmd_node =
+                (cmd_ctrl_node *) util_peek_list(&pmadapter->scan_pending_q,
+                                                 pcb->moal_spin_lock,
+                                                 pcb->moal_spin_unlock))) {
+            util_unlink_list(&pmadapter->scan_pending_q,
+                             (pmlan_linked_list) pcmd_node, pcb->moal_spin_lock,
+                             pcb->moal_spin_unlock);
+            pcmd_node->pioctl_buf = MNULL;
+            wlan_insert_cmd_to_free_q(pmadapter, pcmd_node);
+        }
+        wlan_request_cmd_lock(pmadapter);
+        pmadapter->scan_processing = MFALSE;
+        wlan_release_cmd_lock(pmadapter);
+        break;
+
+    case HostCmd_CMD_MAC_CONTROL:
+        break;
+
+    default:
+        break;
+    }
+    /* 
+     * Handling errors here
+     */
+    wlan_insert_cmd_to_free_q(pmadapter, pmadapter->curr_cmd);
+
+    wlan_request_cmd_lock(pmadapter);
+    pmadapter->curr_cmd = MNULL;
+    wlan_release_cmd_lock(pmadapter);
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function handles the command response of get_hw_spec
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to command buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_ret_get_hw_spec(IN pmlan_private pmpriv,
+                     IN HostCmd_DS_COMMAND * resp, IN t_void * pioctl_buf)
+{
+    HostCmd_DS_GET_HW_SPEC *hw_spec = &resp->params.hw_spec;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u32 i;
+
+    ENTER();
+
+    pmadapter->fw_cap_info = wlan_le32_to_cpu(hw_spec->fw_cap_info);
+
+    if (IS_SUPPORT_MULTI_BANDS(pmadapter)) {
+        pmadapter->fw_bands = (t_u8) GET_FW_DEFAULT_BANDS(pmadapter);
+    } else {
+        pmadapter->fw_bands = BAND_B;
+    }
+
+    pmadapter->config_bands = pmadapter->fw_bands;
+
+    if (pmadapter->fw_bands & BAND_A) {
+        if (pmadapter->fw_bands & BAND_GN) {
+            pmadapter->config_bands |= BAND_AN;
+            pmadapter->fw_bands |= BAND_AN;
+        }
+        if (pmadapter->fw_bands & BAND_AN) {
+            pmadapter->adhoc_start_band = BAND_A | BAND_AN;
+            pmadapter->adhoc_11n_enabled = MTRUE;
+        } else
+            pmadapter->adhoc_start_band = BAND_A;
+        pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL_A;
+    } else if (pmadapter->fw_bands & BAND_GN) {
+        pmadapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN;
+        pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+        pmadapter->adhoc_11n_enabled = MTRUE;
+    } else if (pmadapter->fw_bands & BAND_G) {
+        pmadapter->adhoc_start_band = BAND_G | BAND_B;
+        pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+    } else if (pmadapter->fw_bands & BAND_B) {
+        pmadapter->adhoc_start_band = BAND_B;
+        pmpriv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+    }
+
+    pmadapter->fw_release_number = hw_spec->fw_release_number;
+    pmadapter->number_of_antenna = hw_spec->number_of_antenna;
+
+    PRINTM(MINFO, "GET_HW_SPEC: fw_release_number- 0x%X\n",
+           wlan_le32_to_cpu(pmadapter->fw_release_number));
+    PRINTM(MINFO, "GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
+           hw_spec->permanent_addr[0], hw_spec->permanent_addr[1],
+           hw_spec->permanent_addr[2], hw_spec->permanent_addr[3],
+           hw_spec->permanent_addr[4], hw_spec->permanent_addr[5]);
+    PRINTM(MINFO, "GET_HW_SPEC: hw_if_version=0x%X  version=0x%X\n",
+           wlan_le16_to_cpu(hw_spec->hw_if_version),
+           wlan_le16_to_cpu(hw_spec->version));
+
+    if (pmpriv->curr_addr[0] == 0xff)
+        memmove(pmpriv->curr_addr, hw_spec->permanent_addr,
+                MLAN_MAC_ADDR_LENGTH);
+
+    pmadapter->region_code = wlan_le16_to_cpu(hw_spec->region_code);
+
+    for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
+        /* Use the region code to search for the index */
+        if (pmadapter->region_code == region_code_index[i])
+            break;
+    }
+
+    /* If it's unidentified region code, use the default (USA) */
+    if (i >= MRVDRV_MAX_REGION_CODE) {
+        pmadapter->region_code = 0x10;
+        PRINTM(MWARN, "unidentified region code, use the default (USA)\n");
+    }
+    if (wlan_set_regiontable(pmpriv, (t_u8) pmadapter->region_code,
+                             pmadapter->fw_bands)) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    if (wlan_11d_set_universaltable(pmpriv, pmadapter->fw_bands)) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    pmadapter->hw_dot_11n_dev_cap = wlan_le32_to_cpu(hw_spec->dot_11n_dev_cap);
+    pmadapter->usr_dot_11n_dev_cap = pmadapter->hw_dot_11n_dev_cap &
+        DEFAULT_11N_CAP_MASK;
+    pmadapter->usr_dev_mcs_support = pmadapter->hw_dev_mcs_support =
+        hw_spec->dev_mcs_support;
+    wlan_show_dot11ndevcap(pmadapter, pmadapter->hw_dot_11n_dev_cap);
+    wlan_show_devmcssupport(pmadapter, pmadapter->hw_dev_mcs_support);
+    pmadapter->mp_end_port = wlan_le16_to_cpu(hw_spec->mp_end_port);
+
+    for (i = 1; i <= (unsigned) (MAX_PORT - pmadapter->mp_end_port); i++) {
+        pmadapter->mp_data_port_mask &= ~(1 << (MAX_PORT - i));
+    }
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function handles the command response of RSSI info
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_rssi_info(IN pmlan_private pmpriv,
+                          IN HostCmd_DS_COMMAND * resp,
+                          IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_RSSI_INFO_RSP *prssi_info_rsp =
+        &resp->params.rssi_info_rsp;
+    mlan_ds_get_info *pget_info = MNULL;
+
+    ENTER();
+
+    pmpriv->data_rssi_last = wlan_le16_to_cpu(prssi_info_rsp->data_rssi_last);
+    pmpriv->data_nf_last = wlan_le16_to_cpu(prssi_info_rsp->data_nf_last);
+
+    pmpriv->data_rssi_avg = wlan_le16_to_cpu(prssi_info_rsp->data_rssi_avg);
+    pmpriv->data_nf_avg = wlan_le16_to_cpu(prssi_info_rsp->data_nf_avg);
+
+    pmpriv->bcn_rssi_last = wlan_le16_to_cpu(prssi_info_rsp->bcn_rssi_last);
+    pmpriv->bcn_nf_last = wlan_le16_to_cpu(prssi_info_rsp->bcn_nf_last);
+
+    pmpriv->bcn_rssi_avg = wlan_le16_to_cpu(prssi_info_rsp->bcn_rssi_avg);
+    pmpriv->bcn_nf_avg = wlan_le16_to_cpu(prssi_info_rsp->bcn_nf_avg);
+
+    /* Need to indicate IOCTL complete */
+    if (pioctl_buf != MNULL) {
+        pget_info = (mlan_ds_get_info *) pioctl_buf->pbuf;
+
+        memset(pget_info, 0, sizeof(mlan_ds_get_info));
+
+        pget_info->param.signal.selector = ALL_RSSI_INFO_MASK;
+
+        /* RSSI */
+        pget_info->param.signal.bcn_rssi_last = pmpriv->bcn_rssi_last;
+        pget_info->param.signal.bcn_rssi_avg = pmpriv->bcn_rssi_avg;
+        pget_info->param.signal.data_rssi_last = pmpriv->data_rssi_last;
+        pget_info->param.signal.data_rssi_avg = pmpriv->data_rssi_avg;
+
+        /* SNR */
+        pget_info->param.signal.bcn_snr_last =
+            CAL_SNR(pmpriv->bcn_rssi_last, pmpriv->bcn_nf_last);
+        pget_info->param.signal.bcn_snr_avg =
+            CAL_SNR(pmpriv->bcn_rssi_avg, pmpriv->bcn_nf_avg);
+        pget_info->param.signal.data_snr_last =
+            CAL_SNR(pmpriv->data_rssi_last, pmpriv->data_nf_last);
+        pget_info->param.signal.data_snr_avg =
+            CAL_SNR(pmpriv->data_rssi_avg, pmpriv->data_nf_avg);
+
+        /* NF */
+        pget_info->param.signal.bcn_nf_last = pmpriv->bcn_nf_last;
+        pget_info->param.signal.bcn_nf_avg = pmpriv->bcn_nf_avg;
+        pget_info->param.signal.data_nf_last = pmpriv->data_nf_last;
+        pget_info->param.signal.data_nf_avg = pmpriv->data_nf_avg;
+
+        pioctl_buf->data_read_written = sizeof(mlan_ds_get_info);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of mac_control
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_mac_control(IN pmlan_private pmpriv,
+                     IN HostCmd_DS_COMMAND * resp,
+                     IN mlan_ioctl_req * pioctl_buf)
+{
+    ENTER();
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of snmp_mib
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_snmp_mib(IN pmlan_private pmpriv,
+                         IN HostCmd_DS_COMMAND * resp,
+                         IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_SNMP_MIB *psmib = &resp->params.smib;
+    t_u16 oid = wlan_le16_to_cpu(psmib->oid);
+    t_u16 query_type = wlan_le16_to_cpu(psmib->query_type);
+    t_u32 ul_temp;
+    mlan_ds_snmp_mib *mib = MNULL;
+
+    ENTER();
+
+    if (pioctl_buf)
+        mib = (mlan_ds_snmp_mib *) pioctl_buf->pbuf;
+
+    PRINTM(MINFO, "SNMP_RESP: value of the oid = 0x%x, query_type=0x%x\n", oid,
+           query_type);
+    PRINTM(MINFO, "SNMP_RESP: Buf size  = 0x%x\n",
+           wlan_le16_to_cpu(psmib->buf_size));
+    if (query_type == HostCmd_ACT_GEN_GET) {
+        switch (oid) {
+        case FragThresh_i:
+            ul_temp = wlan_le16_to_cpu(*((t_u16 *) (psmib->value)));
+            PRINTM(MINFO, "SNMP_RESP: FragThsd =%u\n", ul_temp);
+            if (mib)
+                mib->param.frag_threshold = ul_temp;
+            break;
+
+        case RtsThresh_i:
+            ul_temp = wlan_le16_to_cpu(*((t_u16 *) (psmib->value)));
+            PRINTM(MINFO, "SNMP_RESP: RTSThsd =%u\n", ul_temp);
+            if (mib)
+                mib->param.rts_threshold = ul_temp;
+            break;
+
+        case ShortRetryLim_i:
+            ul_temp = wlan_le16_to_cpu(*((t_u16 *) (psmib->value)));
+            PRINTM(MINFO, "SNMP_RESP: TxRetryCount=%u\n", ul_temp);
+            if (mib)
+                mib->param.retry_count = ul_temp;
+            break;
+        case WwsMode_i:
+            ul_temp = wlan_le16_to_cpu(*((t_u16 *) (psmib->value)));
+            PRINTM(MINFO, "SNMP_RESP: WWSCfg =%u\n", ul_temp);
+            if (pioctl_buf)
+                ((mlan_ds_misc_cfg *) pioctl_buf->pbuf)->param.wws_cfg =
+                    ul_temp;
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    if (pioctl_buf) {
+        /* Indicate ioctl complete */
+        pioctl_buf->data_read_written = sizeof(mlan_ds_snmp_mib);
+    }
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of get_log
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_get_log(IN pmlan_private pmpriv,
+                 IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_GET_LOG *pget_log =
+        (HostCmd_DS_802_11_GET_LOG *) & resp->params.get_log;
+    mlan_ds_get_info *pget_info = MNULL;
+
+    ENTER();
+    if (pioctl_buf) {
+        pget_info = (mlan_ds_get_info *) pioctl_buf->pbuf;
+        pget_info->param.stats.mcast_tx_frame =
+            wlan_le32_to_cpu(pget_log->mcast_tx_frame);
+        pget_info->param.stats.failed = wlan_le32_to_cpu(pget_log->failed);
+        pget_info->param.stats.retry = wlan_le32_to_cpu(pget_log->retry);
+        pget_info->param.stats.multi_retry =
+            wlan_le32_to_cpu(pget_log->multiretry);
+        pget_info->param.stats.frame_dup =
+            wlan_le32_to_cpu(pget_log->frame_dup);
+        pget_info->param.stats.rts_success =
+            wlan_le32_to_cpu(pget_log->rts_success);
+        pget_info->param.stats.rts_failure =
+            wlan_le32_to_cpu(pget_log->rts_failure);
+        pget_info->param.stats.ack_failure =
+            wlan_le32_to_cpu(pget_log->ack_failure);
+        pget_info->param.stats.rx_frag = wlan_le32_to_cpu(pget_log->rx_frag);
+        pget_info->param.stats.mcast_rx_frame =
+            wlan_le32_to_cpu(pget_log->mcast_rx_frame);
+        pget_info->param.stats.fcs_error =
+            wlan_le32_to_cpu(pget_log->fcs_error);
+        pget_info->param.stats.tx_frame = wlan_le32_to_cpu(pget_log->tx_frame);
+        pget_info->param.stats.wep_icv_error[0] =
+            wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[0]);
+        pget_info->param.stats.wep_icv_error[1] =
+            wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[1]);
+        pget_info->param.stats.wep_icv_error[2] =
+            wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[2]);
+        pget_info->param.stats.wep_icv_error[3] =
+            wlan_le32_to_cpu(pget_log->wep_icv_err_cnt[3]);
+        /* Indicate ioctl complete */
+        pioctl_buf->data_read_written = sizeof(mlan_ds_get_info);
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of radio_control
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure 
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_radio_control(IN pmlan_private pmpriv,
+                              IN HostCmd_DS_COMMAND * resp,
+                              IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_RADIO_CONTROL *pradio_ctrl =
+        (HostCmd_DS_802_11_RADIO_CONTROL *) & resp->params.radio;
+    mlan_ds_radio_cfg *radio_cfg = MNULL;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+
+    ENTER();
+    pmadapter->radio_on = wlan_le16_to_cpu(pradio_ctrl->control);
+    if (pioctl_buf) {
+        radio_cfg = (mlan_ds_radio_cfg *) pioctl_buf->pbuf;
+        radio_cfg->param.radio_on_off = (t_u32) pmadapter->radio_on;
+        pioctl_buf->data_read_written = sizeof(mlan_ds_radio_cfg);
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of tx_rate_cfg
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure 
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_tx_rate_cfg(IN pmlan_private pmpriv,
+                     IN HostCmd_DS_COMMAND * resp,
+                     IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_ds_rate *ds_rate = MNULL;
+    HostCmd_DS_TX_RATE_CFG *prate_cfg = &resp->params.tx_rate_cfg;
+    MrvlRateScope_t *prate_scope;
+    MrvlIEtypesHeader_t *head = MNULL;
+    t_u16 tlv, tlv_buf_len;
+    t_u8 *tlv_buf;
+    t_u32 i;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    tlv_buf = (t_u8 *) ((t_u8 *) prate_cfg) + sizeof(HostCmd_DS_TX_RATE_CFG);
+    tlv_buf_len = *(t_u16 *) (tlv_buf + sizeof(t_u16));
+    tlv_buf_len = wlan_le16_to_cpu(tlv_buf_len);
+
+    while (tlv_buf && tlv_buf_len > 0) {
+        tlv = (*tlv_buf);
+        tlv = tlv | (*(tlv_buf + 1) << 8);
+
+        switch (tlv) {
+        case TLV_TYPE_RATE_SCOPE:
+            prate_scope = (MrvlRateScope_t *) tlv_buf;
+            pmpriv->bitmap_rates[0] =
+                wlan_le16_to_cpu(prate_scope->hr_dsss_rate_bitmap);
+            pmpriv->bitmap_rates[1] =
+                wlan_le16_to_cpu(prate_scope->ofdm_rate_bitmap);
+            for (i = 0;
+                 i < sizeof(prate_scope->ht_mcs_rate_bitmap) / sizeof(t_u16);
+                 i++)
+                pmpriv->bitmap_rates[2 + i] =
+                    wlan_le16_to_cpu(prate_scope->ht_mcs_rate_bitmap[i]);
+            break;
+            /* Add RATE_DROP tlv here */
+        }
+
+        head = (MrvlIEtypesHeader_t *) tlv_buf;
+        head->len = wlan_le16_to_cpu(head->len);
+        tlv_buf += head->len + sizeof(MrvlIEtypesHeader_t);
+        tlv_buf_len -= head->len;
+    }
+
+    pmpriv->is_data_rate_auto = wlan_is_rate_auto(pmpriv);
+
+    if (pmpriv->is_data_rate_auto) {
+        pmpriv->data_rate = 0;
+    } else {
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_802_11_TX_RATE_QUERY,
+                               HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
+
+    }
+
+    if (pioctl_buf) {
+        ds_rate = (mlan_ds_rate *) pioctl_buf->pbuf;
+        if (wlan_le16_to_cpu(prate_cfg->action) == HostCmd_ACT_GEN_GET) {
+            if (pmpriv->is_data_rate_auto)
+                ds_rate->param.rate_cfg.is_rate_auto = 1;
+            else {
+                ds_rate->param.rate_cfg.rate =
+                    wlan_get_rate_index(pmadapter, pmpriv->bitmap_rates,
+                                        sizeof(pmpriv->bitmap_rates));
+                if (ds_rate->param.rate_cfg.rate >= MLAN_RATE_BITMAP_OFDM0 &&
+                    ds_rate->param.rate_cfg.rate <= MLAN_RATE_BITMAP_OFDM7)
+                    ds_rate->param.rate_cfg.rate -=
+                        (MLAN_RATE_BITMAP_OFDM0 - MLAN_RATE_INDEX_OFDM0);
+                if (ds_rate->param.rate_cfg.rate >= MLAN_RATE_BITMAP_MCS0 &&
+                    ds_rate->param.rate_cfg.rate <= MLAN_RATE_BITMAP_MCS127)
+                    ds_rate->param.rate_cfg.rate -=
+                        (MLAN_RATE_BITMAP_MCS0 - MLAN_RATE_INDEX_MCS0);
+            }
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get power level and rate index
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param pdata_buf    Pointer to the data buffer
+ * 
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_get_power_level(pmlan_private pmpriv, void *pdata_buf)
+{
+    int length = -1, max_power = -1, min_power = -1;
+    MrvlTypes_Power_Group_t *ppg_tlv = MNULL;
+    Power_Group_t *pg = MNULL;
+
+    ENTER();
+
+    if (pdata_buf) {
+        ppg_tlv =
+            (MrvlTypes_Power_Group_t *) ((t_u8 *) pdata_buf +
+                                         sizeof(HostCmd_DS_TXPWR_CFG));
+        pg = (Power_Group_t *) ((t_u8 *) ppg_tlv +
+                                sizeof(MrvlTypes_Power_Group_t));
+        length = ppg_tlv->length;
+        if (length > 0) {
+            max_power = pg->power_max;
+            min_power = pg->power_min;
+            length -= sizeof(Power_Group_t);
+        }
+        while (length) {
+            pg++;
+            if (max_power < pg->power_max) {
+                max_power = pg->power_max;
+            }
+            if (min_power > pg->power_min) {
+                min_power = pg->power_min;
+            }
+            length -= sizeof(Power_Group_t);
+        }
+        if (ppg_tlv->length > 0) {
+            pmpriv->min_tx_power_level = (t_u8) min_power;
+            pmpriv->max_tx_power_level = (t_u8) max_power;
+        }
+    } else {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of tx_power_cfg
+ * 
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_tx_power_cfg(IN pmlan_private pmpriv,
+                      IN HostCmd_DS_COMMAND * resp,
+                      IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    HostCmd_DS_TXPWR_CFG *ptxp_cfg = &resp->params.txp_cfg;
+    MrvlTypes_Power_Group_t *ppg_tlv = MNULL;
+    Power_Group_t *pg = MNULL;
+    t_u16 action = wlan_le16_to_cpu(ptxp_cfg->action);
+    mlan_ds_power_cfg *power = MNULL;
+    t_u32 data[5];
+
+    ENTER();
+    switch (action) {
+    case HostCmd_ACT_GEN_GET:
+        {
+            ppg_tlv =
+                (MrvlTypes_Power_Group_t *) ((t_u8 *) ptxp_cfg +
+                                             sizeof(HostCmd_DS_TXPWR_CFG));
+            pg = (Power_Group_t *) ((t_u8 *) ppg_tlv +
+                                    sizeof(MrvlTypes_Power_Group_t));
+            ppg_tlv->length = wlan_le16_to_cpu(ppg_tlv->length);
+            if (pmadapter->hw_status == WlanHardwareStatusInitializing)
+                wlan_get_power_level(pmpriv, ptxp_cfg);
+            pmpriv->tx_power_level = (t_u16) pg->power_min;
+            break;
+        }
+    case HostCmd_ACT_GEN_SET:
+        if (wlan_le32_to_cpu(ptxp_cfg->mode)) {
+            ppg_tlv =
+                (MrvlTypes_Power_Group_t *) ((t_u8 *) ptxp_cfg +
+                                             sizeof(HostCmd_DS_TXPWR_CFG));
+            pg = (Power_Group_t *) ((t_u8 *) ppg_tlv +
+                                    sizeof(MrvlTypes_Power_Group_t));
+            if (pg->power_max == pg->power_min)
+                pmpriv->tx_power_level = (t_u16) pg->power_min;
+        }
+        break;
+    default:
+        PRINTM(MERROR, "CMD_RESP: unknown command action %d\n", action);
+        LEAVE();
+        return MLAN_STATUS_SUCCESS;
+    }
+    PRINTM(MINFO, "Current TxPower Level = %d,Max Power=%d, Min Power=%d\n",
+           pmpriv->tx_power_level, pmpriv->max_tx_power_level,
+           pmpriv->min_tx_power_level);
+
+    if (pioctl_buf) {
+        power = (mlan_ds_power_cfg *) pioctl_buf->pbuf;
+        if (action == HostCmd_ACT_GEN_GET) {
+            if (power->sub_command == MLAN_OID_POWER_CFG) {
+                pioctl_buf->data_read_written =
+                    sizeof(mlan_power_cfg_t) + MLAN_SUB_COMMAND_SIZE;
+                power->param.power_cfg.power_level = pmpriv->tx_power_level;
+                if (wlan_le32_to_cpu(ptxp_cfg->mode))
+                    power->param.power_cfg.is_power_auto = 0;
+                else
+                    power->param.power_cfg.is_power_auto = 1;
+            } else {
+                power->param.power_ext.len = 0;
+                while (ppg_tlv->length) {
+                    data[0] = pg->first_rate_code;
+                    data[1] = pg->last_rate_code;
+                    if (pg->modulation_class == MOD_CLASS_OFDM) {
+                        data[0] += MLAN_RATE_INDEX_OFDM0;
+                        data[1] += MLAN_RATE_INDEX_OFDM0;
+                    } else if (pg->modulation_class == MOD_CLASS_HT) {
+                        data[0] += MLAN_RATE_INDEX_MCS0;
+                        data[1] += MLAN_RATE_INDEX_MCS0;
+                        if (pg->ht_bandwidth == HT_BW_40) {
+                            data[0] |= TX_RATE_HT_BW40_BIT;
+                            data[1] |= TX_RATE_HT_BW40_BIT;
+                        }
+                    }
+                    data[2] = pg->power_min;
+                    data[3] = pg->power_max;
+                    data[4] = pg->power_step;
+                    memcpy((t_u8 *) & power->param.power_ext.
+                           power_data[power->param.power_ext.len],
+                           (t_u8 *) data, sizeof(data));
+                    power->param.power_ext.len += 5;
+                    pg++;
+                    ppg_tlv->length -= sizeof(Power_Group_t);
+                }
+                pioctl_buf->data_read_written =
+                    sizeof(mlan_power_cfg_ext) + MLAN_SUB_COMMAND_SIZE;
+            }
+        }
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of ps_mode_enh
+ * 
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_opt_ps_mode(IN pmlan_private pmpriv,
+                            IN HostCmd_DS_COMMAND * resp,
+                            IN mlan_ioctl_req * pioctl_buf)
+{
+    pmlan_adapter pmadapter = pmpriv->adapter;
+    HostCmd_DS_802_11_PS_MODE_ENH *pps_mode = &resp->params.psmode_enh;
+
+    ENTER();
+
+    PRINTM(MINFO, "CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n",
+           resp->result, pps_mode->action);
+    pps_mode->action = wlan_le16_to_cpu(pps_mode->action);
+
+    switch (pps_mode->action) {
+    case EN_PS:
+        pmadapter->ps_state = PS_STATE_AWAKE;
+        PRINTM(MDATA, "Settting ps_state to AWAKE\n");
+        if (pmadapter->sleep_period.period) {
+            PRINTM(MDATA, "Setting uapsd/pps mode to TRUE\n");
+        }
+        break;
+    case DIS_PS:
+        pmadapter->ps_state = PS_STATE_AWAKE;
+        PRINTM(MDATA, "Setting ps_state to AWAKE\n");
+        if (pmadapter->sleep_period.period) {
+            pmadapter->delay_null_pkt = MFALSE;
+            pmadapter->tx_lock_flag = MFALSE;
+        }
+        break;
+    case EN_AUTO_DS:
+        pmadapter->ps_state = PS_STATE_AWAKE;
+        PRINTM(MDATA, "Enabled auto deep sleep\n");
+        pmpriv->adapter->is_deep_sleep = MTRUE;
+        break;
+    case DIS_AUTO_DS:
+        pmpriv->adapter->is_deep_sleep = MFALSE;
+        pmadapter->ps_state = PS_STATE_AWAKE;
+        PRINTM(MDATA, "Disabled auto deep sleep\n");
+        break;
+    case SLEEP_CONFIRM:
+        PRINTM(MDATA,
+               "Received Sleep confirm response, setting ps_state to SLEEP\n");
+        pmadapter->ps_state = PS_STATE_SLEEP;
+        break;
+    default:
+        PRINTM(MERROR, "CMD_RESP: unknown PS_MODE action 0x%x\n",
+               pps_mode->action);
+        break;
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of sleep_period
+ *    
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_sleep_period(IN pmlan_private pmpriv,
+                             IN HostCmd_DS_COMMAND * resp,
+                             IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_SLEEP_PERIOD *pcmd_sleep_pd = &resp->params.sleep_pd;
+    mlan_ds_pm_cfg *pm_cfg = MNULL;
+    t_u16 sleep_pd = 0;
+
+    ENTER();
+
+    sleep_pd = wlan_le16_to_cpu(pcmd_sleep_pd->sleep_pd);
+    if (pioctl_buf) {
+        pm_cfg = (mlan_ds_pm_cfg *) pioctl_buf->pbuf;
+        pm_cfg->param.sleep_period = (t_u32) sleep_pd;
+        pioctl_buf->data_read_written = sizeof(pm_cfg->param.sleep_period)
+            + MLAN_SUB_COMMAND_SIZE;
+    }
+    pmpriv->adapter->sleep_period.period = sleep_pd;
+    if (sleep_pd == SLEEP_PERIOD_RESERVED_FF)
+        pmpriv->gen_null_pkg = MFALSE;
+    else
+        pmpriv->gen_null_pkg = MTRUE;
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of sleep_params
+ *    
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_sleep_params(IN pmlan_private pmpriv,
+                             IN HostCmd_DS_COMMAND * resp,
+                             IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_SLEEP_PARAMS *presp_sp = &resp->params.sleep_param;
+    mlan_ds_pm_cfg *pm_cfg = MNULL;
+    mlan_ds_sleep_params *psp = MNULL;
+    sleep_params_t *psleep_params = &pmpriv->adapter->sleep_params;
+
+    ENTER();
+
+    psleep_params->sp_reserved = wlan_le16_to_cpu(presp_sp->reserved);
+    psleep_params->sp_error = wlan_le16_to_cpu(presp_sp->error);
+    psleep_params->sp_offset = wlan_le16_to_cpu(presp_sp->offset);
+    psleep_params->sp_stable_time = wlan_le16_to_cpu(presp_sp->stable_time);
+    psleep_params->sp_cal_control = presp_sp->cal_control;
+    psleep_params->sp_ext_sleep_clk = presp_sp->external_sleep_clk;
+
+    if (pioctl_buf) {
+        pm_cfg = (mlan_ds_pm_cfg *) pioctl_buf->pbuf;
+        psp = (mlan_ds_sleep_params *) & pm_cfg->param.sleep_params;
+
+        psp->error = (t_u32) psleep_params->sp_error;
+        psp->offset = (t_u32) psleep_params->sp_offset;
+        psp->stable_time = (t_u32) psleep_params->sp_stable_time;
+        psp->cal_control = (t_u32) psleep_params->sp_cal_control;
+        psp->ext_sleep_clk = (t_u32) psleep_params->sp_ext_sleep_clk;
+        psp->reserved = (t_u32) psleep_params->sp_reserved;
+
+        pioctl_buf->data_read_written = sizeof(pm_cfg->param.sleep_params)
+            + MLAN_SUB_COMMAND_SIZE;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of mac_address
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_mac_address(IN pmlan_private pmpriv,
+                            IN HostCmd_DS_COMMAND * resp,
+                            IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_MAC_ADDRESS *pmac_addr = &resp->params.mac_addr;
+    mlan_ds_bss *bss = MNULL;
+
+    ENTER();
+
+    memcpy(pmpriv->curr_addr, pmac_addr->mac_addr, MLAN_MAC_ADDR_LENGTH);
+
+    PRINTM(MINFO, "set mac address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+           pmpriv->curr_addr[0], pmpriv->curr_addr[1], pmpriv->curr_addr[2],
+           pmpriv->curr_addr[3], pmpriv->curr_addr[4], pmpriv->curr_addr[5]);
+    if (pioctl_buf) {
+        bss = (mlan_ds_bss *) pioctl_buf->pbuf;
+        memcpy(&bss->param.mac_addr, pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH);
+        pioctl_buf->data_read_written =
+            MLAN_MAC_ADDR_LENGTH + MLAN_SUB_COMMAND_SIZE;
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of multicast_address
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_mac_multicast_adr(IN pmlan_private pmpriv,
+                           IN HostCmd_DS_COMMAND * resp,
+                           IN mlan_ioctl_req * pioctl_buf)
+{
+    ENTER();
+    if (pioctl_buf) {
+        pioctl_buf->data_read_written =
+            sizeof(mlan_multicast_list) + MLAN_SUB_COMMAND_SIZE;
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of tx rate query
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_tx_rate_query(IN pmlan_private pmpriv,
+                              IN HostCmd_DS_COMMAND * resp,
+                              IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    mlan_ds_rate *rate = MNULL;
+    ENTER();
+
+    pmpriv->tx_rate = resp->params.tx_rate.tx_rate;
+    pmpriv->tx_htinfo = resp->params.tx_rate.ht_info;
+    if (!pmpriv->is_data_rate_auto) {
+        pmpriv->data_rate =
+            wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate,
+                                    pmpriv->tx_htinfo);
+    }
+
+    if (pioctl_buf) {
+        rate = (mlan_ds_rate *) pioctl_buf->pbuf;
+        if (rate->sub_command == MLAN_OID_RATE_CFG) {
+            if (rate->param.rate_cfg.rate_type == MLAN_RATE_INDEX) {
+                if (pmpriv->tx_htinfo & MBIT(0))
+                    rate->param.rate_cfg.rate =
+                        pmpriv->tx_rate + MLAN_RATE_INDEX_MCS0;
+                else
+                    /* For HostCmd_CMD_802_11_TX_RATE_QUERY, there is a hole in 
+                       rate table between HR/DSSS and OFDM rates, so minus 1
+                       for OFDM rate index */
+                    rate->param.rate_cfg.rate =
+                        (pmpriv->tx_rate >
+                         MLAN_RATE_INDEX_OFDM0) ? pmpriv->tx_rate -
+                        1 : pmpriv->tx_rate;
+            } else {
+                rate->param.rate_cfg.rate =
+                    wlan_index_to_data_rate(pmadapter, pmpriv->tx_rate,
+                                            pmpriv->tx_htinfo);
+            }
+        } else if (rate->sub_command == MLAN_OID_GET_DATA_RATE) {
+            if (pmpriv->tx_htinfo & MBIT(0))
+                rate->param.data_rate.tx_data_rate =
+                    pmpriv->tx_rate + MLAN_RATE_INDEX_MCS0;
+            else
+                /* For HostCmd_CMD_802_11_TX_RATE_QUERY, there is a hole in
+                   rate table between HR/DSSS and OFDM rates, so minus 1 for
+                   OFDM rate index */
+                rate->param.data_rate.tx_data_rate =
+                    (pmpriv->tx_rate >
+                     MLAN_RATE_INDEX_OFDM0) ? pmpriv->tx_rate -
+                    1 : pmpriv->tx_rate;
+            if (pmpriv->rxpd_htinfo & MBIT(0))
+                rate->param.data_rate.rx_data_rate =
+                    pmpriv->rxpd_rate + MLAN_RATE_INDEX_MCS0;
+            else
+                /* For rate index in RxPD, there is a hole in rate table
+                   between HR/DSSS and OFDM rates, so minus 1 for OFDM rate
+                   index */
+                rate->param.data_rate.rx_data_rate =
+                    (pmpriv->rxpd_rate >
+                     MLAN_RATE_INDEX_OFDM0) ? pmpriv->rxpd_rate -
+                    1 : pmpriv->rxpd_rate;
+        }
+        pioctl_buf->data_read_written =
+            sizeof(mlan_multicast_list) + MLAN_SUB_COMMAND_SIZE;
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles the command response of deauthenticate
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_deauthenticate(IN pmlan_private pmpriv,
+                               IN HostCmd_DS_COMMAND * resp,
+                               IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    ENTER();
+
+    pmadapter->dbg.num_cmd_deauth++;
+    if (!memcmp(resp->params.deauth.mac_addr,
+                &pmpriv->curr_bss_params.bss_descriptor.mac_address,
+                sizeof(resp->params.deauth.mac_addr))) {
+        wlan_reset_connect_state(pmpriv);
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles the command response of ad_hoc_stop
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_ad_hoc_stop(IN pmlan_private pmpriv,
+                            IN HostCmd_DS_COMMAND * resp,
+                            IN mlan_ioctl_req * pioctl_buf)
+{
+    ENTER();
+
+    wlan_reset_connect_state(pmpriv);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of key_material
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_key_material(IN pmlan_private pmpriv,
+                             IN HostCmd_DS_COMMAND * resp,
+                             IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_KEY_MATERIAL *pkey = &resp->params.key_material;
+
+    ENTER();
+
+    if (wlan_le16_to_cpu(pkey->action) == HostCmd_ACT_GEN_SET) {
+        if ((wlan_le16_to_cpu(pkey->key_param_set.key_info) &
+             KEY_INFO_TKIP_MCAST)) {
+            PRINTM(MINFO, "key: GTK is set\n");
+            pmpriv->wpa_is_gtk_set = MTRUE;
+
+        }
+    }
+
+    memset(pmpriv->aes_key.key_param_set.key, 0,
+           sizeof(pkey->key_param_set.key));
+    pmpriv->aes_key.key_param_set.key_len =
+        wlan_le16_to_cpu(pkey->key_param_set.key_len);
+    memcpy(pmpriv->aes_key.key_param_set.key, pkey->key_param_set.key,
+           pmpriv->aes_key.key_param_set.key_len);
+
+    HEXDUMP("CMD_RESP (Key_Material)", pmpriv->aes_key.key_param_set.key,
+            pmpriv->aes_key.key_param_set.key_len);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Handle the supplicant pmk response
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_supplicant_pmk(IN pmlan_private pmpriv,
+                               IN HostCmd_DS_COMMAND * resp,
+                               IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_SUPPLICANT_PMK *supplicant_pmk_resp =
+        &resp->params.esupplicant_psk;
+    mlan_ds_sec_cfg *sec = MNULL;
+    MrvlIEtypes_PMK_t *ppmk_tlv = MNULL;
+    MrvlIEtypes_Passphrase_t *passphrase_tlv = MNULL;
+    MrvlIEtypes_SsIdParamSet_t *pssid_tlv = MNULL;
+    MrvlIEtypes_Bssid_t *pbssid_tlv = MNULL;
+    t_u8 *tlv_buf = (t_u8 *) supplicant_pmk_resp->tlv_buffer;
+    t_u16 action = wlan_le16_to_cpu(supplicant_pmk_resp->action);
+    int tlv_buf_len = 0;
+    t_u16 tlv;
+
+    ENTER();
+    tlv_buf_len = resp->size - (sizeof(HostCmd_DS_802_11_SUPPLICANT_PMK) +
+                                S_DS_GEN - 1);
+    if (pioctl_buf) {
+        sec = (mlan_ds_sec_cfg *) pioctl_buf->pbuf;
+        if (action == HostCmd_ACT_GEN_GET) {
+            while (tlv_buf_len > 0) {
+                tlv = (*tlv_buf) | (*(tlv_buf + 1) << 8);
+                if ((tlv != TLV_TYPE_SSID) && (tlv != TLV_TYPE_BSSID) &&
+                    (tlv != TLV_TYPE_PASSPHRASE)
+                    && (tlv != TLV_TYPE_PMK))
+                    break;
+                switch (tlv) {
+                case TLV_TYPE_SSID:
+                    pssid_tlv = (MrvlIEtypes_SsIdParamSet_t *) tlv_buf;
+                    pssid_tlv->header.len =
+                        wlan_le16_to_cpu(pssid_tlv->header.len);
+                    memcpy(sec->param.passphrase.ssid.ssid, pssid_tlv->ssid,
+                           pssid_tlv->header.len);
+                    sec->param.passphrase.ssid.ssid_len = pssid_tlv->header.len;
+                    tlv_buf +=
+                        pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t);
+                    tlv_buf_len -=
+                        (pssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+                    break;
+                case TLV_TYPE_BSSID:
+                    pbssid_tlv = (MrvlIEtypes_Bssid_t *) tlv_buf;
+                    pbssid_tlv->header.len =
+                        wlan_le16_to_cpu(pbssid_tlv->header.len);
+                    memcpy(&sec->param.passphrase.bssid, pbssid_tlv->bssid,
+                           MLAN_MAC_ADDR_LENGTH);
+                    tlv_buf +=
+                        pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t);
+                    tlv_buf_len -=
+                        (pbssid_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+                    break;
+                case TLV_TYPE_PASSPHRASE:
+                    passphrase_tlv = (MrvlIEtypes_Passphrase_t *) tlv_buf;
+                    passphrase_tlv->header.len =
+                        wlan_le16_to_cpu(passphrase_tlv->header.len);
+                    sec->param.passphrase.psk_type = MLAN_PSK_PASSPHRASE;
+                    sec->param.passphrase.psk.passphrase.passphrase_len =
+                        passphrase_tlv->header.len;
+                    memcpy(sec->param.passphrase.psk.passphrase.passphrase,
+                           passphrase_tlv->passphrase,
+                           passphrase_tlv->header.len);
+                    tlv_buf +=
+                        passphrase_tlv->header.len +
+                        sizeof(MrvlIEtypesHeader_t);
+                    tlv_buf_len -=
+                        (passphrase_tlv->header.len +
+                         sizeof(MrvlIEtypesHeader_t));
+                    break;
+                case TLV_TYPE_PMK:
+                    ppmk_tlv = (MrvlIEtypes_PMK_t *) tlv_buf;
+                    ppmk_tlv->header.len =
+                        wlan_le16_to_cpu(ppmk_tlv->header.len);
+                    sec->param.passphrase.psk_type = MLAN_PSK_PMK;
+                    memcpy(sec->param.passphrase.psk.pmk.pmk, ppmk_tlv->pmk,
+                           ppmk_tlv->header.len);
+                    tlv_buf +=
+                        ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t);
+                    tlv_buf_len -=
+                        (ppmk_tlv->header.len + sizeof(MrvlIEtypesHeader_t));
+                    break;
+
+                }
+            }
+        }
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Handle the supplicant profile response
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_supplicant_profile(IN pmlan_private pmpriv,
+                                   IN HostCmd_DS_COMMAND * resp,
+                                   IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_SUPPLICANT_PROFILE *psup_profile =
+        &resp->params.esupplicant_profile;
+    MrvlIEtypesHeader_t *head;
+    MrvlIEtypes_EncrProto_t *encr_proto_tlv = MNULL;
+    MrvlIEtypes_Cipher_t *pcipher_tlv = MNULL;
+    mlan_ds_sec_cfg *sec = MNULL;
+    t_u8 *tlv;
+    int len;
+
+    ENTER();
+
+    len = resp->size - S_DS_GEN - sizeof(t_u16);
+    tlv = psup_profile->tlv_buf;
+    if (pioctl_buf) {
+        sec = (mlan_ds_sec_cfg *) pioctl_buf->pbuf;
+        while (len > 0) {
+            head = (MrvlIEtypesHeader_t *) tlv;
+            head->type = wlan_le16_to_cpu(head->type);
+            head->len = wlan_le16_to_cpu(head->len);
+            switch (head->type) {
+            case TLV_TYPE_ENCRYPTION_PROTO:
+                encr_proto_tlv = (MrvlIEtypes_EncrProto_t *) head;
+                sec->param.esupp_mode.rsn_mode =
+                    wlan_le16_to_cpu(encr_proto_tlv->rsn_mode);
+                PRINTM(MCMND, "rsn_mode=0x%x\n",
+                       sec->param.esupp_mode.rsn_mode);
+                break;
+            case TLV_TYPE_CIPHER:
+                pcipher_tlv = (MrvlIEtypes_Cipher_t *) head;
+                sec->param.esupp_mode.act_paircipher = pcipher_tlv->pair_cipher;
+                sec->param.esupp_mode.act_groupcipher =
+                    pcipher_tlv->group_cipher;
+                PRINTM(MCMND, "paircipher=0x%x, groupcipher=0x%x\n",
+                       sec->param.esupp_mode.act_paircipher,
+                       sec->param.esupp_mode.act_groupcipher);
+                break;
+            }
+            len -= (head->len - sizeof(MrvlIEtypesHeader_t));
+            tlv = tlv + (head->len + sizeof(MrvlIEtypesHeader_t));
+        }
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of rf_channel
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_rf_channel(IN pmlan_private pmpriv,
+                           IN HostCmd_DS_COMMAND * resp,
+                           IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_RF_CHANNEL *prf_channel = &resp->params.rf_channel;
+    t_u16 new_channel = wlan_le16_to_cpu(prf_channel->current_channel);
+    mlan_ds_bss *bss = MNULL;
+    ENTER();
+    if (pmpriv->curr_bss_params.bss_descriptor.channel != new_channel) {
+        PRINTM(MCMND, "Channel Switch: %d to %d\n",
+               pmpriv->curr_bss_params.bss_descriptor.channel, new_channel);
+        /* Update the channel again */
+        pmpriv->curr_bss_params.bss_descriptor.channel = new_channel;
+    }
+    if (pioctl_buf) {
+        bss = (mlan_ds_bss *) pioctl_buf->pbuf;
+        bss->param.bss_chan.channel = new_channel;
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles the command response of rf_antenna
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_802_11_rf_antenna(IN pmlan_private pmpriv,
+                           IN HostCmd_DS_COMMAND * resp,
+                           IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_RF_ANTENNA *pantenna = &resp->params.antenna;
+    t_u16 ant_mode = wlan_le16_to_cpu(pantenna->antenna_mode);
+    mlan_ds_radio_cfg *radio = MNULL;
+
+    ENTER();
+
+    PRINTM(MINFO, "RF_ANT_RESP: action = 0x%x, Mode = 0x%04x\n",
+           wlan_le16_to_cpu(pantenna->action), ant_mode);
+
+    if (pioctl_buf) {
+        radio = (mlan_ds_radio_cfg *) pioctl_buf->pbuf;
+        radio->param.antenna = ant_mode;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Handle the version_ext resp
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_ver_ext(IN pmlan_private pmpriv,
+                 IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_VERSION_EXT *ver_ext = &resp->params.verext;
+    mlan_ds_get_info *info;
+    ENTER();
+    if (pioctl_buf) {
+        info = (mlan_ds_get_info *) pioctl_buf->pbuf;
+        info->param.ver_ext.version_str_sel = ver_ext->version_str_sel;
+        memcpy(info->param.ver_ext.version_str, ver_ext->version_str,
+               sizeof(char) * 128);
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Handle the ibss_coalescing_status resp
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_ibss_coalescing_status(IN pmlan_private pmpriv,
+                                IN HostCmd_DS_COMMAND * resp)
+{
+    HostCmd_DS_802_11_IBSS_STATUS *pibss_coal_resp =
+        &(resp->params.ibss_coalescing);
+    t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = { 0, 0, 0, 0, 0, 0 };
+
+    ENTER();
+
+    if (wlan_le16_to_cpu(pibss_coal_resp->action) == HostCmd_ACT_GEN_SET) {
+        LEAVE();
+        return MLAN_STATUS_SUCCESS;
+    }
+
+    PRINTM(MINFO, "New BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
+           pibss_coal_resp->bssid[0], pibss_coal_resp->bssid[1],
+           pibss_coal_resp->bssid[2], pibss_coal_resp->bssid[3],
+           pibss_coal_resp->bssid[4], pibss_coal_resp->bssid[5]);
+
+    /* If rsp has MNULL BSSID, Just return..... No Action */
+    if (!memcmp(pibss_coal_resp->bssid, zero_mac, MLAN_MAC_ADDR_LENGTH)) {
+        PRINTM(MMSG, "New BSSID is MNULL\n");
+        LEAVE();
+        return MLAN_STATUS_SUCCESS;
+    }
+
+    /* If BSSID is diff, modify current BSS parameters */
+    if (memcmp(pmpriv->curr_bss_params.bss_descriptor.mac_address,
+               pibss_coal_resp->bssid, MLAN_MAC_ADDR_LENGTH)) {
+        /* BSSID */
+        memcpy(pmpriv->curr_bss_params.bss_descriptor.mac_address,
+               pibss_coal_resp->bssid, MLAN_MAC_ADDR_LENGTH);
+
+        /* Beacon Interval and ATIM window */
+        pmpriv->curr_bss_params.bss_descriptor.beacon_period
+            = wlan_le16_to_cpu(pibss_coal_resp->beacon_interval);
+        pmpriv->curr_bss_params.bss_descriptor.atim_window
+            = wlan_le16_to_cpu(pibss_coal_resp->atim_window);
+
+        /* ERP Information */
+        pmpriv->curr_bss_params.bss_descriptor.erp_flags
+            = (t_u8) wlan_le16_to_cpu(pibss_coal_resp->use_g_rate_protect);
+
+        pmpriv->adhoc_state = ADHOC_COALESCED;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+#ifdef MFG_CMD_SUPPORT
+/** 
+ *  @brief This function handles the command response of mfg_cmd
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_mfg_cmd(IN pmlan_private pmpriv,
+                 IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_misc_cfg *misc;
+
+    ENTER();
+
+    PRINTM(MINFO, "MFG command response size = %d\n", resp->size);
+    resp->size = MIN(resp->size, MRVDRV_SIZE_OF_CMD_BUFFER);
+    if (pioctl_buf) {
+        misc = (mlan_ds_misc_cfg *) pioctl_buf->pbuf;
+        misc->param.mfgcmd.len = resp->size;
+        memcpy(misc->param.mfgcmd.cmd, (void *) resp, resp->size);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+#endif /* MFG_CMD_SUPPORT */
+
+/** 
+ *  @brief This function handles the command response of ldo_cfg
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_ldo_cfg(IN pmlan_private pmpriv,
+                 IN HostCmd_DS_COMMAND * resp, IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_misc_cfg *mis_ccfg = MNULL;
+    HostCmd_DS_802_11_LDO_CFG *pldo_cfg = &resp->params.ldo_cfg;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        mis_ccfg = (mlan_ds_misc_cfg *) pioctl_buf->pbuf;
+        mis_ccfg->param.ldo_cfg = wlan_le16_to_cpu(pldo_cfg->pmsource);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of sysclock
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+static mlan_status
+wlan_ret_sysclock_cfg(IN pmlan_private pmpriv,
+                      IN HostCmd_DS_COMMAND * resp,
+                      IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_misc_cfg *mis_ccfg = MNULL;
+    HostCmd_DS_ECL_SYSTEM_CLOCK_CONFIG *clk_cfg = &resp->params.sys_clock_cfg;
+    int i = 0;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        mis_ccfg = (mlan_ds_misc_cfg *) pioctl_buf->pbuf;
+        mis_ccfg->param.sys_clock.cur_sys_clk =
+            wlan_le16_to_cpu(clk_cfg->cur_sys_clk);
+        mis_ccfg->param.sys_clock.sys_clk_type =
+            wlan_le16_to_cpu(clk_cfg->sys_clk_type);
+        mis_ccfg->param.sys_clock.sys_clk_num =
+            wlan_le16_to_cpu(clk_cfg->sys_clk_len) / sizeof(t_u16);
+        for (i = 0; i < mis_ccfg->param.sys_clock.sys_clk_num; i++)
+            mis_ccfg->param.sys_clock.sys_clk[i] =
+                wlan_le16_to_cpu(clk_cfg->sys_clk[i]);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of reg_access
+ *  
+ *  @param type         The type of reg access (MAC, BBP or RF)
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to command buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_ret_reg_access(t_u16 type,
+                    IN HostCmd_DS_COMMAND * resp,
+                    IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_reg_mem *reg_mem = MNULL;
+    mlan_ds_reg_rw *reg_rw = MNULL;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        reg_mem = (mlan_ds_reg_mem *) pioctl_buf->pbuf;
+        reg_rw = &reg_mem->param.reg_rw;
+        switch (type) {
+        case HostCmd_CMD_MAC_REG_ACCESS:
+            {
+                HostCmd_DS_MAC_REG_ACCESS *reg;
+                reg = (HostCmd_DS_MAC_REG_ACCESS *) & resp->params.mac_reg;
+                reg_rw->offset = (t_u32) wlan_le16_to_cpu(reg->offset);
+                reg_rw->value = wlan_le32_to_cpu(reg->value);
+                break;
+            }
+        case HostCmd_CMD_BBP_REG_ACCESS:
+            {
+                HostCmd_DS_BBP_REG_ACCESS *reg;
+                reg = (HostCmd_DS_BBP_REG_ACCESS *) & resp->params.bbp_reg;
+                reg_rw->offset = (t_u32) wlan_le16_to_cpu(reg->offset);
+                reg_rw->value = (t_u32) reg->value;
+                break;
+            }
+
+        case HostCmd_CMD_RF_REG_ACCESS:
+            {
+                HostCmd_DS_RF_REG_ACCESS *reg;
+                reg = (HostCmd_DS_RF_REG_ACCESS *) & resp->params.rf_reg;
+                reg_rw->offset = (t_u32) wlan_le16_to_cpu(reg->offset);
+                reg_rw->value = (t_u32) reg->value;
+                break;
+            }
+        case HostCmd_CMD_PMIC_REG_ACCESS:
+            {
+                HostCmd_DS_PMIC_REG_ACCESS *reg;
+                reg = (HostCmd_DS_PMIC_REG_ACCESS *) & resp->params.pmic_reg;
+                reg_rw->offset = (t_u32) wlan_le16_to_cpu(reg->offset);
+                reg_rw->value = (t_u32) reg->value;
+                break;
+            }
+        case HostCmd_CMD_CAU_REG_ACCESS:
+            {
+                HostCmd_DS_RF_REG_ACCESS *reg;
+                reg = (HostCmd_DS_RF_REG_ACCESS *) & resp->params.rf_reg;
+                reg_rw->offset = (t_u32) wlan_le16_to_cpu(reg->offset);
+                reg_rw->value = (t_u32) reg->value;
+                break;
+            }
+        case HostCmd_CMD_802_11_EEPROM_ACCESS:
+            {
+                mlan_ds_read_eeprom *eeprom = &reg_mem->param.rd_eeprom;
+                HostCmd_DS_802_11_EEPROM_ACCESS *cmd_eeprom =
+                    (HostCmd_DS_802_11_EEPROM_ACCESS *) & resp->params.eeprom;
+                cmd_eeprom->byte_count =
+                    wlan_le16_to_cpu(cmd_eeprom->byte_count);
+                PRINTM(MINFO, "EEPROM read len=%x\n", cmd_eeprom->byte_count);
+                if (eeprom->byte_count < cmd_eeprom->byte_count) {
+                    eeprom->byte_count = 0;
+                    PRINTM(MINFO, "EEPROM read return length is too big\n");
+                    LEAVE();
+                    return MLAN_STATUS_FAILURE;
+                }
+                eeprom->offset = wlan_le16_to_cpu(cmd_eeprom->offset);
+                eeprom->byte_count = cmd_eeprom->byte_count;
+                if (eeprom->byte_count > 0) {
+                    memcpy(&eeprom->value, &cmd_eeprom->value,
+                           eeprom->byte_count);
+                    HEXDUMP("EEPROM", (char *) &eeprom->value,
+                            eeprom->byte_count);
+                }
+                break;
+            }
+        default:
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of mem_access
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to command buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_ret_mem_access(IN pmlan_private pmpriv,
+                    IN HostCmd_DS_COMMAND * resp,
+                    IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_reg_mem *reg_mem = MNULL;
+    mlan_ds_mem_rw *mem_rw = MNULL;
+    HostCmd_DS_MEM_ACCESS *mem = (HostCmd_DS_MEM_ACCESS *) & resp->params.mem;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        reg_mem = (mlan_ds_reg_mem *) pioctl_buf->pbuf;
+        mem_rw = &reg_mem->param.mem_rw;
+
+        mem_rw->addr = wlan_le32_to_cpu(mem->addr);
+        mem_rw->value = wlan_le32_to_cpu(mem->value);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of inactivity timeout
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp	        A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to command buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_ret_inactivity_timeout(IN pmlan_private pmpriv,
+                            IN HostCmd_DS_COMMAND * resp,
+                            IN mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_pm_cfg *pmcfg = MNULL;
+    mlan_ds_inactivity_to *inac_to = MNULL;
+    HostCmd_DS_INACTIVITY_TIMEOUT_EXT *cmd_inac_to =
+        (HostCmd_DS_INACTIVITY_TIMEOUT_EXT *) & resp->params.inactivity_to;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        pmcfg = (mlan_ds_pm_cfg *) pioctl_buf->pbuf;
+        inac_to = &pmcfg->param.inactivity_to;
+        inac_to->timeout_unit = wlan_le16_to_cpu(cmd_inac_to->timeout_unit);
+        inac_to->unicast_timeout =
+            wlan_le16_to_cpu(cmd_inac_to->unicast_timeout);
+        inac_to->mcast_timeout = wlan_le16_to_cpu(cmd_inac_to->mcast_timeout);
+        inac_to->ps_entry_timeout =
+            wlan_le16_to_cpu(cmd_inac_to->ps_entry_timeout);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function handles the command response of bca_timeshare
+ *  
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp	        A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to command buffer
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static mlan_status
+wlan_ret_802_11_bca_timeshare(pmlan_private pmpriv,
+                              IN HostCmd_DS_COMMAND * resp,
+                              IN mlan_ioctl_req * pioctl_buf)
+{
+    HostCmd_DS_802_11_BCA_TIMESHARE *bca_ts = &resp->params.bca_timeshare;
+    mlan_ds_bca_cfg *bca_cfg = MNULL;
+
+    ENTER();
+
+    PRINTM(MINFO, "TrafficType=0x%x TimeShareInterva=0x%x BTTime=0x%x\n",
+           wlan_le16_to_cpu(bca_ts->traffic_type),
+           wlan_le32_to_cpu(bca_ts->timeshare_interval),
+           wlan_le32_to_cpu(bca_ts->bt_time));
+    if (pioctl_buf) {
+        bca_cfg = (mlan_ds_bca_cfg *) pioctl_buf->pbuf;
+        bca_cfg->param.bca_ts.traffic_type =
+            wlan_le16_to_cpu(bca_ts->traffic_type);
+        bca_cfg->param.bca_ts.timeshare_interval =
+            wlan_le32_to_cpu(bca_ts->timeshare_interval);
+        bca_cfg->param.bca_ts.bt_time = wlan_le32_to_cpu(bca_ts->bt_time);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/********************************************************
+                Global Functions
+********************************************************/
+/** 
+ *  @brief This function handles the station command response
+ *  
+ *  @param priv             A pointer to mlan_private structure
+ *  @param cmdresp_no       cmd no
+ *  @param pcmd_buf         cmdresp buf
+ *  @param pioctl           A pointer to ioctl buf
+ *
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+mlan_process_sta_cmdresp(IN t_void * priv,
+                         IN t_u16 cmdresp_no,
+                         IN t_void * pcmd_buf, IN t_void * pioctl)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = (mlan_private *) priv;
+    HostCmd_DS_COMMAND *resp = (HostCmd_DS_COMMAND *) pcmd_buf;
+    mlan_ioctl_req *pioctl_buf = (mlan_ioctl_req *) pioctl;
+    mlan_adapter *pmadapter = pmpriv->adapter;
+    int ctr;
+    /* If the command is not successful, cleanup and return failure */
+    if ((resp->result != HostCmd_RESULT_OK)
+        ) {
+        wlan_process_cmdresp_error(pmpriv, resp, pioctl_buf);
+        return MLAN_STATUS_FAILURE;
+    }
+    /* Command successful, handle response */
+    switch (cmdresp_no) {
+    case HostCmd_CMD_GET_HW_SPEC:
+        ret = wlan_ret_get_hw_spec(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_MAC_CONTROL:
+        ret = wlan_ret_mac_control(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_MAC_ADDRESS:
+        ret = wlan_ret_802_11_mac_address(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_MAC_MULTICAST_ADR:
+        ret = wlan_ret_mac_multicast_adr(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_TX_RATE_CFG:
+        ret = wlan_ret_tx_rate_cfg(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_SCAN:
+        ret = wlan_ret_802_11_scan(pmpriv, resp, pioctl_buf);
+        pioctl_buf = MNULL;
+        pmadapter->curr_cmd->pioctl_buf = MNULL;
+        break;
+    case HostCmd_CMD_802_11_BG_SCAN_QUERY:
+        ret = wlan_ret_802_11_scan(pmpriv, resp, pioctl_buf);
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BG_SCAN, MNULL);
+        PRINTM(MINFO, "CMD_RESP: BG_SCAN result is ready!\n");
+        break;
+    case HostCmd_CMD_TXPWR_CFG:
+        ret = wlan_ret_tx_power_cfg(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_PS_MODE_ENH:
+        ret = wlan_ret_802_11_opt_ps_mode(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_HS_CFG_ENH:
+        ret = wlan_ret_802_11_hs_cfg(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_SLEEP_PERIOD:
+        ret = wlan_ret_802_11_sleep_period(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_SLEEP_PARAMS:
+        ret = wlan_ret_802_11_sleep_params(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_ASSOCIATE:
+        ret = wlan_ret_802_11_associate(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_DEAUTHENTICATE:
+        ret = wlan_ret_802_11_deauthenticate(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_AD_HOC_START:
+    case HostCmd_CMD_802_11_AD_HOC_JOIN:
+        ret = wlan_ret_802_11_ad_hoc(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_AD_HOC_STOP:
+        ret = wlan_ret_802_11_ad_hoc_stop(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_GET_LOG:
+        ret = wlan_ret_get_log(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_RSSI_INFO:
+        ret = wlan_ret_802_11_rssi_info(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_SNMP_MIB:
+        ret = wlan_ret_802_11_snmp_mib(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_RADIO_CONTROL:
+        ret = wlan_ret_802_11_radio_control(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_TX_RATE_QUERY:
+        ret = wlan_ret_802_11_tx_rate_query(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_RF_CHANNEL:
+        ret = wlan_ret_802_11_rf_channel(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_RF_ANTENNA:
+        ret = wlan_ret_802_11_rf_antenna(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_VERSION_EXT:
+        ret = wlan_ret_ver_ext(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_FUNC_INIT:
+    case HostCmd_CMD_FUNC_SHUTDOWN:
+        break;
+    case HostCmd_CMD_802_11_KEY_MATERIAL:
+        ret = wlan_ret_802_11_key_material(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_SUPPLICANT_PMK:
+        ret = wlan_ret_802_11_supplicant_pmk(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_SUPPLICANT_PROFILE:
+        ret = wlan_ret_802_11_supplicant_profile(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11D_DOMAIN_INFO:
+        ret = wlan_ret_802_11d_domain_info(pmpriv, resp);
+        break;
+    case HostCmd_CMD_802_11_TPC_ADAPT_REQ:
+    case HostCmd_CMD_802_11_TPC_INFO:
+    case HostCmd_CMD_802_11_CHAN_SW_ANN:
+        ret = wlan_11h_cmdresp_process(pmpriv, resp);
+        break;
+    case HostCmd_CMD_11N_ADDBA_REQ:
+        ret = wlan_ret_11n_addba_req(pmpriv, resp);
+        break;
+    case HostCmd_CMD_11N_DELBA:
+        ret = wlan_ret_11n_delba(pmpriv, resp);
+        break;
+    case HostCmd_CMD_11N_ADDBA_RSP:
+        ret = wlan_ret_11n_addba_resp(pmpriv, resp);
+        break;
+    case HostCmd_CMD_RECONFIGURE_TX_BUFF:
+        pmadapter->tx_buf_size = (t_u16) wlan_le16_to_cpu(resp->params.
+                                                          tx_buf.buff_size);
+        pmadapter->mp_end_port = wlan_le16_to_cpu(resp->params.
+                                                  tx_buf.mp_end_port);
+        pmadapter->mp_data_port_mask = DATA_PORT_MASK;
+
+        for (ctr = 1; ctr <= MAX_PORT - pmadapter->mp_end_port; ctr++) {
+            pmadapter->mp_data_port_mask &= ~(1 << (MAX_PORT - ctr));
+        }
+
+        pmadapter->curr_wr_port = 1;
+        PRINTM(MCMND, "end port %d, data port mask %x\n",
+               wlan_le16_to_cpu(resp->params.tx_buf.mp_end_port),
+               pmadapter->mp_data_port_mask);
+        PRINTM(MCMND, "max_tx_buf_size=%d, tx_buf_size=%d\n",
+               pmadapter->max_tx_buf_size, pmadapter->tx_buf_size);
+        break;
+    case HostCmd_CMD_AMSDU_AGGR_CTRL:
+        ret = wlan_ret_amsdu_aggr_ctrl(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_WMM_GET_STATUS:
+        ret = wlan_ret_wmm_get_status(pmpriv, resp);
+        break;
+    case HostCmd_CMD_WMM_ADDTS_REQ:
+        ret = wlan_ret_wmm_addts_req(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_WMM_DELTS_REQ:
+        ret = wlan_ret_wmm_delts_req(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_WMM_QUEUE_CONFIG:
+        ret = wlan_ret_wmm_queue_config(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_WMM_QUEUE_STATS:
+        ret = wlan_ret_wmm_queue_stats(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_WMM_TS_STATUS:
+        ret = wlan_ret_wmm_ts_status(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
+        ret = wlan_ret_ibss_coalescing_status(pmpriv, resp);
+        break;
+#ifdef MFG_CMD_SUPPORT
+    case HostCmd_CMD_MFG_COMMAND:
+        ret = wlan_ret_mfg_cmd(pmpriv, resp, pioctl_buf);
+        break;
+#endif
+    case HostCmd_CMD_11N_CFG:
+        ret = wlan_ret_11n_cfg(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_LDO_CONFIG:
+        ret = wlan_ret_ldo_cfg(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG:
+        ret = wlan_ret_sysclock_cfg(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_MAC_REG_ACCESS:
+    case HostCmd_CMD_BBP_REG_ACCESS:
+    case HostCmd_CMD_RF_REG_ACCESS:
+    case HostCmd_CMD_PMIC_REG_ACCESS:
+    case HostCmd_CMD_CAU_REG_ACCESS:
+    case HostCmd_CMD_802_11_EEPROM_ACCESS:
+        ret = wlan_ret_reg_access(cmdresp_no, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_MEM_ACCESS:
+        ret = wlan_ret_mem_access(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_INACTIVITY_TIMEOUT_EXT:
+        ret = wlan_ret_inactivity_timeout(pmpriv, resp, pioctl_buf);
+        break;
+    case HostCmd_CMD_802_11_BCA_CONFIG_TIMESHARE:
+        ret = wlan_ret_802_11_bca_timeshare(pmpriv, resp, pioctl_buf);
+        break;
+    default:
+        PRINTM(MERROR, "CMD_RESP: Unknown command response %#x\n",
+               resp->command);
+        break;
+    }
+    return ret;
+}
diff --git a/wlan_src/mlan/mlan_sta_event.c b/wlan_src/mlan/mlan_sta_event.c
new file mode 100755
index 0000000..1c67ad5
--- /dev/null
+++ b/wlan_src/mlan/mlan_sta_event.c
@@ -0,0 +1,453 @@
+/** @file mlan_sta_event.c
+ *  
+ *  @brief This file contains MLAN event handling.
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    10/13/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_11h.h"
+
+/********************************************************
+        Global Variables
+********************************************************/
+
+/********************************************************
+        Local Functions
+********************************************************/
+
+/********************************************************
+        Global Functions
+********************************************************/
+/** 
+ *  @brief This function handles disconnect event, reports disconnect
+ *  		to upper layer, cleans tx/rx packets,
+ *  		resets link state etc.
+ *  
+ *  @param priv    A pointer to mlan_private structure
+ *
+ *  @return        N/A
+ */
+t_void
+wlan_reset_connect_state(pmlan_private priv)
+{
+    mlan_adapter *pmadapter = priv->adapter;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    state_11d_t enable;
+
+    ENTER();
+
+    if (priv->media_connected != MTRUE) {
+        LEAVE();
+        return;
+    }
+
+    PRINTM(MINFO, "Handles disconnect event.\n");
+
+    priv->media_connected = MFALSE;
+
+    /* Free Tx and Rx packets, report disconnect to upper layer */
+    wlan_clean_txrx(priv);
+
+    /* Reset SNR/NF/RSSI values */
+    priv->data_rssi_last = 0;
+    priv->data_nf_last = 0;
+    priv->data_rssi_avg = 0;
+    priv->data_nf_avg = 0;
+    priv->bcn_rssi_last = 0;
+    priv->bcn_nf_last = 0;
+    priv->bcn_rssi_avg = 0;
+    priv->bcn_nf_avg = 0;
+    priv->rxpd_rate = 0;
+    priv->rxpd_htinfo = 0;
+
+    PRINTM(MINFO, "Current SSID=%s, SSID Length=%u\n",
+           priv->curr_bss_params.bss_descriptor.ssid.ssid,
+           priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
+    PRINTM(MINFO, "Previous SSID=%s, SSID Length=%u\n",
+           priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
+    priv->sec_info.ewpa_enabled = MFALSE;
+    priv->sec_info.wpa_enabled = MFALSE;
+    priv->sec_info.wpa2_enabled = MFALSE;
+    priv->wpa_ie_len = 0;
+
+    priv->sec_info.wapi_enabled = MFALSE;
+    priv->wapi_ie_len = 0;
+    priv->sec_info.wapi_key_on = MFALSE;
+
+    priv->sec_info.encryption_mode = MLAN_ENCRYPTION_MODE_NONE;
+
+    /* Enable auto data rate */
+    priv->is_data_rate_auto = MTRUE;
+    priv->data_rate = 0;
+
+    if (priv->bss_mode == MLAN_BSS_MODE_IBSS) {
+        priv->adhoc_state = ADHOC_IDLE;
+        priv->adhoc_is_link_sensed = MFALSE;
+        priv->adhoc_auto_sel = MTRUE;
+    }
+
+    /* 
+     * Memorize the previous SSID and BSSID so
+     * it could be used for re-assoc
+     */
+
+    memcpy(&priv->prev_ssid,
+           &priv->curr_bss_params.bss_descriptor.ssid,
+           sizeof(mlan_802_11_ssid));
+
+    memcpy(priv->prev_bssid,
+           priv->curr_bss_params.bss_descriptor.mac_address,
+           MLAN_MAC_ADDR_LENGTH);
+
+    /* Need to erase the current SSID and BSSID info */
+    memset(&priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params));
+
+    pmadapter->tx_lock_flag = MFALSE;
+    pmadapter->ps_state = PS_STATE_AWAKE;
+    pmadapter->pm_wakeup_card_req = MFALSE;
+
+    if ((wlan_11d_get_state(priv) == ENABLE_11D) &&
+        (pmadapter->state_11d.user_enable_11d == DISABLE_11D)) {
+
+        pmadapter->state_11d.enable_11d = DISABLE_11D;
+        enable = DISABLE_11D;
+
+        /* Send cmd to FW to enable/disable 11D function */
+        ret = wlan_prepare_cmd(priv,
+                               HostCmd_CMD_802_11_SNMP_MIB,
+                               HostCmd_ACT_GEN_SET, Dot11D_i, MNULL, &enable);
+        if (ret)
+            PRINTM(MERROR, "11D: Failed to enable 11D\n");
+    }
+    if (pmadapter->num_cmd_timeout && pmadapter->curr_cmd &&
+        (pmadapter->cmd_timer_is_set == MFALSE)) {
+        LEAVE();
+        return;
+    }
+    wlan_recv_event(priv, MLAN_EVENT_ID_FW_DISCONNECTED, MNULL);
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function handles link lost, deauth and
+ *  		disassoc events.
+ *  
+ *  @param priv    A pointer to mlan_private structure
+ *  @return        N/A
+ */
+static void
+wlan_handle_disconnect_event(pmlan_private priv)
+{
+    ENTER();
+    if (priv->media_connected == MTRUE) {
+        wlan_reset_connect_state(priv);
+    }
+    LEAVE();
+}
+
+/** 
+ *  @brief This function sends the OBSS scan parameters to the application
+ *  
+ *  @param pmpriv     A pointer to mlan_private structure
+ *
+ *  @return           N/A
+ */
+t_void
+wlan_2040_coex_event(pmlan_private pmpriv)
+{
+    t_u8 event_buf[100];
+    mlan_event *pevent = (mlan_event *) event_buf;
+    t_u8 ele_len;
+
+    ENTER();
+
+    if (pmpriv->curr_bss_params.bss_descriptor.poverlap_bss_scan_param &&
+        pmpriv->curr_bss_params.bss_descriptor.poverlap_bss_scan_param->
+        ieee_hdr.element_id == OVERLAPBSSSCANPARAM) {
+        ele_len =
+            pmpriv->curr_bss_params.bss_descriptor.poverlap_bss_scan_param->
+            ieee_hdr.len;
+        pevent->bss_num = pmpriv->bss_num;
+        pevent->event_id = MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM;
+        /* Copy OBSS scan parameters */
+        memcpy((t_u8 *) pevent->event_buf,
+               (t_u8 *) & pmpriv->curr_bss_params.bss_descriptor.
+               poverlap_bss_scan_param->obss_scan_param, ele_len);
+        pevent->event_len = ele_len;
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM, pevent);
+    }
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function handles events generated by firmware
+ *  
+ *  @param priv	A pointer to mlan_private structure
+ *
+ *  @return		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+mlan_process_sta_event(IN t_void * priv)
+{
+    pmlan_private pmpriv = (pmlan_private) priv;
+    pmlan_adapter pmadapter = pmpriv->adapter;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u32 eventcause = pmadapter->event_cause;
+    t_u8 event_buf[100];
+    mlan_event *pevent = (mlan_event *) event_buf;
+
+    ENTER();
+
+    /* Clear BSS_NO_BITS from event */
+    eventcause &= EVENT_ID_MASK;
+    switch (eventcause) {
+    case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
+        PRINTM(MERROR,
+               "Invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignoring it\n");
+        break;
+    case EVENT_LINK_SENSED:
+        PRINTM(MEVENT, "EVENT: LINK_SENSED\n");
+        pmpriv->adhoc_is_link_sensed = MTRUE;
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED, MNULL);
+        break;
+
+    case EVENT_DEAUTHENTICATED:
+        PRINTM(MEVENT, "EVENT: Deauthenticated\n");
+        pmadapter->dbg.num_event_deauth++;
+        wlan_handle_disconnect_event(pmpriv);
+        break;
+
+    case EVENT_DISASSOCIATED:
+        PRINTM(MEVENT, "EVENT: Disassociated\n");
+        pmadapter->dbg.num_event_disassoc++;
+        wlan_handle_disconnect_event(pmpriv);
+        break;
+
+    case EVENT_LINK_LOST:
+        PRINTM(MEVENT, "EVENT: Link lost\n");
+        pmadapter->dbg.num_event_link_lost++;
+        wlan_handle_disconnect_event(pmpriv);
+        break;
+
+    case EVENT_PS_SLEEP:
+        PRINTM(MINFO, "EVENT: SLEEP\n");
+        PRINTM(MEVENT, "_");
+
+        pmadapter->ps_state = PS_STATE_PRE_SLEEP;
+
+        wlan_check_ps_cond(pmadapter);
+        break;
+
+    case EVENT_PS_AWAKE:
+        PRINTM(MINFO, "EVENT: AWAKE \n");
+        PRINTM(MEVENT, "|");
+        pmadapter->tx_lock_flag = MFALSE;
+        if (pmadapter->sleep_period.period) {
+            if (MTRUE == wlan_check_last_packet_indication(pmpriv)) {
+                if (!pmadapter->data_sent && pmpriv->gen_null_pkg) {
+                    wlan_send_null_packet(pmpriv,
+                                          MRVDRV_TxPD_POWER_MGMT_NULL_PACKET |
+                                          MRVDRV_TxPD_POWER_MGMT_LAST_PACKET);
+                    pmadapter->ps_state = PS_STATE_SLEEP;
+                    return MLAN_STATUS_SUCCESS;
+                }
+            }
+        }
+        pmadapter->ps_state = PS_STATE_AWAKE;
+        pmadapter->pm_wakeup_card_req = MFALSE;
+        pmadapter->pm_wakeup_fw_try = MFALSE;
+
+        break;
+
+    case EVENT_DEEP_SLEEP_AWAKE:
+        wlan_pm_reset_card(pmadapter);
+        PRINTM(MEVENT, "EVENT: DS_AWAKE\n");
+        if (pmadapter->is_deep_sleep == MTRUE) {
+            pmadapter->is_deep_sleep = MFALSE;
+        }
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DS_AWAKE, MNULL);
+        break;
+
+    case EVENT_HS_ACT_REQ:
+        PRINTM(MEVENT, "EVENT: HS_ACT_REQ\n");
+        ret = wlan_prepare_cmd(priv,
+                               HostCmd_CMD_802_11_HS_CFG_ENH,
+                               0, 0, MNULL, MNULL);
+        break;
+
+    case EVENT_MIC_ERR_UNICAST:
+        PRINTM(MEVENT, "EVENT: UNICAST MIC ERROR\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_UNI, MNULL);
+        break;
+
+    case EVENT_MIC_ERR_MULTICAST:
+        PRINTM(MEVENT, "EVENT: MULTICAST MIC ERROR\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MIC_ERR_MUL, MNULL);
+        break;
+    case EVENT_MIB_CHANGED:
+    case EVENT_INIT_DONE:
+        break;
+
+    case EVENT_ADHOC_BCN_LOST:
+        PRINTM(MEVENT, "EVENT: ADHOC_BCN_LOST\n");
+        pmpriv->adhoc_is_link_sensed = MFALSE;
+        wlan_clean_txrx(pmpriv);
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_ADHOC_LINK_LOST, MNULL);
+        break;
+    case EVENT_BG_SCAN_REPORT:
+        PRINTM(MEVENT, "EVENT: BGS_REPORT\n");
+        /* Clear the previous scan result */
+        memset(pmadapter->pscan_table, 0x00,
+               sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST);
+        pmadapter->num_in_scan_table = 0;
+        pmadapter->pbcn_buf_end = pmadapter->bcn_buf;
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_802_11_BG_SCAN_QUERY,
+                               HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
+        break;
+    case EVENT_STOP_TX:
+        PRINTM(MEVENT, "EVENT: Stop Tx (%#x)\n", eventcause);
+        wlan_11h_tx_disable(pmpriv);
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_STOP_TX, MNULL);
+        break;
+    case EVENT_START_TX:
+        PRINTM(MEVENT, "EVENT: Start Tx (%#x)\n", eventcause);
+        wlan_11h_tx_enable(pmpriv);
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_START_TX, MNULL);
+        break;
+    case EVENT_CHANNEL_SWITCH:
+        PRINTM(MEVENT, "EVENT: Channel Switch (%#x)\n", eventcause);
+        /* To be handled for 'chanswann' private command */
+        break;
+    case EVENT_MEAS_REPORT_RDY:
+        PRINTM(MINFO, "EVENT: Measurement Report Ready (%#x)\n", eventcause);
+        /* To be handled for 'measreq' private command */
+        break;
+    case EVENT_WMM_STATUS_CHANGE:
+        PRINTM(MEVENT, "EVENT: WMM status changed\n");
+        ret = (mlan_status) wlan_cmd_wmm_status_change(pmpriv);
+        break;
+
+    case EVENT_RSSI_LOW:
+        PRINTM(MEVENT, "EVENT: Beacon RSSI_LOW\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_RSSI_LOW, MNULL);
+        break;
+    case EVENT_SNR_LOW:
+        PRINTM(MEVENT, "EVENT: Beacon SNR_LOW\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_LOW, MNULL);
+        break;
+    case EVENT_MAX_FAIL:
+        PRINTM(MEVENT, "EVENT: MAX_FAIL\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_MAX_FAIL, MNULL);
+        break;
+    case EVENT_RSSI_HIGH:
+        PRINTM(MEVENT, "EVENT: Beacon RSSI_HIGH\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_RSSI_HIGH, MNULL);
+        break;
+    case EVENT_SNR_HIGH:
+        PRINTM(MEVENT, "EVENT: Beacon SNR_HIGH\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BCN_SNR_HIGH, MNULL);
+        break;
+    case EVENT_DATA_RSSI_LOW:
+        PRINTM(MEVENT, "EVENT: Data RSSI_LOW\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_LOW, MNULL);
+        break;
+    case EVENT_DATA_SNR_LOW:
+        PRINTM(MEVENT, "EVENT: Data SNR_LOW\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_LOW, MNULL);
+        break;
+    case EVENT_DATA_RSSI_HIGH:
+        PRINTM(MEVENT, "EVENT: Data RSSI_HIGH\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_RSSI_HIGH, MNULL);
+        break;
+    case EVENT_DATA_SNR_HIGH:
+        PRINTM(MEVENT, "EVENT: Data SNR_HIGH\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_DATA_SNR_HIGH, MNULL);
+        break;
+    case EVENT_LINK_QUALITY:
+        PRINTM(MEVENT, "EVENT: Link Quality\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_LINK_QUALITY, MNULL);
+        break;
+    case EVENT_PRE_BEACON_LOST:
+        PRINTM(MEVENT, "EVENT: Pre-Beacon Lost\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PRE_BCN_LOST, MNULL);
+        break;
+    case EVENT_IBSS_COALESCED:
+        PRINTM(MEVENT, "EVENT: IBSS_COALESCED\n");
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
+                               HostCmd_ACT_GEN_GET, 0, MNULL, MNULL);
+        break;
+    case EVENT_PORT_RELEASE:
+        PRINTM(MEVENT, "EVENT: PORT RELEASE\n");
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_PORT_RELEASE, MNULL);
+        break;
+    case EVENT_ADDBA:
+        PRINTM(MEVENT, "EVENT: ADDBA Request\n");
+        wlan_prepare_cmd(pmpriv, HostCmd_CMD_11N_ADDBA_RSP,
+                         HostCmd_ACT_GEN_SET, 0, MNULL, pmadapter->event_body);
+        break;
+    case EVENT_DELBA:
+        PRINTM(MEVENT, "EVENT: DELBA Request\n");
+        wlan_11n_delete_bastream(pmpriv, pmadapter->event_body);
+        break;
+    case EVENT_BA_STREAM_TIEMOUT:
+        PRINTM(MEVENT, "EVENT:  BA Stream timeout\n");
+        wlan_11n_ba_stream_timeout(pmpriv,
+                                   (HostCmd_DS_11N_BATIMEOUT *) pmadapter->
+                                   event_body);
+        break;
+    case EVENT_AMSDU_AGGR_CTRL:
+        PRINTM(MEVENT, "EVENT:  AMSDU_AGGR_CTRL %d\n",
+               *(t_u16 *) pmadapter->event_body);
+        pmpriv->adapter->tx_buf_size =
+            MIN(pmpriv->adapter->max_tx_buf_size,
+                wlan_le16_to_cpu(*(t_u16 *) pmadapter->event_body));
+        PRINTM(MEVENT, "tx_buf_size %d\n", pmpriv->adapter->tx_buf_size);
+        break;
+
+    case EVENT_WEP_ICV_ERR:
+        PRINTM(MEVENT, "EVENT: WEP ICV error\n");
+        pevent->bss_num = pmpriv->bss_num;
+        pevent->event_id = MLAN_EVENT_ID_FW_WEP_ICV_ERR;
+        pevent->event_len = sizeof(Event_WEP_ICV_ERR);
+        memcpy((t_u8 *) pevent->event_buf, pmadapter->event_body,
+               pevent->event_len);
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_WEP_ICV_ERR, pevent);
+        break;
+
+    case EVENT_BW_CHANGE:
+        PRINTM(MEVENT, "EVENT: BW Change\n");
+        pevent->bss_num = pmpriv->bss_num;
+        pevent->event_id = MLAN_EVENT_ID_FW_BW_CHANGED;
+        pevent->event_len = sizeof(t_u8);
+        /* Copy event body from the event buffer */
+        memcpy((t_u8 *) pevent->event_buf, pmadapter->event_body,
+               pevent->event_len);
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_BW_CHANGED, pevent);
+        break;
+
+    default:
+        PRINTM(MEVENT, "EVENT: unknown event id: %#x\n", eventcause);
+        wlan_recv_event(pmpriv, MLAN_EVENT_ID_FW_UNKNOWN, MNULL);
+        break;
+    }
+
+    LEAVE();
+    return ret;
+}
diff --git a/wlan_src/mlan/mlan_sta_ioctl.c b/wlan_src/mlan/mlan_sta_ioctl.c
new file mode 100755
index 0000000..749055f
--- /dev/null
+++ b/wlan_src/mlan/mlan_sta_ioctl.c
@@ -0,0 +1,4838 @@
+/** @file mlan_sta_ioctl.c
+ *  
+ *  @brief This file contains the functions for station ioctl.
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    10/21/2008: initial version
+******************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+                Local Variables
+********************************************************/
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+/** 
+ *  @brief enable adhoc aes key 
+ *
+ *  @param pmpriv	A pointer to mlan_private structure
+ *
+ *  @return		N/A
+ */
+void
+wlan_enable_aes_key(pmlan_private pmpriv)
+{
+    mlan_ds_encrypt_key encrypt_key;
+    if (pmpriv->aes_key.key_param_set.key_len != WPA_AES_KEY_LEN)
+        return;
+    memset(&encrypt_key, 0, sizeof(mlan_ds_encrypt_key));
+    encrypt_key.key_len = WPA_AES_KEY_LEN;
+    encrypt_key.key_index = 0x40000000;
+    memcpy(encrypt_key.key_material, pmpriv->aes_key.key_param_set.key,
+           encrypt_key.key_len);
+    wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
+                     HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, MNULL,
+                     &encrypt_key);
+    encrypt_key.key_index &= ~0x40000000;
+    wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_KEY_MATERIAL,
+                     HostCmd_ACT_GEN_SET,
+                     KEY_INFO_ENABLED, MNULL, &encrypt_key);
+    return;
+}
+
+/** 
+ *  @brief Get signal information
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_get_info_signal(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    pmlan_private pmpriv = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    if (pioctl_req != MNULL) {
+        pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    } else {
+        PRINTM(MERROR, "MLAN IOCTL information is not present\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    /* Check information buffer length of MLAN IOCTL */
+    if (pioctl_req->buf_len < sizeof(mlan_ds_get_signal)) {
+        PRINTM(MWARN, "MLAN IOCTL information buffer length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_get_signal);
+        ret = MLAN_STATUS_RESOURCE;
+        goto exit;
+    }
+
+    /* Signal info can be obtained only if connected */
+    if (pmpriv->media_connected == MFALSE) {
+        PRINTM(MINFO, "Can not get signal in disconnected state\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_RSSI_INFO,
+                           HostCmd_ACT_GEN_GET,
+                           0, (t_void *) pioctl_req, MNULL);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get statistics information
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_get_info_stats(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    pmlan_private pmpriv = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    if (pioctl_req != MNULL) {
+        pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    } else {
+        PRINTM(MERROR, "MLAN IOCTL information is not present\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    /* Check information buffer length of MLAN IOCTL */
+    if (pioctl_req->buf_len < sizeof(mlan_ds_get_stats)) {
+        PRINTM(MWARN, "MLAN IOCTL information buffer length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_get_stats);
+        ret = MLAN_STATUS_RESOURCE;
+        goto exit;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_GET_LOG,
+                           HostCmd_ACT_GEN_GET,
+                           0, (t_void *) pioctl_req, MNULL);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get BSS information
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_get_info_bss_info(IN pmlan_adapter pmadapter,
+                       IN pmlan_ioctl_req pioctl_req)
+{
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_get_info *info;
+    BSSDescriptor_t *pbss_desc;
+    t_s32 tbl_idx = 0;
+
+    ENTER();
+
+    /* Get current BSS info */
+    pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
+    info = (mlan_ds_get_info *) pioctl_req->pbuf;
+
+    /* BSS mode */
+    info->param.bss_info.bss_mode = pmpriv->bss_mode;
+
+    /* SSID */
+    memcpy(&info->param.bss_info.ssid, &pbss_desc->ssid,
+           sizeof(mlan_802_11_ssid));
+
+    /* BSSID */
+    memcpy(&info->param.bss_info.bssid, &pbss_desc->mac_address,
+           MLAN_MAC_ADDR_LENGTH);
+
+    /* Channel */
+    info->param.bss_info.bss_chan = pbss_desc->channel;
+
+    /* Region code */
+    info->param.bss_info.region_code = pmadapter->region_code;
+
+    /* Scan table index if connected */
+    info->param.bss_info.scan_table_idx = 0;
+    if (pmpriv->media_connected == MTRUE) {
+        tbl_idx =
+            wlan_find_ssid_in_list(pmpriv, &pbss_desc->ssid,
+                                   pbss_desc->mac_address, pmpriv->bss_mode);
+        if (tbl_idx >= 0)
+            info->param.bss_info.scan_table_idx = tbl_idx;
+    }
+
+    /* Connection status */
+    info->param.bss_info.media_connected = pmpriv->media_connected;
+
+    /* Radio status */
+    info->param.bss_info.radio_on = pmadapter->radio_on;
+
+    /* Tx power information */
+    info->param.bss_info.max_power_level = pmpriv->max_tx_power_level;
+    info->param.bss_info.min_power_level = pmpriv->min_tx_power_level;
+
+    /* AdHoc state */
+    info->param.bss_info.adhoc_state = pmpriv->adhoc_state;
+
+    /* Last beacon NF */
+    info->param.bss_info.bcn_nf_last = pmpriv->bcn_nf_last;
+
+    /* wep status */
+    if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)
+        info->param.bss_info.wep_status = MTRUE;
+    else
+        info->param.bss_info.wep_status = MFALSE;
+
+    info->param.bss_info.is_hs_configured = pmadapter->is_hs_configured;
+    info->param.bss_info.is_deep_sleep = pmadapter->is_deep_sleep;
+
+    pioctl_req->data_read_written =
+        sizeof(mlan_bss_info) + MLAN_SUB_COMMAND_SIZE;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get extended version information
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_get_info_ver_ext(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_get_info *info;
+
+    ENTER();
+
+    info = (mlan_ds_get_info *) pioctl_req->pbuf;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_VERSION_EXT,
+                           HostCmd_ACT_GEN_GET,
+                           0,
+                           (t_void *) pioctl_req,
+                           &info->param.ver_ext.version_str_sel);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get information handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_get_info_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_get_info *pget_info = MNULL;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    pget_info = (mlan_ds_get_info *) pioctl_req->pbuf;
+
+    switch (pget_info->sub_command) {
+    case MLAN_OID_GET_STATS:
+        status = wlan_get_info_stats(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_GET_SIGNAL:
+        status = wlan_get_info_signal(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_GET_FW_INFO:
+        pioctl_req->data_read_written =
+            sizeof(mlan_fw_info) + MLAN_SUB_COMMAND_SIZE;
+        pget_info->param.fw_info.fw_ver = pmadapter->fw_release_number;
+        memcpy(&pget_info->param.fw_info.mac_addr, pmpriv->curr_addr,
+               MLAN_MAC_ADDR_LENGTH);
+        break;
+    case MLAN_OID_GET_BSS_INFO:
+        status = wlan_get_info_bss_info(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_GET_DEBUG_INFO:
+        status = wlan_get_info_debug_info(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_GET_VER_EXT:
+        status = wlan_get_info_ver_ext(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set/Get SNMP MIB handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_snmp_mib_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 cmd_action = 0;
+    t_u16 cmd_oid = 0;
+    mlan_ds_snmp_mib *mib = MNULL;
+    t_u32 value = 0;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_snmp_mib)) {
+        PRINTM(MWARN, "MLAN IOCTL information buffer length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_snmp_mib);
+        ret = MLAN_STATUS_RESOURCE;
+        goto exit;
+    }
+
+    mib = (mlan_ds_snmp_mib *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_SET)
+        cmd_action = HostCmd_ACT_GEN_SET;
+    else
+        cmd_action = HostCmd_ACT_GEN_GET;
+
+    switch (mib->sub_command) {
+    case MLAN_OID_SNMP_MIB_RTS_THRESHOLD:
+        value = mib->param.rts_threshold;
+        cmd_oid = RtsThresh_i;
+        break;
+    case MLAN_OID_SNMP_MIB_FRAG_THRESHOLD:
+        value = mib->param.frag_threshold;
+        cmd_oid = FragThresh_i;
+        break;
+    case MLAN_OID_SNMP_MIB_RETRY_COUNT:
+        value = mib->param.retry_count;
+        cmd_oid = ShortRetryLim_i;
+        break;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_SNMP_MIB,
+                           cmd_action, cmd_oid, (t_void *) pioctl_req, &value);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get radio status
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_radio_ioctl_radio_ctl(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_radio_cfg *radio_cfg = MNULL;
+    t_u16 cmd_action = 0;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    radio_cfg = (mlan_ds_radio_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        if (pmadapter->radio_on == radio_cfg->param.radio_on_off) {
+            ret = MLAN_STATUS_SUCCESS;
+            goto exit;
+        } else {
+            if (pmpriv->media_connected == MTRUE) {
+                ret = MLAN_STATUS_FAILURE;
+                goto exit;
+            }
+            cmd_action = HostCmd_ACT_GEN_SET;
+            pmadapter->radio_on = (t_u16) radio_cfg->param.radio_on_off;
+        }
+    } else
+        cmd_action = HostCmd_ACT_GEN_GET;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_RADIO_CONTROL,
+                           cmd_action, 0, (t_void *) pioctl_req, MNULL);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get Infra/Ad-hoc band configuration
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_radio_ioctl_band_cfg(IN pmlan_adapter pmadapter,
+                          IN pmlan_ioctl_req pioctl_req)
+{
+    t_u8 infra_band = 0;
+    t_u8 adhoc_band = 0;
+    t_u32 adhoc_channel = 0;
+    mlan_ds_radio_cfg *radio_cfg = MNULL;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    radio_cfg = (mlan_ds_radio_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        infra_band = (t_u8) radio_cfg->param.band_cfg.config_bands;
+        adhoc_band = (t_u8) radio_cfg->param.band_cfg.adhoc_start_band;
+        adhoc_channel = radio_cfg->param.band_cfg.adhoc_channel;
+
+        /* SET Infra band */
+        if ((infra_band | pmadapter->fw_bands) & ~pmadapter->fw_bands) {
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+
+        if (wlan_set_regiontable
+            (pmpriv, (t_u8) pmadapter->region_code, infra_band)) {
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+
+        if (wlan_set_universal_table(pmpriv, infra_band)) {
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+        pmadapter->config_bands = infra_band;
+
+        /* SET Ad-hoc Band */
+        if ((adhoc_band | pmadapter->fw_bands) & ~pmadapter->fw_bands) {
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+
+        if (adhoc_band)
+            pmadapter->adhoc_start_band = adhoc_band;
+        pmpriv->adhoc_auto_sel = MFALSE;
+        /* 
+         * If no adhoc_channel is supplied verify if the existing adhoc channel
+         * compiles with new adhoc_band
+         */
+        if (!adhoc_channel) {
+            if (!wlan_find_cfp_by_band_and_channel
+                (pmadapter, pmadapter->adhoc_start_band,
+                 pmpriv->adhoc_channel)) {
+                /* Pass back the default channel */
+                radio_cfg->param.band_cfg.adhoc_channel =
+                    DEFAULT_AD_HOC_CHANNEL;
+                if ((pmadapter->adhoc_start_band & BAND_A)
+                    || (pmadapter->adhoc_start_band & BAND_AN)
+                    ) {
+                    radio_cfg->param.band_cfg.adhoc_channel =
+                        DEFAULT_AD_HOC_CHANNEL_A;
+                }
+            }
+        } else {                /* Retrurn error if adhoc_band and
+                                   adhoc_channel combination is invalid */
+            if (!wlan_find_cfp_by_band_and_channel
+                (pmadapter, pmadapter->adhoc_start_band,
+                 (t_u16) adhoc_channel)) {
+                LEAVE();
+                return MLAN_STATUS_FAILURE;
+            }
+            pmpriv->adhoc_channel = (t_u8) adhoc_channel;
+        }
+        if ((adhoc_band & BAND_GN)
+            || (adhoc_band & BAND_AN)
+            ) {
+            pmadapter->adhoc_11n_enabled = MTRUE;
+        } else {
+            pmadapter->adhoc_11n_enabled = MFALSE;
+        }
+    } else {
+        radio_cfg->param.band_cfg.config_bands = pmadapter->config_bands;       /* Infra 
+                                                                                   Bands 
+                                                                                 */
+        radio_cfg->param.band_cfg.adhoc_start_band = pmadapter->adhoc_start_band;       /* Adhoc 
+                                                                                           Band 
+                                                                                         */
+        radio_cfg->param.band_cfg.adhoc_channel = pmpriv->adhoc_channel;        /* Adhoc 
+                                                                                   Channel 
+                                                                                 */
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Set/Get antenna configuration
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_PENDING --success, otherwise fail
+ */
+static mlan_status
+wlan_radio_ioctl_ant_cfg(IN pmlan_adapter pmadapter,
+                         IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_radio_cfg *radio_cfg = MNULL;
+    t_u16 cmd_action = 0;
+    t_u16 antenna_mode;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    radio_cfg = (mlan_ds_radio_cfg *) pioctl_req->pbuf;
+
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        /* User input validation */
+        if ((radio_cfg->param.antenna < RF_ANTENNA_1 ||
+             radio_cfg->param.antenna >=
+             (unsigned) (RF_ANTENNA_1 + pmadapter->number_of_antenna)) &&
+            (radio_cfg->param.antenna != RF_ANTENNA_AUTO ||
+             pmadapter->number_of_antenna <= 1)) {
+            PRINTM(MERROR, "Invalid antenna setting\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+        cmd_action = HostCmd_ACT_GEN_SET;
+    } else
+        cmd_action = HostCmd_ACT_GEN_GET;
+
+    /* Cast it to t_u16, antenna mode for command HostCmd_CMD_802_11_RF_ANTENNA 
+       requires 2 bytes */
+    antenna_mode = (t_u16) radio_cfg->param.antenna;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_RF_ANTENNA,
+                           cmd_action,
+                           0, (t_void *) pioctl_req, (t_void *) & antenna_mode);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Radio command handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_radio_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_radio_cfg *radio_cfg = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_radio_cfg)) {
+        PRINTM(MWARN, "MLAN IOCTL information buffer length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_radio_cfg);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    radio_cfg = (mlan_ds_radio_cfg *) pioctl_req->pbuf;
+    switch (radio_cfg->sub_command) {
+    case MLAN_OID_RADIO_CTRL:
+        status = wlan_radio_ioctl_radio_ctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_BAND_CFG:
+        status = wlan_radio_ioctl_band_cfg(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_ANT_CFG:
+        status = wlan_radio_ioctl_ant_cfg(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set/Get MAC address
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_mac_address(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    ENTER();
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        pioctl_req->data_read_written =
+            MLAN_MAC_ADDR_LENGTH + MLAN_SUB_COMMAND_SIZE;
+        memcpy(&bss->param.mac_addr, pmpriv->curr_addr, MLAN_MAC_ADDR_LENGTH);
+        ret = MLAN_STATUS_SUCCESS;
+        goto exit;
+    }
+
+    memcpy(pmpriv->curr_addr, &bss->param.mac_addr, MLAN_MAC_ADDR_LENGTH);
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_MAC_ADDRESS,
+                           HostCmd_ACT_GEN_SET,
+                           0, (t_void *) pioctl_req, MNULL);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set multicast list
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_set_multicast_list(IN pmlan_adapter pmadapter,
+                                  IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 old_pkt_filter;
+
+    ENTER();
+
+    old_pkt_filter = pmpriv->curr_pkt_filter;
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+    pioctl_req->data_read_written =
+        sizeof(mlan_multicast_list) + MLAN_SUB_COMMAND_SIZE;
+    if (bss->param.multicast_list.mode == MLAN_PROMISC_MODE) {
+        PRINTM(MINFO, "Enable Promiscuous mode\n");
+        pmpriv->curr_pkt_filter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
+        pmpriv->curr_pkt_filter &= ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
+    } else {
+        /* Multicast */
+        pmpriv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
+        if (bss->param.multicast_list.mode == MLAN_MULTICAST_MODE) {
+            PRINTM(MINFO, "Enabling All Multicast!\n");
+            pmpriv->curr_pkt_filter |= HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
+        } else {
+            pmpriv->curr_pkt_filter &= ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
+            if (bss->param.multicast_list.num_multicast_addr) {
+                PRINTM(MINFO, "Set multicast list=%d\n",
+                       bss->param.multicast_list.num_multicast_addr);
+                /* Set multicast addresses to firmware */
+                if (old_pkt_filter == pmpriv->curr_pkt_filter) {
+                    /* Send request to firmware */
+                    ret =
+                        wlan_prepare_cmd(pmpriv, HostCmd_CMD_MAC_MULTICAST_ADR,
+                                         HostCmd_ACT_GEN_SET, 0,
+                                         (t_void *) pioctl_req,
+                                         &bss->param.multicast_list);
+                    if (ret == MLAN_STATUS_SUCCESS)
+                        ret = MLAN_STATUS_PENDING;
+                } else {
+                    /* Send request to firmware */
+                    ret =
+                        wlan_prepare_cmd(pmpriv, HostCmd_CMD_MAC_MULTICAST_ADR,
+                                         HostCmd_ACT_GEN_SET, 0, MNULL,
+                                         &bss->param.multicast_list);
+                }
+            }
+        }
+    }
+    PRINTM(MINFO, "old_pkt_filter=0x%lx, curr_pkt_filter=0x%lx\n",
+           old_pkt_filter, pmpriv->curr_pkt_filter);
+    if (old_pkt_filter != pmpriv->curr_pkt_filter) {
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_MAC_CONTROL,
+                               HostCmd_ACT_GEN_SET,
+                               0,
+                               (t_void *) pioctl_req, &pmpriv->curr_pkt_filter);
+        if (ret == MLAN_STATUS_SUCCESS)
+            ret = MLAN_STATUS_PENDING;
+    }
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get channel list
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_get_channel_list(IN pmlan_adapter pmadapter,
+                                IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    chan_freq_power_t *cfp;
+    t_u32 i, j;
+
+    ENTER();
+
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+    if (pioctl_req->action != MLAN_ACT_GET) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    if ((wlan_11d_get_state(pmpriv) == ENABLE_11D &&
+         pmpriv->media_connected == MTRUE) &&
+        ((pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) ||
+         (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS &&
+          pmpriv->adhoc_state != ADHOC_STARTED))
+        ) {
+        t_u8 chan_no;
+        t_u8 band;
+
+        parsed_region_chan_11d_t *parsed_region_chan = MNULL;
+        parsed_region_chan_11d_t region_chan;
+
+        BSSDescriptor_t *pbss_desc = &pmpriv->curr_bss_params.bss_descriptor;
+
+        /* If country IE is present in the associated AP then return the
+           channel list from country IE else return it from the learning table */
+
+        if (wlan_11d_parse_domain_info(pmadapter, &pbss_desc->country_info,
+                                       (t_u8) pbss_desc->bss_band,
+                                       &region_chan) == MLAN_STATUS_SUCCESS) {
+
+            parsed_region_chan = &region_chan;
+        } else {
+            parsed_region_chan = &pmadapter->parsed_region_chan;
+        }
+
+        band = parsed_region_chan->band;
+        PRINTM(MINFO, "band=%d no_of_chan=%d\n", band,
+               parsed_region_chan->no_of_chan);
+
+        for (i = 0; (bss->param.chanlist.num_of_chan < MLAN_MAX_CHANNEL_NUM)
+             && (i < parsed_region_chan->no_of_chan); i++) {
+            chan_no = parsed_region_chan->chan_pwr[i].chan;
+            PRINTM(MINFO, "chan_no=%d\n", chan_no);
+            bss->param.chanlist.cf[bss->param.chanlist.num_of_chan].channel =
+                (t_u32) chan_no;
+            bss->param.chanlist.cf[bss->param.chanlist.num_of_chan].freq =
+                (t_u32) wlan_11d_chan_2_freq(pmadapter, chan_no, band);
+            bss->param.chanlist.num_of_chan++;
+        }
+    } else {
+        for (j = 0; (bss->param.chanlist.num_of_chan < MLAN_MAX_CHANNEL_NUM)
+             && (j <
+                 sizeof(pmadapter->region_channel) /
+                 sizeof(pmadapter->region_channel[0])); j++) {
+            cfp = pmadapter->region_channel[j].pcfp;
+            for (i = 0; (bss->param.chanlist.num_of_chan < MLAN_MAX_CHANNEL_NUM)
+                 && pmadapter->region_channel[j].valid
+                 && cfp && (i < pmadapter->region_channel[j].num_cfp); i++) {
+                bss->param.chanlist.cf[bss->param.chanlist.num_of_chan].
+                    channel = (t_u32) cfp->channel;
+                bss->param.chanlist.cf[bss->param.chanlist.num_of_chan].freq =
+                    (t_u32) cfp->freq;
+                bss->param.chanlist.num_of_chan++;
+                cfp++;
+            }
+        }
+    }
+
+    PRINTM(MINFO, "num of channel=%d\n", bss->param.chanlist.num_of_chan);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get BSS channel
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_channel(IN pmlan_adapter pmadapter,
+                       IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    chan_freq_power_t *cfp;
+    ENTER();
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        cfp = wlan_find_cfp_by_band_and_channel(pmadapter,
+                                                pmpriv->curr_bss_params.band,
+                                                (t_u16) pmpriv->curr_bss_params.
+                                                bss_descriptor.channel);
+        if (cfp) {
+            bss->param.bss_chan.channel = cfp->channel;
+            bss->param.bss_chan.freq = cfp->freq;
+        } else
+            ret = MLAN_STATUS_FAILURE;
+        pioctl_req->data_read_written =
+            sizeof(chan_freq) + MLAN_SUB_COMMAND_SIZE;
+        LEAVE();
+        return ret;
+    }
+    if (!bss->param.bss_chan.channel && !bss->param.bss_chan.freq) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    if (pmadapter->adhoc_start_band & BAND_AN)
+        pmadapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN;
+    else if (pmadapter->adhoc_start_band & BAND_A)
+        pmadapter->adhoc_start_band = BAND_G | BAND_B;
+    if (bss->param.bss_chan.channel) {
+        cfp =
+            wlan_find_cfp_by_band_and_channel(pmadapter, 0,
+                                              (t_u16) bss->param.bss_chan.
+                                              channel);
+        if (!cfp) {
+            cfp =
+                wlan_find_cfp_by_band_and_channel(pmadapter, BAND_A,
+                                                  (t_u16) bss->param.bss_chan.
+                                                  channel);
+            if (cfp) {
+                if (pmadapter->adhoc_11n_enabled)
+                    pmadapter->adhoc_start_band = BAND_A | BAND_AN;
+                else
+                    pmadapter->adhoc_start_band = BAND_A;
+            }
+        }
+    } else {
+        cfp =
+            wlan_find_cfp_by_band_and_freq(pmadapter, 0,
+                                           bss->param.bss_chan.freq);
+        if (!cfp) {
+            cfp =
+                wlan_find_cfp_by_band_and_freq(pmadapter, BAND_A,
+                                               bss->param.bss_chan.freq);
+            if (cfp) {
+                if (pmadapter->adhoc_11n_enabled)
+                    pmadapter->adhoc_start_band = BAND_A | BAND_AN;
+                else
+                    pmadapter->adhoc_start_band = BAND_A;
+            }
+        }
+    }
+    if (!cfp || !cfp->channel) {
+        PRINTM(MERROR, "Invalid channel/freq\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+
+    }
+    pmpriv->adhoc_channel = (t_u8) cfp->channel;
+    pmpriv->adhoc_auto_sel = MFALSE;
+    bss->param.bss_chan.channel = cfp->channel;
+    bss->param.bss_chan.freq = cfp->freq;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get BSS mode
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_mode(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+
+    ENTER();
+
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        bss->param.bss_mode = pmpriv->bss_mode;
+        pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+        goto exit;
+    }
+
+    if ((pmpriv->bss_mode == bss->param.bss_mode) ||
+        (bss->param.bss_mode == MLAN_BSS_MODE_AUTO)) {
+        PRINTM(MINFO, "Already set to required mode! No change!\n");
+        pmpriv->bss_mode = bss->param.bss_mode;
+        goto exit;
+    }
+
+    if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) {
+        pmadapter->ps_mode = Wlan802_11PowerModeCAM;
+    }
+
+    ret = wlan_disconnect(pmpriv, pioctl_req, MNULL);
+
+    pmpriv->sec_info.authentication_mode = MLAN_AUTH_MODE_OPEN;
+    pmpriv->bss_mode = bss->param.bss_mode;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Start BSS
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_start(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = (mlan_ds_bss *) pioctl_req->pbuf;
+    t_s32 i = -1;
+
+    ENTER();
+
+    if (pmpriv->bss_mode == MLAN_BSS_MODE_INFRA) {
+        /* Infra mode */
+        ret = wlan_disconnect(pmpriv, MNULL, MNULL);
+        if (ret)
+            goto start_ssid_done;
+
+        /* Search for the requested SSID in the scan table */
+        if (bss->param.ssid_bssid.ssid.ssid_len) {
+            i = wlan_find_ssid_in_list(pmpriv,
+                                       &bss->param.ssid_bssid.ssid,
+                                       MNULL, MLAN_BSS_MODE_INFRA);
+        } else {
+            i = wlan_find_bssid_in_list(pmpriv,
+                                        (t_u8 *) & bss->param.ssid_bssid.bssid,
+                                        MLAN_BSS_MODE_INFRA);
+        }
+
+        if (i >= 0) {
+            PRINTM(MINFO, "SSID found in scan list ... associating...\n");
+
+            /* Clear any past association response stored for application
+               retrieval */
+            pmpriv->assoc_rsp_size = 0;
+            ret = wlan_associate(pmpriv, pioctl_req,
+                                 &pmadapter->pscan_table[i]);
+            if (ret)
+                goto start_ssid_done;
+        } else {                /* i >= 0 */
+            ret = MLAN_STATUS_FAILURE;
+            goto start_ssid_done;
+        }
+    } else {
+        /* Adhoc mode */
+        /* If the requested SSID matches current SSID, return */
+        if (bss->param.ssid_bssid.ssid.ssid_len &&
+            (!wlan_ssid_cmp
+             (pmadapter, &pmpriv->curr_bss_params.bss_descriptor.ssid,
+              &bss->param.ssid_bssid.ssid))) {
+            ret = MLAN_STATUS_SUCCESS;
+            goto start_ssid_done;
+        }
+
+        /* Exit Adhoc mode first */
+        PRINTM(MINFO, "Sending Adhoc Stop\n");
+        ret = wlan_disconnect(pmpriv, MNULL, MNULL);
+        if (ret)
+            goto start_ssid_done;
+
+        pmpriv->adhoc_is_link_sensed = MFALSE;
+
+        /* Search for the requested network in the scan table */
+        if (bss->param.ssid_bssid.ssid.ssid_len) {
+            i = wlan_find_ssid_in_list(pmpriv,
+                                       &bss->param.ssid_bssid.ssid,
+                                       MNULL, MLAN_BSS_MODE_IBSS);
+        } else {
+            i = wlan_find_bssid_in_list(pmpriv,
+                                        (t_u8 *) & bss->param.ssid_bssid.bssid,
+                                        MLAN_BSS_MODE_IBSS);
+        }
+
+        if (i >= 0) {
+            PRINTM(MINFO, "Network found in scan list ... joining ...\n");
+            if (pmpriv->adhoc_aes_enabled)
+                wlan_enable_aes_key(pmpriv);
+            ret =
+                wlan_adhoc_join(pmpriv, pioctl_req, &pmadapter->pscan_table[i]);
+            if (ret)
+                goto start_ssid_done;
+        } else {                /* i >= 0 */
+            PRINTM(MINFO, "Network not found in the list, "
+                   "creating adhoc with ssid = %s\n",
+                   bss->param.ssid_bssid.ssid.ssid);
+            if (pmpriv->adhoc_aes_enabled)
+                wlan_enable_aes_key(pmpriv);
+            ret =
+                wlan_adhoc_start(pmpriv, pioctl_req,
+                                 &bss->param.ssid_bssid.ssid);
+            if (ret)
+                goto start_ssid_done;
+        }
+    }
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  start_ssid_done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Stop BSS
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_stop(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = (mlan_ds_bss *) pioctl_req->pbuf;
+
+    ENTER();
+
+    ret = wlan_disconnect(pmpriv, pioctl_req, &bss->param.bssid);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get IBSS channel
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_ibss_channel(IN pmlan_adapter pmadapter,
+                            IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 cmd_action;
+
+    ENTER();
+
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        if (pmpriv->media_connected == MFALSE) {
+            bss->param.bss_chan.channel = pmpriv->adhoc_channel;
+            goto exit;
+        }
+        cmd_action = HostCmd_ACT_GEN_GET;
+    } else {
+        cmd_action = HostCmd_ACT_GEN_SET;
+        pmpriv->adhoc_channel = (t_u8) bss->param.bss_chan.channel;
+        pmpriv->adhoc_auto_sel = MFALSE;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_RF_CHANNEL,
+                           cmd_action,
+                           0,
+                           (t_void *) pioctl_req, &bss->param.bss_chan.channel);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get beacon interval
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_beacon_interval(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    ENTER();
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        bss->param.bcn_interval = pmpriv->beacon_period;
+        if (pmpriv->media_connected == MTRUE)
+            bss->param.bcn_interval =
+                pmpriv->curr_bss_params.bss_descriptor.beacon_period;
+    } else
+        pmpriv->beacon_period = (t_u16) bss->param.bcn_interval;
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get ATIM window
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_atim_window(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    ENTER();
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        bss->param.atim_window = pmpriv->atim_window;
+        if (pmpriv->media_connected == MTRUE)
+            bss->param.atim_window =
+                pmpriv->curr_bss_params.bss_descriptor.atim_window;
+    } else
+        pmpriv->atim_window = (t_u16) bss->param.atim_window;
+
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Search for a BSS
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl_find_bss(IN pmlan_adapter pmadapter,
+                        IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bss *bss = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
+    t_u8 mac[MLAN_MAC_ADDR_LENGTH];
+    int i = 0;
+    BSSDescriptor_t *pbss_desc;
+
+    ENTER();
+
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+    if (memcmp(&bss->param.ssid_bssid.bssid, zero_mac, sizeof(zero_mac))) {
+        i = wlan_find_bssid_in_list(pmpriv,
+                                    (t_u8 *) & bss->param.ssid_bssid.bssid,
+                                    pmpriv->bss_mode);
+        if (i < 0) {
+            memcpy(mac, &bss->param.ssid_bssid.bssid, sizeof(mac));
+            PRINTM(MERROR, "Can not find bssid %02x:%02x:%02x:%02x:%02x:%02x\n",
+                   mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+        pbss_desc = &pmadapter->pscan_table[i];
+        memcpy(&bss->param.ssid_bssid.ssid, &pbss_desc->ssid,
+               sizeof(mlan_802_11_ssid));
+    } else if (bss->param.ssid_bssid.ssid.ssid_len) {
+        i = wlan_find_ssid_in_list(pmpriv, &bss->param.ssid_bssid.ssid, MNULL,
+                                   pmpriv->bss_mode);
+        if (i < 0) {
+            PRINTM(MERROR, "Can not find ssid %s\n",
+                   bss->param.ssid_bssid.ssid.ssid);
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+        pbss_desc = &pmadapter->pscan_table[i];
+        memcpy((t_u8 *) & bss->param.ssid_bssid.bssid,
+               (t_u8 *) & pbss_desc->mac_address, MLAN_MAC_ADDR_LENGTH);
+    } else {
+        ret = wlan_find_best_network(pmpriv, &bss->param.ssid_bssid);
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief BSS command handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bss_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_bss *bss = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_bss)) {
+        PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_bss);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+
+    bss = (mlan_ds_bss *) pioctl_req->pbuf;
+
+    switch (bss->sub_command) {
+    case MLAN_OID_BSS_START:
+        status = wlan_bss_ioctl_start(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_BSS_STOP:
+        status = wlan_bss_ioctl_stop(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_BSS_MODE:
+        status = wlan_bss_ioctl_mode(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_BSS_CHANNEL:
+        status = wlan_bss_ioctl_channel(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_BSS_CHANNEL_LIST:
+        status = wlan_bss_ioctl_get_channel_list(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_BSS_MAC_ADDR:
+        status = wlan_bss_ioctl_mac_address(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_BSS_MULTICAST_LIST:
+        status = wlan_bss_ioctl_set_multicast_list(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_BSS_FIND_BSS:
+        status = wlan_bss_ioctl_find_bss(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_IBSS_BCN_INTERVAL:
+        status = wlan_bss_ioctl_beacon_interval(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_IBSS_ATIM_WINDOW:
+        status = wlan_bss_ioctl_atim_window(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_IBSS_CHANNEL:
+        status = wlan_bss_ioctl_ibss_channel(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get supported rates
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl_get_supported_rate(IN pmlan_adapter pmadapter,
+                                   IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_rate *rate = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    ENTER();
+    if (pioctl_req->action != MLAN_ACT_GET) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    rate = (mlan_ds_rate *) pioctl_req->pbuf;
+    wlan_get_active_data_rates(pmpriv, rate->param.rates);
+    pioctl_req->data_read_written =
+        MLAN_SUPPORTED_RATES + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get rate value
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl_get_rate_value(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_ds_rate *rate = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    rate = (mlan_ds_rate *) pioctl_req->pbuf;
+    rate->param.rate_cfg.is_rate_auto = pmpriv->is_data_rate_auto;
+    pioctl_req->data_read_written =
+        sizeof(mlan_rate_cfg_t) + MLAN_SUB_COMMAND_SIZE;
+
+    if (pmpriv->media_connected != MTRUE) {
+        switch (pmadapter->config_bands) {
+        case BAND_B:
+            /* Return the lowest supported rate for B band */
+            rate->param.rate_cfg.rate = SupportedRates_B[0] & 0x7f;
+            break;
+        case BAND_G:
+        case BAND_G | BAND_GN:
+            /* Return the lowest supported rate for G band */
+            rate->param.rate_cfg.rate = SupportedRates_G[0] & 0x7f;
+            break;
+        case BAND_B | BAND_G:
+        case BAND_A | BAND_B | BAND_G:
+        case BAND_A | BAND_B:
+        case BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN:
+        case BAND_B | BAND_G | BAND_GN:
+            /* Return the lowest supported rate for BG band */
+            rate->param.rate_cfg.rate = SupportedRates_BG[0] & 0x7f;
+            break;
+        case BAND_A:
+        case BAND_A | BAND_G:
+        case BAND_A | BAND_G | BAND_AN | BAND_GN:
+        case BAND_A | BAND_AN:
+            /* Return the lowest supported rate for A band */
+            rate->param.rate_cfg.rate = SupportedRates_A[0] & 0x7f;
+            break;
+        case BAND_GN:
+            /* Return the lowest supported rate for N band */
+            rate->param.rate_cfg.rate = SupportedRates_N[0] & 0x7f;
+            break;
+        default:
+            PRINTM(MMSG, "Invalid Band 0x%x\n", pmadapter->config_bands);
+            break;
+        }
+    } else {
+        /* Send request to firmware */
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_802_11_TX_RATE_QUERY,
+                               HostCmd_ACT_GEN_GET,
+                               0, (t_void *) pioctl_req, MNULL);
+        if (ret == MLAN_STATUS_SUCCESS)
+            ret = MLAN_STATUS_PENDING;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set rate value
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl_set_rate_value(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_ds_rate *ds_rate = MNULL;
+    WLAN_802_11_RATES rates;
+    t_u8 *rate = MNULL;
+    int rate_index = 0;
+    t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
+    t_u32 i = 0;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    ds_rate = (mlan_ds_rate *) pioctl_req->pbuf;
+
+    if (ds_rate->param.rate_cfg.is_rate_auto) {
+        memset(bitmap_rates, 0, sizeof(bitmap_rates));
+        /* Support all HR/DSSS rates */
+        bitmap_rates[0] = 0x000F;
+        /* Support all OFDM rates */
+        bitmap_rates[1] = 0x00FF;
+        /* Support all HT-MCSs rate */
+        for (i = 0; i < NELEMENTS(pmpriv->bitmap_rates) - 3; i++)
+            bitmap_rates[i + 2] = 0xFFFF;
+        bitmap_rates[9] = 0x3FFF;
+    } else {
+        memset(rates, 0, sizeof(rates));
+        wlan_get_active_data_rates(pmpriv, rates);
+        rate = rates;
+        for (i = 0; (rate[i] && i < WLAN_SUPPORTED_RATES); i++) {
+            PRINTM(MINFO, "Rate=0x%X  Wanted=0x%X\n", rate[i],
+                   ds_rate->param.rate_cfg.rate);
+            if ((rate[i] & 0x7f) == (ds_rate->param.rate_cfg.rate & 0x7f))
+                break;
+        }
+        if (!rate[i] || (i == WLAN_SUPPORTED_RATES)) {
+            PRINTM(MERROR, "The fixed data rate 0x%X is out "
+                   "of range\n", ds_rate->param.rate_cfg.rate);
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+        memset(bitmap_rates, 0, sizeof(bitmap_rates));
+
+        rate_index =
+            wlan_data_rate_to_index(pmadapter, ds_rate->param.rate_cfg.rate);
+
+        /* Only allow b/g rates to be set */
+        if (rate_index >= MLAN_RATE_INDEX_HRDSSS0 &&
+            rate_index <= MLAN_RATE_INDEX_HRDSSS3)
+            bitmap_rates[0] = 1 << rate_index;
+        else {
+            rate_index -= 1;    /* There is a 0x00 in the table */
+            if (rate_index >= MLAN_RATE_INDEX_OFDM0 &&
+                rate_index <= MLAN_RATE_INDEX_OFDM7)
+                bitmap_rates[1] = 1 << (rate_index - MLAN_RATE_INDEX_OFDM0);
+        }
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_TX_RATE_CFG,
+                           HostCmd_ACT_GEN_SET,
+                           0, (t_void *) pioctl_req, bitmap_rates);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get rate index
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl_get_rate_index(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_TX_RATE_CFG,
+                           HostCmd_ACT_GEN_GET,
+                           0, (t_void *) pioctl_req, MNULL);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set rate index
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl_set_rate_index(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    int rate_index;
+    t_u32 i;
+    mlan_ds_rate *ds_rate = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    t_u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
+
+    ENTER();
+
+    ds_rate = (mlan_ds_rate *) pioctl_req->pbuf;
+    rate_index = ds_rate->param.rate_cfg.rate;
+    if (ds_rate->param.rate_cfg.is_rate_auto) {
+        memset(bitmap_rates, 0, sizeof(bitmap_rates));
+        /* Support all HR/DSSS rates */
+        bitmap_rates[0] = 0x000F;
+        /* Support all OFDM rates */
+        bitmap_rates[1] = 0x00FF;
+        /* Support all HT-MCSs rate */
+        for (i = 0; i < NELEMENTS(bitmap_rates) - 3; i++)
+            bitmap_rates[i + 2] = 0xFFFF;
+        bitmap_rates[9] = 0x3FFF;
+    } else {
+        PRINTM(MINFO, "Rate index is %d\n", rate_index);
+        memset(bitmap_rates, 0, sizeof(bitmap_rates));
+        /* Bitmap of HR/DSSS rates */
+        if (rate_index >= MLAN_RATE_INDEX_HRDSSS0 &&
+            rate_index <= MLAN_RATE_INDEX_HRDSSS3)
+            bitmap_rates[0] = 1 << rate_index;
+        /* Bitmap of OFDM rates */
+        if (rate_index >= MLAN_RATE_INDEX_OFDM0 &&
+            rate_index <= MLAN_RATE_INDEX_OFDM7)
+            bitmap_rates[1] = 1 << (rate_index - MLAN_RATE_INDEX_OFDM0);
+        /* Bitmap of HT-MCSs allowed for initial rate */
+        if (rate_index >= MLAN_RATE_INDEX_MCS0 &&
+            rate_index <= MLAN_RATE_INDEX_MCS32)
+            bitmap_rates[((rate_index - MLAN_RATE_INDEX_MCS0) / 16) + 2] =
+                1 << ((rate_index - MLAN_RATE_INDEX_MCS0) % 16);
+    }
+
+    PRINTM(MINFO, "RateBitmap=%04x%04x%04x%04x%04x%04x%04x%04x%04x%04x, "
+           "IsRateAuto=%d, DataRate=%d\n",
+           bitmap_rates[9], bitmap_rates[8],
+           bitmap_rates[7], bitmap_rates[6],
+           bitmap_rates[5], bitmap_rates[4],
+           bitmap_rates[3], bitmap_rates[2],
+           bitmap_rates[1], bitmap_rates[0],
+           pmpriv->is_data_rate_auto, pmpriv->data_rate);
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_TX_RATE_CFG,
+                           HostCmd_ACT_GEN_SET,
+                           0, (t_void *) pioctl_req, (t_void *) bitmap_rates);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Rate configuration command handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl_cfg(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_ds_rate *rate = MNULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    rate = (mlan_ds_rate *) pioctl_req->pbuf;
+    if (rate->param.rate_cfg.rate_type == MLAN_RATE_VALUE) {
+        if (pioctl_req->action == MLAN_ACT_GET)
+            status = wlan_rate_ioctl_get_rate_value(pmadapter, pioctl_req);
+        else
+            status = wlan_rate_ioctl_set_rate_value(pmadapter, pioctl_req);
+    } else {
+        if (pioctl_req->action == MLAN_ACT_GET)
+            status = wlan_rate_ioctl_get_rate_index(pmadapter, pioctl_req);
+        else
+            status = wlan_rate_ioctl_set_rate_index(pmadapter, pioctl_req);
+    }
+
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get data rates
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl_get_data_rate(IN pmlan_adapter pmadapter,
+                              IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    if (pioctl_req->action != MLAN_ACT_GET) {
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_TX_RATE_QUERY,
+                           HostCmd_ACT_GEN_GET,
+                           0, (t_void *) pioctl_req, MNULL);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Rate command handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_rate_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_rate *rate = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_rate)) {
+        PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_rate);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    rate = (mlan_ds_rate *) pioctl_req->pbuf;
+    switch (rate->sub_command) {
+    case MLAN_OID_RATE_CFG:
+        status = wlan_rate_ioctl_cfg(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_GET_DATA_RATE:
+        status = wlan_rate_ioctl_get_data_rate(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_SUPPORTED_RATES:
+        status = wlan_rate_ioctl_get_supported_rate(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get Tx power configuration
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_power_ioctl_get_power(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_TXPWR_CFG,
+                           HostCmd_ACT_GEN_GET,
+                           0, (t_void *) pioctl_req, MNULL);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set Tx power configuration
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_power_ioctl_set_power(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_ds_power_cfg *power = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    HostCmd_DS_TXPWR_CFG *txp_cfg = MNULL;
+    MrvlTypes_Power_Group_t *pg_tlv = MNULL;
+    Power_Group_t *pg = MNULL;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_u8 *buf = MNULL;
+    t_u16 dbm = 0;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    power = (mlan_ds_power_cfg *) pioctl_req->pbuf;
+    if (!power->param.power_cfg.is_power_auto) {
+        dbm = (t_u16) power->param.power_cfg.power_level;
+        if ((dbm < pmpriv->min_tx_power_level) ||
+            (dbm > pmpriv->max_tx_power_level)) {
+            PRINTM(MERROR,
+                   "The set txpower value %d dBm is out of range (%d dBm-%d dBm)!\n",
+                   dbm, pmpriv->min_tx_power_level, pmpriv->max_tx_power_level);
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+    }
+
+    ret = pcb->moal_malloc(MRVDRV_SIZE_OF_CMD_BUFFER, &buf);
+    if (ret != MLAN_STATUS_SUCCESS || buf == MNULL) {
+        PRINTM(MMSG, "ALLOC_CMD_BUF: pcmd_buf: out of memory\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+    memset(buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
+    txp_cfg = (HostCmd_DS_TXPWR_CFG *) buf;
+    txp_cfg->action = HostCmd_ACT_GEN_SET;
+    if (!power->param.power_cfg.is_power_auto) {
+        txp_cfg->mode = 1;
+        pg_tlv =
+            (MrvlTypes_Power_Group_t *) (buf + sizeof(HostCmd_DS_TXPWR_CFG));
+        pg_tlv->type = TLV_TYPE_POWER_GROUP;
+        pg_tlv->length = 4 * sizeof(Power_Group_t);
+        pg = (Power_Group_t *) (buf + sizeof(HostCmd_DS_TXPWR_CFG) +
+                                sizeof(MrvlTypes_Power_Group_t));
+        /* Power group for modulation class HR/DSSS */
+        pg->first_rate_code = 0x00;
+        pg->last_rate_code = 0x03;
+        pg->modulation_class = MOD_CLASS_HR_DSSS;
+        pg->power_step = 0;
+        pg->power_min = (t_s8) dbm;
+        pg->power_max = (t_s8) dbm;
+        pg++;
+        /* Power group for modulation class OFDM */
+        pg->first_rate_code = 0x00;
+        pg->last_rate_code = 0x07;
+        pg->modulation_class = MOD_CLASS_OFDM;
+        pg->power_step = 0;
+        pg->power_min = (t_s8) dbm;
+        pg->power_max = (t_s8) dbm;
+        pg++;
+        /* Power group for modulation class HTBW20 */
+        pg->first_rate_code = 0x00;
+        pg->last_rate_code = 0x20;
+        pg->modulation_class = MOD_CLASS_HT;
+        pg->power_step = 0;
+        pg->power_min = (t_s8) dbm;
+        pg->power_max = (t_s8) dbm;
+        pg->ht_bandwidth = HT_BW_20;
+        pg++;
+        /* Power group for modulation class HTBW40 */
+        pg->first_rate_code = 0x00;
+        pg->last_rate_code = 0x20;
+        pg->modulation_class = MOD_CLASS_HT;
+        pg->power_step = 0;
+        pg->power_min = (t_s8) dbm;
+        pg->power_max = (t_s8) dbm;
+        pg->ht_bandwidth = HT_BW_40;
+    }
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_TXPWR_CFG,
+                           HostCmd_ACT_GEN_SET, 0, (t_void *) pioctl_req, buf);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+    if (buf)
+        pcb->moal_mfree(buf);
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get modulation class from rate index
+ *  
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param rate_index	Rate index
+ *  
+ *  @return		0 fail, otherwise return modulation class
+ */
+static int
+wlan_get_modulation_class(pmlan_adapter pmadapter, int rate_index)
+{
+    ENTER();
+    if (rate_index >= MLAN_RATE_INDEX_HRDSSS0 &&
+        rate_index <= MLAN_RATE_INDEX_HRDSSS3) {
+        return MOD_CLASS_HR_DSSS;
+    } else if (rate_index >= MLAN_RATE_INDEX_OFDM0 &&
+               rate_index <= MLAN_RATE_INDEX_OFDM7) {
+        return MOD_CLASS_OFDM;
+    } else if (rate_index >= MLAN_RATE_INDEX_MCS0 &&
+               rate_index <= MLAN_RATE_INDEX_MCS127) {
+        return MOD_CLASS_HT;
+    }
+    PRINTM(MERROR, "Invalid rate index = %d supplied!\n", rate_index);
+
+    LEAVE();
+    return 0;
+}
+
+/** 
+ *  @brief Set extended power configuration
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_power_ioctl_set_power_ext(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_power_cfg *power = MNULL;
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    t_u8 *buf = MNULL;
+    HostCmd_DS_TXPWR_CFG *txp_cfg = MNULL;
+    MrvlTypes_Power_Group_t *pg_tlv = MNULL;
+    Power_Group_t *pg = MNULL;
+    int mod_class;
+    t_u32 data[4];
+    t_u8 ht_bw;
+
+    ENTER();
+
+    power = (mlan_ds_power_cfg *) pioctl_req->pbuf;
+    ret = pcb->moal_malloc(MRVDRV_SIZE_OF_CMD_BUFFER, &buf);
+    if (ret != MLAN_STATUS_SUCCESS || buf == MNULL) {
+        PRINTM(MERROR, "ALLOC_CMD_BUF: pcmd_buf: out of memory\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+    memset(buf, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
+    txp_cfg = (HostCmd_DS_TXPWR_CFG *) buf;
+    txp_cfg->action = HostCmd_ACT_GEN_SET;
+    memcpy((t_u8 *) & data, (t_u8 *) power->param.power_ext.power_data,
+           sizeof(data));
+    switch (power->param.power_ext.len) {
+    case 1:
+        if (data[0] == 0xFF)
+            txp_cfg->mode = 0;
+        else
+            ret = MLAN_STATUS_FAILURE;
+        break;
+    case 2:
+    case 4:
+        ht_bw = (data[0] & TX_RATE_HT_BW40_BIT) ? HT_BW_40 : HT_BW_20;
+        data[0] &= ~TX_RATE_HT_BW40_BIT;
+        if (!(mod_class = wlan_get_modulation_class(pmadapter, data[0]))) {
+            ret = MLAN_STATUS_FAILURE;
+            break;
+        }
+        if (ht_bw && mod_class != MOD_CLASS_HT) {
+            ret = MLAN_STATUS_FAILURE;
+            break;
+        }
+        txp_cfg->mode = 1;
+        pg_tlv =
+            (MrvlTypes_Power_Group_t *) (buf + sizeof(HostCmd_DS_TXPWR_CFG));
+        pg_tlv->type = TLV_TYPE_POWER_GROUP;
+        pg_tlv->length = sizeof(Power_Group_t);
+        pg = (Power_Group_t *) (buf + sizeof(HostCmd_DS_TXPWR_CFG) +
+                                sizeof(MrvlTypes_Power_Group_t));
+        pg->modulation_class = (t_u8) mod_class;
+        pg->first_rate_code = (t_u8) data[0];
+        pg->last_rate_code = (t_u8) data[0];
+        if (mod_class == MOD_CLASS_OFDM) {
+            pg->first_rate_code = (t_u8) (data[0] - MLAN_RATE_INDEX_OFDM0);
+            pg->last_rate_code = (t_u8) (data[0] - MLAN_RATE_INDEX_OFDM0);
+        } else if (mod_class == MOD_CLASS_HT) {
+            pg->first_rate_code = (t_u8) (data[0] - MLAN_RATE_INDEX_MCS0);
+            pg->last_rate_code = (t_u8) (data[0] - MLAN_RATE_INDEX_MCS0);
+            pg->ht_bandwidth = ht_bw;
+        }
+        pg->power_min = (t_s8) data[1];
+        pg->power_max = (t_s8) data[1];
+        if (power->param.power_ext.len == 4) {
+            pg->power_max = (t_s8) data[2];
+            pg->power_step = (t_s8) data[3];
+        }
+        break;
+    default:
+        ret = MLAN_STATUS_FAILURE;
+        break;
+    }
+    if (ret == MLAN_STATUS_FAILURE) {
+        if (buf)
+            pcb->moal_mfree(buf);
+        goto exit;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_TXPWR_CFG,
+                           HostCmd_ACT_GEN_SET, 0, (t_void *) pioctl_req, buf);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+    if (buf)
+        pcb->moal_mfree(buf);
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Power configuration command handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_power_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_power_cfg *power = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_power_cfg)) {
+        PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_power_cfg);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    power = (mlan_ds_power_cfg *) pioctl_req->pbuf;
+    switch (power->sub_command) {
+    case MLAN_OID_POWER_CFG:
+        if (pioctl_req->action == MLAN_ACT_GET)
+            status = wlan_power_ioctl_get_power(pmadapter, pioctl_req);
+        else
+            status = wlan_power_ioctl_set_power(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_POWER_CFG_EXT:
+        if (pioctl_req->action == MLAN_ACT_GET)
+            status = wlan_power_ioctl_get_power(pmadapter, pioctl_req);
+        else
+            status = wlan_power_ioctl_set_power_ext(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set power save configurations
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *  @param ps_mode	Power save mode
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_pm_ioctl_ps_mode(IN pmlan_adapter pmadapter,
+                      IN pmlan_ioctl_req pioctl_req, IN t_u16 ps_mode)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    t_u16 sub_cmd;
+
+    ENTER();
+
+    sub_cmd = (pmadapter->ps_mode == Wlan802_11PowerModePSP) ? EN_PS : DIS_PS;
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_PS_MODE_ENH, sub_cmd,
+                           0, (t_void *) pioctl_req, MNULL);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set Host Sleep configurations
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *  @param phs_cfg	A pointer to HOST_SLEEP_CFG structure
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_pm_ioctl_hs_cfg(IN pmlan_adapter pmadapter,
+                     IN pmlan_ioctl_req pioctl_req,
+                     IN HostCmd_DS_802_11_HS_CFG_ENH * phs_cfg)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_HS_CFG_ENH,
+                           HostCmd_ACT_GEN_SET,
+                           0, (t_void *) pioctl_req, phs_cfg);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get Inactivity timeout extend
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_pm_ioctl_inactivity_timeout(IN pmlan_adapter pmadapter,
+                                 IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_pm_cfg *pmcfg = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    pmcfg = (mlan_ds_pm_cfg *) pioctl_req->pbuf;
+    cmd_action = HostCmd_ACT_GEN_GET;
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        cmd_action = HostCmd_ACT_GEN_SET;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_INACTIVITY_TIMEOUT_EXT,
+                           cmd_action, 0, (t_void *) pioctl_req,
+                           (t_void *) & pmcfg->param.inactivity_to);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Enable/Disable Auto Deep Sleep
+ *   
+ *  @param pmadapter 	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_set_auto_deep_sleep(IN pmlan_adapter pmadapter,
+                         IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = (pmlan_private) pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_auto_ds auto_ds;
+    t_u32 mode;
+
+    ENTER();
+
+    if (((mlan_ds_pm_cfg *) pioctl_req->pbuf)->param.auto_deep_sleep.auto_ds ==
+        DEEP_SLEEP_ON) {
+        auto_ds.auto_ds = DEEP_SLEEP_ON;
+        PRINTM(MINFO, "Auto Deep Sleep: on\n");
+        mode = EN_AUTO_DS;
+    } else {
+        auto_ds.auto_ds = DEEP_SLEEP_OFF;
+        PRINTM(MINFO, "AutoAUTO_DEEP_SLEEP Deep Sleep: off\n");
+        mode = DIS_AUTO_DS;
+    }
+    auto_ds.idletime =
+        ((mlan_ds_pm_cfg *) pioctl_req->pbuf)->param.auto_deep_sleep.idletime;
+
+    /* note: the command could be queued and executed later if there is
+       command in progress. */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_PS_MODE_ENH,
+                           mode, 0, (t_void *) pioctl_req, &auto_ds);
+
+    if (ret) {
+        LEAVE();
+        return ret;
+    }
+    ret = MLAN_STATUS_PENDING;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get sleep period
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_set_get_sleep_pd(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_pm_cfg *pm_cfg = MNULL;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    pm_cfg = (mlan_ds_pm_cfg *) pioctl_req->pbuf;
+    cmd_action = HostCmd_ACT_GEN_GET;
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        cmd_action = HostCmd_ACT_GEN_SET;
+    }
+
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SLEEP_PERIOD,
+                           cmd_action, 0, (t_void *) pioctl_req,
+                           &pm_cfg->param.sleep_period);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get PS configuration parameter
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_set_get_ps_cfg(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_ds_pm_cfg *pm_cfg = MNULL;
+
+    ENTER();
+
+    pm_cfg = (mlan_ds_pm_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        pm_cfg->param.ps_cfg.ps_null_interval =
+            (t_u32) pmadapter->null_pkt_interval;
+        pm_cfg->param.ps_cfg.multiple_dtim_interval =
+            (t_u32) pmadapter->multiple_dtim;
+        pm_cfg->param.ps_cfg.listen_interval =
+            (t_u32) pmadapter->local_listen_interval;
+        pm_cfg->param.ps_cfg.adhoc_awake_period =
+            (t_u32) pmadapter->adhoc_awake_period;
+        pm_cfg->param.ps_cfg.bcn_miss_timeout =
+            (t_u32) pmadapter->bcn_miss_time_out;
+        pm_cfg->param.ps_cfg.delay_to_ps = (t_u32) pmadapter->delay_to_ps;
+        pm_cfg->param.ps_cfg.ps_mode = (t_u32) pmadapter->enhanced_ps_mode;
+    } else {
+        if (pm_cfg->param.ps_cfg.ps_null_interval)
+            pmadapter->null_pkt_interval =
+                (t_u16) pm_cfg->param.ps_cfg.ps_null_interval;
+        else
+            pm_cfg->param.ps_cfg.ps_null_interval =
+                (t_u32) pmadapter->null_pkt_interval;
+        if (pm_cfg->param.ps_cfg.multiple_dtim_interval)
+            pmadapter->multiple_dtim =
+                (t_u16) pm_cfg->param.ps_cfg.multiple_dtim_interval;
+        else
+            pm_cfg->param.ps_cfg.multiple_dtim_interval =
+                (t_u32) pmadapter->multiple_dtim;
+        if (pm_cfg->param.ps_cfg.listen_interval)
+            pmadapter->local_listen_interval =
+                (t_u16) pm_cfg->param.ps_cfg.listen_interval;
+        else
+            pm_cfg->param.ps_cfg.listen_interval =
+                (t_u32) pmadapter->local_listen_interval;
+        if (pm_cfg->param.ps_cfg.adhoc_awake_period)
+            pmadapter->adhoc_awake_period =
+                (t_u16) pm_cfg->param.ps_cfg.adhoc_awake_period;
+        else
+            pm_cfg->param.ps_cfg.adhoc_awake_period =
+                (t_u32) pmadapter->adhoc_awake_period;
+        if (pm_cfg->param.ps_cfg.bcn_miss_timeout)
+            pmadapter->bcn_miss_time_out =
+                (t_u16) pm_cfg->param.ps_cfg.bcn_miss_timeout;
+        else
+            pm_cfg->param.ps_cfg.bcn_miss_timeout =
+                (t_u32) pmadapter->bcn_miss_time_out;
+        if (pm_cfg->param.ps_cfg.delay_to_ps != DELAY_TO_PS_UNCHANGED)
+            pmadapter->delay_to_ps = (t_u16) pm_cfg->param.ps_cfg.delay_to_ps;
+        else
+            pm_cfg->param.ps_cfg.delay_to_ps = (t_u32) pmadapter->delay_to_ps;
+        if (pm_cfg->param.ps_cfg.ps_mode)
+            pmadapter->enhanced_ps_mode = (t_u16) pm_cfg->param.ps_cfg.ps_mode;
+        else
+            pm_cfg->param.ps_cfg.ps_mode = (t_u32) pmadapter->enhanced_ps_mode;
+    }
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Get/Set the sleep parameters
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		        MLAN_STATUS_PENDING --success, otherwise fail
+ */
+static mlan_status
+wlan_set_get_sleep_params(IN pmlan_adapter pmadapter,
+                          IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_pm_cfg *pm_cfg = MNULL;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    pm_cfg = (mlan_ds_pm_cfg *) pioctl_req->pbuf;
+    cmd_action = HostCmd_ACT_GEN_GET;
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        cmd_action = HostCmd_ACT_GEN_SET;
+    }
+
+    /* Send command to firmware */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_802_11_SLEEP_PARAMS,
+                           cmd_action, 0, (t_void *) pioctl_req,
+                           &pm_cfg->param.sleep_params);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Power save command handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_pm_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_pm_cfg *pm = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_pm_cfg)) {
+        PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_pm_cfg);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    pm = (mlan_ds_pm_cfg *) pioctl_req->pbuf;
+    switch (pm->sub_command) {
+    case MLAN_OID_PM_CFG_IEEE_PS:
+        switch (pioctl_req->action) {
+        case MLAN_ACT_SET:
+            if (pm->param.ps_mode)
+                pmadapter->ps_mode = Wlan802_11PowerModePSP;
+            else
+                pmadapter->ps_mode = Wlan802_11PowerModeCAM;
+            status =
+                wlan_pm_ioctl_ps_mode(pmadapter, pioctl_req,
+                                      pmadapter->ps_mode);
+            break;
+        case MLAN_ACT_GET:
+            if (pmadapter->ps_mode == Wlan802_11PowerModePSP)
+                pm->param.ps_mode = 1;
+            else
+                pm->param.ps_mode = 0;
+            break;
+        default:
+            status = MLAN_STATUS_FAILURE;
+            break;
+        }
+        break;
+    case MLAN_OID_PM_CFG_HS_CFG:
+        switch (pioctl_req->action) {
+        case MLAN_ACT_SET:
+            pmadapter->hs_cfg.params.hs_config.conditions =
+                pm->param.hs_cfg.conditions;
+            pmadapter->hs_cfg.params.hs_config.gpio = pm->param.hs_cfg.gpio;
+            pmadapter->hs_cfg.params.hs_config.gap = pm->param.hs_cfg.gap;
+            if (pm->param.hs_cfg.is_invoke_hostcmd == MTRUE) {
+                status =
+                    wlan_pm_ioctl_hs_cfg(pmadapter, pioctl_req,
+                                         &pmadapter->hs_cfg);
+            }
+            break;
+        case MLAN_ACT_GET:
+            if (pmadapter->is_hs_configured) {
+                pm->param.hs_cfg.conditions =
+                    pmadapter->hs_cfg.params.hs_config.conditions;
+                pm->param.hs_cfg.gpio = pmadapter->hs_cfg.params.hs_config.gpio;
+                pm->param.hs_cfg.gap = pmadapter->hs_cfg.params.hs_config.gap;
+            }
+            break;
+        default:
+            status = MLAN_STATUS_FAILURE;
+            break;
+        }
+        break;
+    case MLAN_OID_PM_CFG_INACTIVITY_TO:
+        status = wlan_pm_ioctl_inactivity_timeout(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_PM_CFG_DEEP_SLEEP:
+        switch (pioctl_req->action) {
+        case MLAN_ACT_SET:
+            if (pmadapter->is_deep_sleep &&
+                pm->param.auto_deep_sleep.auto_ds == DEEP_SLEEP_ON) {
+                PRINTM(MMSG, "Station already in enhanced deep sleep mode\n");
+                status = MLAN_STATUS_FAILURE;
+                break;
+            } else if (!pmadapter->is_deep_sleep &&
+                       pm->param.auto_deep_sleep.auto_ds == DEEP_SLEEP_OFF) {
+                PRINTM(MMSG,
+                       "Station already not in enhanced deep sleep mode\n");
+                status = MLAN_STATUS_FAILURE;
+                break;
+            }
+            status = wlan_set_auto_deep_sleep(pmadapter, pioctl_req);
+            break;
+        case MLAN_ACT_GET:
+            if (pmadapter->is_deep_sleep)
+                pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_ON;
+            else
+                pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_OFF;
+            break;
+        default:
+            status = MLAN_STATUS_FAILURE;
+            break;
+        }
+        break;
+    case MLAN_OID_PM_CFG_PS_CFG:
+        status = wlan_set_get_ps_cfg(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_PM_CFG_SLEEP_PD:
+        status = wlan_set_get_sleep_pd(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_PM_CFG_SLEEP_PARAMS:
+        status = wlan_set_get_sleep_params(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set/Get WMM status
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_enable(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_wmm_cfg *wmm = MNULL;
+    ENTER();
+    wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET)
+        wmm->param.wmm_enable = (t_u32) pmpriv->wmm_required;
+    else
+        pmpriv->wmm_required = (t_u8) wmm->param.wmm_enable;
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get WMM QoS configuration
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_qos(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_wmm_cfg *wmm = MNULL;
+
+    ENTER();
+
+    wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+    if (pioctl_req->action == MLAN_ACT_GET)
+        wmm->param.qos_cfg = pmpriv->wmm_qosinfo;
+    else
+        pmpriv->wmm_qosinfo = wmm->param.qos_cfg;
+
+    pioctl_req->data_read_written = sizeof(t_u8) + MLAN_SUB_COMMAND_SIZE;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/get tid multi-port eligibility table
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_tid_elig_tbl(IN pmlan_adapter pmadapter,
+                            IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_wmm_cfg *wmm = MNULL;
+    t_u32 i;
+
+    ENTER();
+
+    wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        for (i = 0; i < MAX_NUM_TID; i++)
+            wmm->param.tid_tbl[i] = pmadapter->tx_eligibility[i];
+    } else {
+        for (i = 0; i < MAX_NUM_TID; i++) {
+            if (wmm->param.tid_tbl[i] >= pmadapter->mp_end_port)
+                ret = MLAN_STATUS_FAILURE;
+        }
+        if (ret == MLAN_STATUS_SUCCESS) {
+            for (i = 0; i < MAX_NUM_TID; i++) {
+                if (wmm->param.tid_tbl[i])
+                    pmadapter->tx_eligibility[i] = (t_u8) wmm->param.tid_tbl[i];
+            }
+        }
+    }
+
+    pioctl_req->data_read_written =
+        sizeof(wmm->param.tid_tbl) + MLAN_SUB_COMMAND_SIZE;
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Request for add a TSPEC
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pioctl_req   A pointer to ioctl request buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_addts_req(IN pmlan_adapter pmadapter,
+                         IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_wmm_cfg *cfg = MNULL;
+
+    ENTER();
+    cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_ADDTS_REQ,
+                           0, 0, (t_void *) pioctl_req,
+                           (t_void *) & cfg->param.addts);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Request for delete a TSPEC
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pioctl_req   A pointer to ioctl request buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_delts_req(IN pmlan_adapter pmadapter,
+                         IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_wmm_cfg *cfg = MNULL;
+
+    ENTER();
+    cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_DELTS_REQ,
+                           0, 0, (t_void *) pioctl_req,
+                           (t_void *) & cfg->param.delts);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get a specified AC Queue's parameters
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pioctl_req   A pointer to ioctl request buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_queue_config(IN pmlan_adapter pmadapter,
+                            IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_wmm_cfg *cfg = MNULL;
+
+    ENTER();
+    cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_QUEUE_CONFIG,
+                           0, 0, (t_void *) pioctl_req,
+                           (t_void *) & cfg->param.q_cfg);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief To get and start/stop queue stats on a WMM AC
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pioctl_req   A pointer to ioctl request buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_queue_stats(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_wmm_cfg *cfg = MNULL;
+
+    ENTER();
+    cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_QUEUE_STATS,
+                           0, 0, (t_void *) pioctl_req,
+                           (t_void *) & cfg->param.q_stats);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get the status of the WMM AC queues
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pioctl_req   A pointer to ioctl request buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_queue_status(IN pmlan_adapter pmadapter,
+                            IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_wmm_cfg *cfg = MNULL;
+    mlan_ds_wmm_queue_status *pqstatus = MNULL;
+    WmmAcStatus_t *pac_status = MNULL;
+    mlan_wmm_ac_e ac_idx;
+
+    ENTER();
+
+    cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+    pqstatus = (mlan_ds_wmm_queue_status *) & cfg->param.q_status;
+
+    for (ac_idx = WMM_AC_BK; ac_idx <= WMM_AC_VO; ac_idx++) {
+        pac_status = &pmpriv->wmm.ac_status[ac_idx];
+
+        /* Firmware status */
+        pqstatus->ac_status[ac_idx].flow_required = pac_status->flow_required;
+        pqstatus->ac_status[ac_idx].flow_created = pac_status->flow_created;
+        pqstatus->ac_status[ac_idx].disabled = pac_status->disabled;
+
+        /* ACM bit reflected in firmware status (redundant) */
+        pqstatus->ac_status[ac_idx].wmm_acm = pac_status->flow_required;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get the status of the WMM Traffic Streams
+ *
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param pioctl_req   A pointer to ioctl request buffer
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_ioctl_ts_status(IN pmlan_adapter pmadapter,
+                         IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_wmm_cfg *cfg = MNULL;
+
+    ENTER();
+
+    cfg = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv, HostCmd_CMD_WMM_TS_STATUS,
+                           0, 0, (t_void *) pioctl_req,
+                           (t_void *) & cfg->param.ts_status);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief WMM configuration handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wmm_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_wmm_cfg *wmm = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_wmm_cfg)) {
+        PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_wmm_cfg);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    wmm = (mlan_ds_wmm_cfg *) pioctl_req->pbuf;
+    switch (wmm->sub_command) {
+    case MLAN_OID_WMM_CFG_ENABLE:
+        status = wlan_wmm_ioctl_enable(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_WMM_CFG_QOS:
+        status = wlan_wmm_ioctl_qos(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_TID_ELIG_TBL:
+        status = wlan_wmm_ioctl_tid_elig_tbl(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_WMM_CFG_ADDTS:
+        status = wlan_wmm_ioctl_addts_req(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_WMM_CFG_DELTS:
+        status = wlan_wmm_ioctl_delts_req(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_WMM_CFG_QUEUE_CONFIG:
+        status = wlan_wmm_ioctl_queue_config(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_WMM_CFG_QUEUE_STATS:
+        status = wlan_wmm_ioctl_queue_stats(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_WMM_CFG_QUEUE_STATUS:
+        status = wlan_wmm_ioctl_queue_status(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_WMM_CFG_TS_STATUS:
+        status = wlan_wmm_ioctl_ts_status(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set/Get WPA IE   
+ *
+ *  @param priv         A pointer to mlan_private structure
+ *  @param ie_data_ptr  A pointer to IE
+ *  @param ie_len       Length of the IE
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+mlan_status
+wlan_set_wpa_ie_helper(mlan_private * priv, t_u8 * ie_data_ptr, t_u16 ie_len)
+{
+    ENTER();
+
+    if (ie_len) {
+        if (ie_len > sizeof(priv->wpa_ie)) {
+            PRINTM(MERROR, "failed to copy WPA IE, too big \n");
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+        memcpy(priv->wpa_ie, ie_data_ptr, ie_len);
+        priv->wpa_ie_len = (t_u8) ie_len;
+        PRINTM(MCMND, "Set Wpa_ie_len=%d IE=%#x\n", priv->wpa_ie_len,
+               priv->wpa_ie[0]);
+        DBG_HEXDUMP(MCMD_D, "Wpa_ie", priv->wpa_ie, priv->wpa_ie_len);
+        if (priv->wpa_ie[0] == WPA_IE) {
+            priv->sec_info.wpa_enabled = MTRUE;
+        } else if (priv->wpa_ie[0] == RSN_IE) {
+            priv->sec_info.wpa2_enabled = MTRUE;
+        } else {
+            priv->sec_info.wpa_enabled = MFALSE;
+            priv->sec_info.wpa2_enabled = MFALSE;
+        }
+    } else {
+        memset(priv->wpa_ie, 0, sizeof(priv->wpa_ie));
+        priv->wpa_ie_len = 0;
+        PRINTM(MINFO, "Reset Wpa_ie_len=%d IE=%#x\n", priv->wpa_ie_len,
+               priv->wpa_ie[0]);
+        priv->sec_info.wpa_enabled = MFALSE;
+        priv->sec_info.wpa2_enabled = MFALSE;
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Set WAPI IE   
+ *
+ *  @param priv         A pointer to mlan_private structure
+ *  @param ie_data_ptr  A pointer to IE
+ *  @param ie_len       Length of the IE
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+mlan_status
+wlan_set_wapi_ie(mlan_private * priv, t_u8 * ie_data_ptr, t_u16 ie_len)
+{
+    ENTER();
+    if (ie_len) {
+        if (ie_len > sizeof(priv->wapi_ie)) {
+            PRINTM(MINFO, "failed to copy WAPI IE, too big \n");
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+        memcpy(priv->wapi_ie, ie_data_ptr, ie_len);
+        priv->wapi_ie_len = ie_len;
+        PRINTM(MCMND, "Set wapi_ie_len=%d IE=%#x\n", priv->wapi_ie_len,
+               priv->wapi_ie[0]);
+        DBG_HEXDUMP(MCMD_D, "wapi_ie", priv->wapi_ie, priv->wapi_ie_len);
+        if (priv->wapi_ie[0] == WAPI_IE)
+            priv->sec_info.wapi_enabled = MTRUE;
+    } else {
+        memset(priv->wapi_ie, 0, sizeof(priv->wapi_ie));
+        priv->wapi_ie_len = ie_len;
+        PRINTM(MINFO, "Reset wapi_ie_len=%d IE=%#x\n", priv->wapi_ie_len,
+               priv->wapi_ie[0]);
+        priv->sec_info.wapi_enabled = MFALSE;
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Set/Get WAPI status
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_wapi_enable(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    ENTER();
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        if (pmpriv->wapi_ie_len)
+            sec->param.wapi_enabled = MTRUE;
+        else
+            sec->param.wapi_enabled = MFALSE;
+    } else {
+        if (sec->param.wapi_enabled == MFALSE)
+            wlan_set_wapi_ie(pmpriv, MNULL, 0);
+    }
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set WAPI key
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_set_wapi_key(IN pmlan_adapter pmadapter,
+                            IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    ENTER();
+
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_KEY_MATERIAL,
+                           HostCmd_ACT_GEN_SET,
+                           KEY_INFO_ENABLED,
+                           (t_void *) pioctl_req, &sec->param.encrypt_key);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get authentication mode
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_auth_mode(IN pmlan_adapter pmadapter,
+                         IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    ENTER();
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET)
+        sec->param.auth_mode = pmpriv->sec_info.authentication_mode;
+    else {
+        pmpriv->sec_info.authentication_mode = sec->param.auth_mode;
+        if (pmpriv->sec_info.authentication_mode == MLAN_AUTH_MODE_NETWORKEAP)
+            wlan_set_wpa_ie_helper(pmpriv, MNULL, 0);
+    }
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get encryption mode
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_encrypt_mode(IN pmlan_adapter pmadapter,
+                            IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    ENTER();
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET)
+        sec->param.encrypt_mode = pmpriv->sec_info.encryption_mode;
+    else {
+        pmpriv->sec_info.encryption_mode = sec->param.encrypt_mode;
+    }
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get WPA status
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_wpa_enable(IN pmlan_adapter pmadapter,
+                          IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    ENTER();
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        if (pmpriv->wpa_ie_len)
+            sec->param.wpa_enabled = MTRUE;
+        else
+            sec->param.wpa_enabled = MFALSE;
+    } else {
+        if (sec->param.wpa_enabled == MFALSE)
+            wlan_set_wpa_ie_helper(pmpriv, MNULL, 0);
+    }
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set WEP keys
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_set_wep_key(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    mrvl_wep_key_t *pwep_key = MNULL;
+    int index;
+
+    ENTER();
+
+    if (pmpriv->wep_key_curr_index >= MRVL_NUM_WEP_KEY)
+        pmpriv->wep_key_curr_index = 0;
+    pwep_key = &pmpriv->wep_key[pmpriv->wep_key_curr_index];
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    if (sec->param.encrypt_key.is_current_wep_key == MTRUE)
+        index = pmpriv->wep_key_curr_index;
+    else
+        index = sec->param.encrypt_key.key_index;
+    if (sec->param.encrypt_key.key_disable == MTRUE) {
+        if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled &&
+            pmpriv->media_connected == MTRUE &&
+            pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) {
+            PRINTM(MERROR, "Can not disable key in IBSS connected state\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+        pmpriv->sec_info.wep_status = Wlan802_11WEPDisabled;
+    } else if (!sec->param.encrypt_key.key_len) {
+        if (pmpriv->sec_info.wep_status != Wlan802_11WEPEnabled &&
+            pmpriv->media_connected == MTRUE &&
+            pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) {
+            PRINTM(MERROR, "Can not enable key in IBSS connected state\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+        /* Copy the required key as the current key */
+        pwep_key = &pmpriv->wep_key[index];
+        if (!pwep_key->key_length) {
+            PRINTM(MERROR, "Key not set,so cannot enable it\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+        pmpriv->wep_key_curr_index = (t_u16) index;
+        pmpriv->sec_info.wep_status = Wlan802_11WEPEnabled;
+    } else {
+        pwep_key = &pmpriv->wep_key[index];
+        /* Cleanup */
+        memset(pwep_key, 0, sizeof(mrvl_wep_key_t));
+        /* Copy the key in the driver */
+        memcpy(pwep_key->key_material, sec->param.encrypt_key.key_material,
+               sec->param.encrypt_key.key_len);
+        pwep_key->key_index = index;
+        pwep_key->key_length = sec->param.encrypt_key.key_len;
+        if (pmpriv->sec_info.wep_status != Wlan802_11WEPEnabled) {
+            /* 
+             * The status is set as Key Absent 
+             * so as to make sure we display the 
+             * keys when iwlist mlanX key is used
+             */
+            pmpriv->sec_info.wep_status = Wlan802_11WEPKeyAbsent;
+        }
+        pmpriv->wep_key_curr_index = (t_u16) index;
+    }
+    if (pwep_key->key_length) {
+        /* Send request to firmware */
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_802_11_KEY_MATERIAL,
+                               HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
+        if (ret)
+            goto exit;
+    }
+    if (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)
+        pmpriv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
+    else
+        pmpriv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_MAC_CONTROL,
+                           HostCmd_ACT_GEN_SET,
+                           0, (t_void *) pioctl_req, &pmpriv->curr_pkt_filter);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set WPA key
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_set_wpa_key(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    t_u8 remove_key = MFALSE;
+    HostCmd_DS_802_11_KEY_MATERIAL *pibss_key;
+
+    ENTER();
+
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    /* Current driver only supports key length of up to 32 bytes */
+    if (sec->param.encrypt_key.key_len > MLAN_MAX_KEY_LENGTH) {
+        PRINTM(MERROR, " Error in key length \n");
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS) {
+        /* 
+         * IBSS/WPA-None uses only one key (Group) for both receiving and
+         *  sending unicast and multicast packets.
+         */
+        /* Send the key as PTK to firmware */
+        sec->param.encrypt_key.key_index = 0x40000000;
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_802_11_KEY_MATERIAL,
+                               HostCmd_ACT_GEN_SET,
+                               KEY_INFO_ENABLED,
+                               MNULL, &sec->param.encrypt_key);
+        if (ret)
+            goto exit;
+
+        pibss_key = &pmpriv->aes_key;
+        memset(pibss_key, 0, sizeof(HostCmd_DS_802_11_KEY_MATERIAL));
+        /* Copy the key in the driver */
+        memcpy(pibss_key->key_param_set.key,
+               sec->param.encrypt_key.key_material,
+               sec->param.encrypt_key.key_len);
+        memcpy(&pibss_key->key_param_set.key_len,
+               &sec->param.encrypt_key.key_len,
+               sizeof(pibss_key->key_param_set.key_len));
+        pibss_key->key_param_set.key_type_id = KEY_TYPE_ID_TKIP;
+        pibss_key->key_param_set.key_info = KEY_INFO_TKIP_ENABLED;
+
+        /* Send the key as GTK to firmware */
+        sec->param.encrypt_key.key_index = ~0x40000000;
+    }
+    if (pmpriv->bss_mode == MLAN_BSS_MODE_IBSS &&
+        sec->param.encrypt_key.key_len == WPA_AES_KEY_LEN) {
+        t_u8 zero_key_material[WPA_AES_KEY_LEN];
+
+        memset(zero_key_material, 0, sizeof(zero_key_material));
+        if (memcmp(sec->param.encrypt_key.key_material, zero_key_material,
+                   WPA_AES_KEY_LEN)) {
+            PRINTM(MINFO, "Adhoc AES Enabled.\n");
+            pmpriv->adhoc_aes_enabled = MTRUE;
+            remove_key = MFALSE;
+        } else {
+            PRINTM(MINFO, "Adhoc AES Disabled.\n");
+            pmpriv->adhoc_aes_enabled = MFALSE;
+            remove_key = MTRUE;
+        }
+    }
+
+    if (!sec->param.encrypt_key.key_index)
+        sec->param.encrypt_key.key_index = 0x40000000;
+
+    if (remove_key == MTRUE) {
+        /* Send request to firmware */
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_802_11_KEY_MATERIAL,
+                               HostCmd_ACT_GEN_SET,
+                               !(KEY_INFO_ENABLED),
+                               (t_void *) pioctl_req, &sec->param.encrypt_key);
+    } else {
+        /* Send request to firmware */
+        ret = wlan_prepare_cmd(pmpriv,
+                               HostCmd_CMD_802_11_KEY_MATERIAL,
+                               HostCmd_ACT_GEN_SET,
+                               KEY_INFO_ENABLED,
+                               (t_void *) pioctl_req, &sec->param.encrypt_key);
+    }
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get security keys
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_get_key(IN pmlan_adapter pmadapter,
+                       IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    int index;
+    ENTER();
+
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+
+    if (pmpriv->adhoc_aes_enabled == MTRUE &&
+        (pmpriv->aes_key.key_param_set.key_len == WPA_AES_KEY_LEN)) {
+        HEXDUMP("Get WPA Key", pmpriv->aes_key.key_param_set.key,
+                WPA_AES_KEY_LEN);
+        memcpy(sec->param.encrypt_key.key_material,
+               pmpriv->aes_key.key_param_set.key, WPA_AES_KEY_LEN);
+        LEAVE();
+        return ret;
+
+    }
+
+    if (pmpriv->wep_key_curr_index >= MRVL_NUM_WEP_KEY)
+        pmpriv->wep_key_curr_index = 0;
+
+    if ((pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)
+        || (pmpriv->sec_info.wep_status == Wlan802_11WEPKeyAbsent)
+        || pmpriv->sec_info.ewpa_enabled
+        || pmpriv->sec_info.wpa_enabled || pmpriv->sec_info.wpa2_enabled) {
+        sec->param.encrypt_key.key_disable = MFALSE;
+    } else {
+        sec->param.encrypt_key.key_disable = MTRUE;
+    }
+
+    if (sec->param.encrypt_key.is_current_wep_key == MTRUE) {
+        if ((pmpriv->wep_key[pmpriv->wep_key_curr_index].key_length) &&
+            (pmpriv->sec_info.wep_status == Wlan802_11WEPEnabled)) {
+            index = pmpriv->wep_key_curr_index;
+            sec->param.encrypt_key.key_index = pmpriv->wep_key[index].key_index;
+            memcpy(sec->param.encrypt_key.key_material,
+                   pmpriv->wep_key[index].key_material,
+                   pmpriv->wep_key[index].key_length);
+            sec->param.encrypt_key.key_len = pmpriv->wep_key[index].key_length;
+        } else if ((pmpriv->sec_info.wpa_enabled)
+                   || (pmpriv->sec_info.ewpa_enabled)
+                   || (pmpriv->sec_info.wpa2_enabled)
+            ) {
+            /* Return WPA enabled */
+            sec->param.encrypt_key.key_disable = MFALSE;
+            memcpy(sec->param.encrypt_key.key_material,
+                   pmpriv->aes_key.key_param_set.key,
+                   pmpriv->aes_key.key_param_set.key_len);
+            sec->param.encrypt_key.key_len =
+                pmpriv->aes_key.key_param_set.key_len;
+        } else {
+            sec->param.encrypt_key.key_disable = MTRUE;
+        }
+    } else {
+        index = sec->param.encrypt_key.key_index;
+        if (pmpriv->wep_key[index].key_length) {
+            sec->param.encrypt_key.key_index = pmpriv->wep_key[index].key_index;
+            memcpy(sec->param.encrypt_key.key_material,
+                   pmpriv->wep_key[index].key_material,
+                   pmpriv->wep_key[index].key_length);
+            sec->param.encrypt_key.key_len = pmpriv->wep_key[index].key_length;
+        } else if ((pmpriv->sec_info.wpa_enabled)
+                   || (pmpriv->sec_info.ewpa_enabled)
+                   || (pmpriv->sec_info.wpa2_enabled)
+            ) {
+            /* Return WPA enabled */
+            sec->param.encrypt_key.key_disable = MFALSE;
+        } else {
+            sec->param.encrypt_key.key_disable = MTRUE;
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set security key(s)
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_encrypt_key(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_sec_cfg *sec = MNULL;
+    ENTER();
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        if (sec->param.encrypt_key.is_wapi_key)
+            status = wlan_sec_ioctl_set_wapi_key(pmadapter, pioctl_req);
+        else if (sec->param.encrypt_key.key_len > MAX_WEP_KEY_SIZE)
+            status = wlan_sec_ioctl_set_wpa_key(pmadapter, pioctl_req);
+        else
+            status = wlan_sec_ioctl_set_wep_key(pmadapter, pioctl_req);
+    } else {
+        status = wlan_sec_ioctl_get_key(pmadapter, pioctl_req);
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set/Get WPA passphrase for esupplicant
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_passphrase(IN pmlan_adapter pmadapter,
+                          IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    t_u16 cmd_action = 0;
+    BSSDescriptor_t *pbss_desc;
+    int i = 0;
+
+    ENTER();
+
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        if (sec->param.passphrase.psk_type == MLAN_PSK_CLEAR)
+            cmd_action = HostCmd_ACT_GEN_REMOVE;
+        else
+            cmd_action = HostCmd_ACT_GEN_SET;
+    } else {
+        if (sec->param.passphrase.psk_type == MLAN_PSK_QUERY) {
+            if (sec->param.passphrase.ssid.ssid_len == 0) {
+                i = wlan_find_bssid_in_list(pmpriv,
+                                            (t_u8 *) & sec->param.passphrase.
+                                            bssid, MLAN_BSS_MODE_AUTO);
+                if (i > 0) {
+                    pbss_desc = &pmadapter->pscan_table[i];
+                    memcpy(&sec->param.passphrase.ssid, &pbss_desc->ssid,
+                           sizeof(mlan_802_11_ssid));
+                    memset(&sec->param.passphrase.bssid, 0,
+                           MLAN_MAC_ADDR_LENGTH);
+                    PRINTM(MCMND, "PSK_QUERY: found ssid=%s\n",
+                           sec->param.passphrase.ssid.ssid);
+                }
+            } else
+                memset(&sec->param.passphrase.bssid, 0, MLAN_MAC_ADDR_LENGTH);
+        }
+        cmd_action = HostCmd_ACT_GEN_GET;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_SUPPLICANT_PMK,
+                           cmd_action,
+                           0, (t_void *) pioctl_req, &sec->param.passphrase);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get esupplicant status
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_ewpa_enable(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_sec_cfg *sec = MNULL;
+    ENTER();
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        sec->param.ewpa_enabled = pmpriv->sec_info.ewpa_enabled;
+    } else {
+        pmpriv->sec_info.ewpa_enabled = (t_u8) sec->param.ewpa_enabled;
+        PRINTM(MCMND, "Set: ewpa_enabled = %d\n",
+               (int) pmpriv->sec_info.ewpa_enabled);
+    }
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get esupplicant mode
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_ioctl_esupp_mode(IN pmlan_adapter pmadapter,
+                          IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+
+    ENTER();
+
+    if (pmpriv->media_connected != MTRUE) {
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_SUPPLICANT_PROFILE,
+                           HostCmd_ACT_GEN_GET_CURRENT,
+                           0, (t_void *) pioctl_req, MNULL);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Security configuration handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_sec_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_sec_cfg *sec = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_sec_cfg)) {
+        PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_sec_cfg);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    sec = (mlan_ds_sec_cfg *) pioctl_req->pbuf;
+    switch (sec->sub_command) {
+    case MLAN_OID_SEC_CFG_AUTH_MODE:
+        status = wlan_sec_ioctl_auth_mode(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_SEC_CFG_ENCRYPT_MODE:
+        status = wlan_sec_ioctl_encrypt_mode(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_SEC_CFG_WPA_ENABLED:
+        status = wlan_sec_ioctl_wpa_enable(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_SEC_CFG_WAPI_ENABLED:
+        status = wlan_sec_ioctl_wapi_enable(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_SEC_CFG_ENCRYPT_KEY:
+        status = wlan_sec_ioctl_encrypt_key(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_SEC_CFG_PASSPHRASE:
+        status = wlan_sec_ioctl_passphrase(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_SEC_CFG_EWPA_ENABLED:
+        status = wlan_sec_ioctl_ewpa_enable(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_SEC_CFG_ESUPP_MODE:
+        status = wlan_sec_ioctl_esupp_mode(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief  Append/Reset IE buffer. 
+ *   
+ *  Pass an opaque block of data, expected to be IEEE IEs, to the driver 
+ *    for eventual passthrough to the firmware in an associate/join 
+ *    (and potentially start) command.  This function is the main body
+ *    for both wlan_set_gen_ie_ioctl and wlan_set_gen_ie
+ *
+ *  Data is appended to an existing buffer and then wrapped in a passthrough
+ *    TLV in the command API to the firmware.  The firmware treats the data
+ *    as a transparent passthrough to the transmitted management frame.
+ *
+ *  @param priv         A pointer to mlan_private structure
+ *  @param ie_data_ptr  A pointer to iwreq structure
+ *  @param ie_len       Length of the IE or IE block passed in ie_data_ptr
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+int
+wlan_set_gen_ie_helper(mlan_private * priv, t_u8 * ie_data_ptr, t_u16 ie_len)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    IEEEtypes_VendorHeader_t *pvendor_ie;
+    const t_u8 wpa_oui[] = { 0x00, 0x50, 0xf2, 0x01 };
+    const t_u8 wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 };
+
+    ENTER();
+
+    /* If the passed length is zero, reset the buffer */
+    if (!ie_len) {
+        priv->gen_ie_buf_len = 0;
+        priv->wps.session_enable = MFALSE;
+    } else if (!ie_data_ptr) {
+        /* MNULL check */
+        ret = MLAN_STATUS_FAILURE;
+    } else {
+
+        pvendor_ie = (IEEEtypes_VendorHeader_t *) ie_data_ptr;
+        /* Test to see if it is a WPA IE, if not, then it is a gen IE */
+        if (((pvendor_ie->element_id == WPA_IE)
+             && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui))))
+            || (pvendor_ie->element_id == RSN_IE)
+            ) {
+
+            /* IE is a WPA/WPA2 IE so call set_wpa function */
+            ret = wlan_set_wpa_ie_helper(priv, ie_data_ptr, ie_len);
+            priv->wps.session_enable = MFALSE;
+        } else if (pvendor_ie->element_id == WAPI_IE) {
+            /* IE is a WAPI IE so call set_wapi function */
+            ret = wlan_set_wapi_ie(priv, ie_data_ptr, ie_len);
+        } else {
+            /* 
+             * Verify that the passed length is not larger than the available 
+             * space remaining in the buffer
+             */
+            if (ie_len < (sizeof(priv->gen_ie_buf) - priv->gen_ie_buf_len)) {
+
+                /* Test to see if it is a WPS IE, if so, enable wps session
+                   flag */
+                pvendor_ie = (IEEEtypes_VendorHeader_t *) ie_data_ptr;
+                if ((pvendor_ie->element_id == WPS_IE)
+                    && (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) {
+                    priv->wps.session_enable = MTRUE;
+                    PRINTM(MINFO, "WPS Session Enabled.\n");
+                }
+
+                /* Append the passed data to the end of the genIeBuffer */
+                memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr,
+                       ie_len);
+                /* Increment the stored buffer length by the size passed */
+                priv->gen_ie_buf_len += ie_len;
+            } else {
+                /* Passed data does not fit in the remaining buffer space */
+                ret = MLAN_STATUS_FAILURE;
+            }
+        }
+    }
+
+    /* Return MLAN_STATUS_SUCCESS, or MLAN_STATUS_FAILURE for error case */
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief  Get IE buffer from driver 
+ *   
+ *  Used to pass an opaque block of data, expected to be IEEE IEs,
+ *    back to the application.  Currently the data block passed
+ *    back to the application is the saved association response retrieved 
+ *    from the firmware.
+ *
+ *  @param priv         A pointer to mlan_private structure
+ *  @param ie_data_ptr  A pointer to the IE or IE block
+ *  @param ie_len_ptr   In/Out parameter pointer for the buffer length passed 
+ *                      in ie_data_ptr and the resulting data length copied
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+int
+wlan_get_gen_ie_helper(mlan_private * priv, t_u8 * ie_data_ptr,
+                       t_u16 * ie_len_ptr)
+{
+    IEEEtypes_AssocRsp_t *passoc_rsp;
+    t_u16 copy_size;
+
+    ENTER();
+
+    if ((priv->media_connected == MFALSE) || (priv->assoc_rsp_size == 0)) {
+        *ie_len_ptr = 0;
+        LEAVE();
+        return MLAN_STATUS_SUCCESS;
+    }
+
+    passoc_rsp = (IEEEtypes_AssocRsp_t *) priv->assoc_rsp_buf;
+
+    /* 
+     * Set the amount to copy back to the application as the minimum of the 
+     *   available IE data or the buffer provided by the application
+     */
+    copy_size = (t_u16) (priv->assoc_rsp_size - sizeof(passoc_rsp->capability)
+                         - sizeof(passoc_rsp->status_code) -
+                         sizeof(passoc_rsp->a_id));
+    copy_size = MIN(copy_size, *ie_len_ptr);
+
+    /* Copy the IEEE TLVs in the assoc response back to the application */
+    memcpy(ie_data_ptr, (t_u8 *) passoc_rsp->ie_buffer, copy_size);
+    /* Returned copy length */
+    *ie_len_ptr = copy_size;
+    /* No error on return */
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Set/Get WWS mode
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_misc_ioctl_wws_cfg(IN pmlan_adapter pmadapter,
+                        IN pmlan_ioctl_req pioctl_req)
+{
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_misc_cfg *misc_cfg = MNULL;
+    t_u16 cmd_action = 0;
+    t_u32 enable = 0;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_misc_cfg)) {
+        PRINTM(MWARN, "MLAN IOCTL information buffer length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_misc_cfg);
+        ret = MLAN_STATUS_RESOURCE;
+        goto exit;
+    }
+
+    misc_cfg = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_SET)
+        cmd_action = HostCmd_ACT_GEN_SET;
+    else
+        cmd_action = HostCmd_ACT_GEN_GET;
+
+    enable = misc_cfg->param.wws_cfg;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_SNMP_MIB,
+                           cmd_action,
+                           WwsMode_i, (t_void *) pioctl_req, &enable);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+
+}
+
+/** 
+ *  @brief Set/Get 11D status
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_11d_cfg_ioctl_enable(IN pmlan_adapter pmadapter,
+                          IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_11d_cfg *pcfg_11d = MNULL;
+
+    ENTER();
+
+    pcfg_11d = (mlan_ds_11d_cfg *) pioctl_req->pbuf;
+
+    if (pioctl_req->action == MLAN_ACT_SET) {
+        PRINTM(MINFO, "11D: 11dcfg SET=%d\n", pcfg_11d->param.enable_11d);
+
+        /* Compare with current settings */
+        if (pmadapter->state_11d.user_enable_11d != pcfg_11d->param.enable_11d) {
+            ret =
+                wlan_11d_enable(pmpriv, pioctl_req,
+                                (state_11d_t) pcfg_11d->param.enable_11d);
+            if (ret == MLAN_STATUS_SUCCESS)
+                ret = MLAN_STATUS_PENDING;
+        } else {
+            PRINTM(MINFO, "11D: same as current setting, do nothing\n");
+        }
+    } else {
+        pcfg_11d->param.enable_11d =
+            (t_u32) pmadapter->state_11d.user_enable_11d;
+        pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+        PRINTM(MINFO, "11D: 11dcfg GET=%d\n", pcfg_11d->param.enable_11d);
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief 11D configuration handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_11d_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_11d_cfg *pcfg_11d = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_11d_cfg)) {
+        PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_11d_cfg);
+        status = MLAN_STATUS_RESOURCE;
+        goto exit;
+    }
+
+    pcfg_11d = (mlan_ds_11d_cfg *) pioctl_req->pbuf;
+    switch (pcfg_11d->sub_command) {
+    case MLAN_OID_11D_CFG_ENABLE:
+        status = wlan_11d_cfg_ioctl_enable(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+
+  exit:
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief WPS configuration handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_wps_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_wps_cfg *pwps = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_wps_cfg)) {
+        PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_wps_cfg);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+
+    pwps = (mlan_ds_wps_cfg *) pioctl_req->pbuf;
+    switch (pwps->sub_command) {
+    case MLAN_OID_WPS_CFG_SESSION:
+        if (pioctl_req->action == MLAN_ACT_SET) {
+            if (pwps->param.wps_session == MLAN_WPS_CFG_SESSION_START ||
+                pwps->param.wps_session == MLAN_WPS_CFG_SESSION_END)
+                pmpriv->wps.session_enable = (t_u8) pwps->param.wps_session;
+            else
+                pmpriv->wps.session_enable = MLAN_WPS_CFG_SESSION_END;
+        } else {
+            pwps->param.wps_session = (t_u32) pmpriv->wps.session_enable;
+            pioctl_req->data_read_written = sizeof(t_u32);
+            PRINTM(MINFO, "wpscfg GET=%d\n", pwps->param.wps_session);
+        }
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Read/write adapter register
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_reg_mem_ioctl_reg_rw(IN pmlan_adapter pmadapter,
+                          IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_reg_mem *reg_mem = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 cmd_action = 0, cmd_no;
+
+    ENTER();
+
+    reg_mem = (mlan_ds_reg_mem *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET)
+        cmd_action = HostCmd_ACT_GEN_GET;
+    else
+        cmd_action = HostCmd_ACT_GEN_SET;
+
+    switch (reg_mem->param.reg_rw.type) {
+    case MLAN_REG_MAC:
+        cmd_no = HostCmd_CMD_MAC_REG_ACCESS;
+        break;
+    case MLAN_REG_BBP:
+        cmd_no = HostCmd_CMD_BBP_REG_ACCESS;
+        break;
+    case MLAN_REG_RF:
+        cmd_no = HostCmd_CMD_RF_REG_ACCESS;
+        break;
+    case MLAN_REG_PMIC:
+        cmd_no = HostCmd_CMD_PMIC_REG_ACCESS;
+        break;
+    case MLAN_REG_CAU:
+        cmd_no = HostCmd_CMD_CAU_REG_ACCESS;
+        break;
+    default:
+        ret = MLAN_STATUS_FAILURE;
+        goto exit;
+    }
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv, cmd_no, cmd_action,
+                           0, (t_void *) pioctl_req,
+                           (t_void *) & reg_mem->param.reg_rw);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+  exit:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Read the EEPROM contents of the card 
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_reg_mem_ioctl_read_eeprom(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_reg_mem *reg_mem = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    reg_mem = (mlan_ds_reg_mem *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET)
+        cmd_action = HostCmd_ACT_GEN_GET;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_EEPROM_ACCESS,
+                           cmd_action, 0, (t_void *) pioctl_req,
+                           (t_void *) & reg_mem->param.rd_eeprom);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Read/write memory of device
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_reg_mem_ioctl_mem_rw(IN pmlan_adapter pmadapter,
+                          IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_reg_mem *reg_mem = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    reg_mem = (mlan_ds_reg_mem *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET)
+        cmd_action = HostCmd_ACT_GEN_GET;
+    else
+        cmd_action = HostCmd_ACT_GEN_SET;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_MEM_ACCESS,
+                           cmd_action, 0,
+                           (t_void *) pioctl_req,
+                           (t_void *) & reg_mem->param.mem_rw);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief register memory access handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_reg_mem_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_reg_mem *reg_mem = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_reg_mem)) {
+        PRINTM(MWARN, "MLAN REG_MEM IOCTL length is too short\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_reg_mem);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    reg_mem = (mlan_ds_reg_mem *) pioctl_req->pbuf;
+    switch (reg_mem->sub_command) {
+    case MLAN_OID_REG_RW:
+        status = wlan_reg_mem_ioctl_reg_rw(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_EEPROM_RD:
+        status = wlan_reg_mem_ioctl_read_eeprom(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_MEM_RW:
+        status = wlan_reg_mem_ioctl_mem_rw(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set/Get BCA time share parameters
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bca_cfg_ioctl_bca_ts(IN pmlan_adapter pmadapter,
+                          IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_bca_cfg *bca_cfg = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    bca_cfg = (mlan_ds_bca_cfg *) pioctl_req->pbuf;
+    cmd_action = HostCmd_ACT_GEN_GET;
+    if (pioctl_req->action == MLAN_ACT_SET)
+        cmd_action = HostCmd_ACT_GEN_SET;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_BCA_CONFIG_TIMESHARE,
+                           cmd_action, 0, (t_void *) pioctl_req,
+                           (t_void *) & bca_cfg->param.bca_ts);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief BCA configuration handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_bca_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_bca_cfg *bca_cfg = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_bca_cfg)) {
+        PRINTM(MWARN, "MLAN_IOCTL_BCA_CFG IOCTL length is too short\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_bca_cfg);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    bca_cfg = (mlan_ds_bca_cfg *) pioctl_req->pbuf;
+    switch (bca_cfg->sub_command) {
+    case MLAN_OID_BCA_TS:
+        status = wlan_bca_cfg_ioctl_bca_ts(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set/Get generic IE
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_misc_ioctl_gen_ie(IN pmlan_adapter pmadapter,
+                       IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_misc_cfg *misc = MNULL;
+
+    ENTER();
+
+    misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+    switch (misc->param.gen_ie.type) {
+    case MLAN_IE_TYPE_GEN_IE:
+        if (pioctl_req->action == MLAN_ACT_GET) {
+            misc->param.gen_ie.len = pmpriv->wpa_ie_len;
+            memcpy(misc->param.gen_ie.ie_data, pmpriv->wpa_ie,
+                   misc->param.gen_ie.len);
+        } else {
+            wlan_set_gen_ie_helper(pmpriv, misc->param.gen_ie.ie_data,
+                                   (t_u16) misc->param.gen_ie.len);
+        }
+        break;
+    case MLAN_IE_TYPE_ARP_FILTER:
+        memset(pmadapter->arp_filter, 0, sizeof(pmadapter->arp_filter));
+        if (misc->param.gen_ie.len > ARP_FILTER_MAX_BUF_SIZE) {
+            pmadapter->arp_filter_size = 0;
+            PRINTM(MERROR, "Invalid ARP Filter Size\n");
+            ret = MLAN_STATUS_FAILURE;
+        } else {
+            memcpy(pmadapter->arp_filter, misc->param.gen_ie.ie_data,
+                   misc->param.gen_ie.len);
+            pmadapter->arp_filter_size = misc->param.gen_ie.len;
+            HEXDUMP("ArpFilter", pmadapter->arp_filter,
+                    pmadapter->arp_filter_size);
+        }
+        break;
+    default:
+        PRINTM(MERROR, "Invalid IE type\n");
+        ret = MLAN_STATUS_FAILURE;
+    }
+    pioctl_req->data_read_written =
+        sizeof(mlan_ds_misc_gen_ie) + MLAN_SUB_COMMAND_SIZE;
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get region code
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_misc_ioctl_region(IN pmlan_adapter pmadapter,
+                       IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_misc_cfg *misc = MNULL;
+    int i;
+
+    ENTER();
+
+    misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET) {
+        misc->param.region_code = pmadapter->region_code;
+    } else {
+        for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
+            /* Use the region code to search for the index */
+            if (misc->param.region_code == region_code_index[i]) {
+                pmadapter->region_code = (t_u16) misc->param.region_code;
+                break;
+            }
+        }
+        /* It's unidentified region code */
+        if (i >= MRVDRV_MAX_REGION_CODE) {
+            PRINTM(MERROR, "Region Code not identified\n");
+            LEAVE();
+            return MLAN_STATUS_FAILURE;
+        }
+        if (wlan_set_regiontable(pmpriv, (t_u8) pmadapter->region_code,
+                                 pmadapter->config_bands)) {
+            ret = MLAN_STATUS_FAILURE;
+        }
+    }
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Perform warm reset
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_PENDING
+ */
+static mlan_status
+wlan_misc_ioctl_warm_reset(IN pmlan_adapter pmadapter,
+                           IN pmlan_ioctl_req pioctl_req)
+{
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    pmlan_callbacks pcb = &pmadapter->callbacks;
+    HostCmd_DS_VERSION_EXT dummy;
+    t_s32 i = 0;
+    t_u8 first_sta = MTRUE;
+
+    ENTER();
+
+    /** Init all the head nodes and free all the locks here */
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        pmpriv = pmadapter->priv[i];
+        if (pmadapter->priv[i]) {
+            wlan_wmm_cleanup_node(pmpriv);
+            pcb->moal_free_lock(pmpriv->rx_pkt_lock);
+            pcb->moal_free_lock(pmpriv->wmm.ra_list_spinlock);
+        }
+    }
+
+    /* Initialize adapter structure */
+    wlan_init_adapter(pmadapter);
+
+    /* Initialize private structures */
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        pmpriv = pmadapter->priv[i];
+        if (pmadapter->priv[i])
+            wlan_init_priv(pmpriv);
+    }
+
+    pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    /* Restart the firmware */
+    wlan_prepare_cmd(pmpriv, HostCmd_CMD_FUNC_SHUTDOWN,
+                     HostCmd_ACT_GEN_SET, 0, MNULL, MNULL);
+
+    /* Issue commands to initialize firmware */
+    for (i = 0; i < MLAN_MAX_BSS_NUM; i++) {
+        if (pmadapter->priv[i]) {
+            pmadapter->priv[i]->ops.init_cmd(pmadapter->priv[i], first_sta);
+            first_sta = MFALSE;
+        }
+    }
+
+    /* Issue dummy Get command to complete the ioctl */
+    memset(&dummy, 0, sizeof(HostCmd_DS_VERSION_EXT));
+    wlan_prepare_cmd(pmpriv, HostCmd_CMD_VERSION_EXT, HostCmd_ACT_GEN_GET,
+                     0, (t_void *) pioctl_req, (t_void *) & dummy);
+
+    LEAVE();
+    return MLAN_STATUS_PENDING;
+}
+
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+/** 
+ *  @brief Reconfigure SDIO multiport aggregation parameters
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_misc_ioctl_sdio_mpa_ctrl(IN pmlan_adapter pmadapter,
+                              IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_misc_cfg *misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+    mlan_ds_misc_sdio_mpa_ctrl *mpa_ctrl = MNULL;
+
+    ENTER();
+
+    mpa_ctrl = &misc->param.mpa_ctrl;
+
+    if (pioctl_req->action == MLAN_ACT_SET) {
+
+        if (pmpriv->media_connected == MTRUE) {
+            PRINTM(MMSG, "SDIO MP-A CTRL: not allowed\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+
+        if (mpa_ctrl->tx_enable > 1) {
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+
+        if (mpa_ctrl->rx_enable > 1) {
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+
+        if (mpa_ctrl->tx_max_ports > SDIO_MP_AGGR_DEF_PKT_LIMIT) {
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+
+        if (mpa_ctrl->rx_max_ports > SDIO_MP_AGGR_DEF_PKT_LIMIT) {
+            ret = MLAN_STATUS_FAILURE;
+            goto exit;
+        }
+
+        if (mpa_ctrl->tx_buf_size || mpa_ctrl->rx_buf_size) {
+
+            wlan_free_sdio_mpa_buffers(pmadapter);
+
+            if (mpa_ctrl->tx_buf_size > 0)
+                pmadapter->mpa_tx.buf_size = mpa_ctrl->tx_buf_size;
+
+            if (mpa_ctrl->rx_buf_size > 0)
+                pmadapter->mpa_rx.buf_size = mpa_ctrl->rx_buf_size;
+
+            if (wlan_alloc_sdio_mpa_buffers(pmadapter,
+                                            pmadapter->mpa_tx.buf_size,
+                                            pmadapter->mpa_rx.buf_size) !=
+                MLAN_STATUS_SUCCESS) {
+                PRINTM(MERROR, "Failed to allocate sdio mp-a buffers\n");
+                ret = MLAN_STATUS_FAILURE;
+                goto exit;
+            }
+        }
+
+        if (mpa_ctrl->tx_max_ports > 0)
+            pmadapter->mpa_tx.pkt_aggr_limit = mpa_ctrl->tx_max_ports;
+        if (mpa_ctrl->rx_max_ports > 0)
+            pmadapter->mpa_rx.pkt_aggr_limit = mpa_ctrl->rx_max_ports;
+
+        pmadapter->mpa_tx.enabled = mpa_ctrl->tx_enable;
+        pmadapter->mpa_rx.enabled = mpa_ctrl->rx_enable;
+
+    } else {
+        mpa_ctrl->tx_enable = pmadapter->mpa_tx.enabled;
+        mpa_ctrl->rx_enable = pmadapter->mpa_rx.enabled;
+        mpa_ctrl->tx_buf_size = pmadapter->mpa_tx.buf_size;
+        mpa_ctrl->rx_buf_size = pmadapter->mpa_rx.buf_size;
+        mpa_ctrl->tx_max_ports = pmadapter->mpa_tx.pkt_aggr_limit;
+        mpa_ctrl->rx_max_ports = pmadapter->mpa_rx.pkt_aggr_limit;
+    }
+
+  exit:
+    LEAVE();
+    return ret;
+}
+#endif /* SDIO_MULTI_PORT_TX_AGGR || SDIO_MULTI_PORT_RX_AGGR */
+
+#ifdef MFG_CMD_SUPPORT
+/** 
+ *  @brief send mfg cmd
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_misc_ioctl_mfg_cmd(IN pmlan_adapter pmadapter,
+                        IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_misc_cfg *misc = MNULL;
+
+    ENTER();
+
+    misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_MFG_COMMAND,
+                           0,
+                           0,
+                           (t_void *) pioctl_req,
+                           (t_void *) & misc->param.mfgcmd);
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+#endif /* MFG_CMD_SUPPORT */
+
+/** 
+ *  @brief Set/Get LDO configuration
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_misc_ioctl_ldo(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_misc_cfg *misc = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET)
+        cmd_action = HostCmd_ACT_GEN_GET;
+    else
+        cmd_action = HostCmd_ACT_GEN_SET;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_802_11_LDO_CONFIG,
+                           cmd_action,
+                           0,
+                           (t_void *) pioctl_req,
+                           (t_void *) & misc->param.ldo_cfg);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get system clock configuration
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_misc_ioctl_sysclock(IN pmlan_adapter pmadapter,
+                         IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_misc_cfg *misc = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u16 cmd_action = 0;
+
+    ENTER();
+
+    misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+    if (pioctl_req->action == MLAN_ACT_GET)
+        cmd_action = HostCmd_ACT_GEN_GET;
+    else
+        cmd_action = HostCmd_ACT_GEN_SET;
+
+    /* Send request to firmware */
+    ret = wlan_prepare_cmd(pmpriv,
+                           HostCmd_CMD_ECL_SYSTEM_CLOCK_CONFIG,
+                           cmd_action,
+                           0,
+                           (t_void *) pioctl_req,
+                           (t_void *) & misc->param.sys_clock);
+
+    if (ret == MLAN_STATUS_SUCCESS)
+        ret = MLAN_STATUS_PENDING;
+
+    LEAVE();
+    return ret;
+}
+
+/** Flag for VSIE */
+#define VSIE_FLAG   1
+
+/** Max total length of vendor specific IEs for scan/assoc/ad-hoc */
+#define MAX_TOTAL_VSIE_LEN	512
+
+/**
+ *  @brief Get/Add/Remove the vendor specific IE
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_misc_ioctl_vendor_spec_ie(IN pmlan_adapter pmadapter,
+                               IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_private *pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_ds_misc_cfg *misc = MNULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u32 id, index, max_len;
+    t_u16 mask_bak;
+    t_u8 bit, len_bak;
+
+    ENTER();
+
+    misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+    id = misc->param.vsie.id;
+    switch (pioctl_req->action) {
+    case MLAN_ACT_GET:
+        misc->param.vsie.mask = (t_u32) pmpriv->vs_ie[id].mask;
+        memcpy(misc->param.vsie.ie, pmpriv->vs_ie[id].ie,
+               sizeof(misc->param.vsie.ie));
+        break;
+    case MLAN_ACT_SET:
+        mask_bak = pmpriv->vs_ie[id].mask;
+        pmpriv->vs_ie[id].mask = (t_u16) misc->param.vsie.mask;
+        if (!pmpriv->vs_ie[id].mask) {
+            memset(&pmpriv->vs_ie[id], 0, sizeof(vendor_spec_cfg_ie));
+        } else {
+            /* Check if the total length of VS IEs is over limitation */
+            len_bak = pmpriv->vs_ie[id].ie[1];
+            pmpriv->vs_ie[id].ie[1] = misc->param.vsie.ie[1];
+            for (bit = MLAN_VSIE_MASK_SCAN; bit <= MLAN_VSIE_MASK_ADHOC;
+                 bit <<= 1) {
+                max_len = 0;
+                for (index = 0; index < MLAN_MAX_VSIE_NUM; index++) {
+                    if (pmpriv->vs_ie[index].mask & bit)
+                        max_len += (pmpriv->vs_ie[index].ie[1] + 2);
+                }
+                if (max_len > MAX_TOTAL_VSIE_LEN) {
+                    PRINTM(MERROR,
+                           "Total length of VS IEs for %s (%d) is over limitation (%d)\n",
+                           (bit == MLAN_VSIE_MASK_SCAN) ? "scan" : (bit ==
+                                                                    MLAN_VSIE_MASK_ASSOC)
+                           ? "assoc" : "ad-hoc", max_len, MAX_TOTAL_VSIE_LEN);
+                    pmpriv->vs_ie[id].mask = mask_bak;
+                    pmpriv->vs_ie[id].ie[1] = len_bak;
+                    ret = MLAN_STATUS_FAILURE;
+                    break;
+                }
+            }
+
+            if (!ret) {
+                pmpriv->vs_ie[id].flag = VSIE_FLAG;
+                memcpy(pmpriv->vs_ie[id].ie, misc->param.vsie.ie,
+                       sizeof(misc->param.vsie.ie));
+                pmpriv->vs_ie[id].ie[0] = VS_IE;
+            }
+        }
+        break;
+    default:
+        break;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Miscellaneous configuration handler
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_misc_cfg_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_misc_cfg *misc = MNULL;
+
+    ENTER();
+
+    if (pioctl_req->buf_len < sizeof(mlan_ds_misc_cfg)) {
+        PRINTM(MWARN, "MLAN bss IOCTL length is too short.\n");
+        pioctl_req->data_read_written = 0;
+        pioctl_req->buf_len_needed = sizeof(mlan_ds_misc_cfg);
+        LEAVE();
+        return MLAN_STATUS_RESOURCE;
+    }
+    misc = (mlan_ds_misc_cfg *) pioctl_req->pbuf;
+    switch (misc->sub_command) {
+    case MLAN_OID_MISC_GEN_IE:
+        status = wlan_misc_ioctl_gen_ie(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_MISC_REGION:
+        status = wlan_misc_ioctl_region(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_MISC_WARM_RESET:
+        status = wlan_misc_ioctl_warm_reset(pmadapter, pioctl_req);
+        break;
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+    case MLAN_OID_MISC_SDIO_MPA_CTRL:
+        status = wlan_misc_ioctl_sdio_mpa_ctrl(pmadapter, pioctl_req);
+        break;
+#endif
+#ifdef MFG_CMD_SUPPORT
+    case MLAN_OID_MISC_MFG_CMD:
+        status = wlan_misc_ioctl_mfg_cmd(pmadapter, pioctl_req);
+        break;
+#endif
+    case MLAN_OID_MISC_HOST_CMD:
+        status = wlan_misc_ioctl_host_cmd(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_MISC_LDO:
+        status = wlan_misc_ioctl_ldo(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_MISC_SYS_CLOCK:
+        status = wlan_misc_ioctl_sysclock(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_MISC_WWS:
+        status = wlan_misc_ioctl_wws_cfg(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_MISC_VS_IE:
+        status = wlan_misc_ioctl_vendor_spec_ie(pmadapter, pioctl_req);
+        break;
+    case MLAN_OID_MISC_INIT_SHUTDOWN:
+        status = wlan_misc_ioctl_init_shutdown(pmadapter, pioctl_req);
+        break;
+
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set/Get scan configuration parameter
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *  @param action	    Set/Get
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_set_get_scan_cfg(IN pmlan_adapter pmadapter,
+                      IN pmlan_ioctl_req pioctl_req, IN t_u32 action)
+{
+    mlan_ds_scan *scan = MNULL;
+
+    ENTER();
+
+    scan = (mlan_ds_scan *) pioctl_req->pbuf;
+    if (action == MLAN_ACT_GET) {
+        scan->param.scan_cfg.scan_type = (t_u32) pmadapter->scan_type + 1;
+        scan->param.scan_cfg.scan_mode = pmadapter->scan_mode;
+        scan->param.scan_cfg.scan_probe = (t_u32) pmadapter->scan_probes;
+        scan->param.scan_cfg.scan_time.specific_scan_time =
+            (t_u32) pmadapter->specific_scan_time;
+        scan->param.scan_cfg.scan_time.active_scan_time =
+            (t_u32) pmadapter->active_scan_time;
+        scan->param.scan_cfg.scan_time.passive_scan_time =
+            (t_u32) pmadapter->passive_scan_time;
+    } else {
+        if (scan->param.scan_cfg.scan_type)
+            pmadapter->scan_type = (t_u8) scan->param.scan_cfg.scan_type - 1;
+        if (scan->param.scan_cfg.scan_mode)
+            pmadapter->scan_mode = scan->param.scan_cfg.scan_mode;
+        if (scan->param.scan_cfg.scan_probe)
+            pmadapter->scan_probes = (t_u16) scan->param.scan_cfg.scan_probe;
+        if (scan->param.scan_cfg.scan_time.specific_scan_time)
+            pmadapter->specific_scan_time =
+                (t_u16) scan->param.scan_cfg.scan_time.specific_scan_time;
+        if (scan->param.scan_cfg.scan_time.active_scan_time)
+            pmadapter->active_scan_time =
+                (t_u16) scan->param.scan_cfg.scan_time.active_scan_time;
+        if (scan->param.scan_cfg.scan_time.passive_scan_time)
+            pmadapter->passive_scan_time =
+                (t_u16) scan->param.scan_cfg.scan_time.passive_scan_time;
+    }
+    pioctl_req->data_read_written = sizeof(t_u32) + MLAN_SUB_COMMAND_SIZE;
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Set/Get scan
+ *
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static mlan_status
+wlan_scan_ioctl(IN pmlan_adapter pmadapter, IN pmlan_ioctl_req pioctl_req)
+{
+    pmlan_private pmpriv = pmadapter->priv[pioctl_req->bss_num];
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    mlan_ds_scan *pscan;
+
+    ENTER();
+
+    pscan = (mlan_ds_scan *) pioctl_req->pbuf;
+    if (pmadapter->scan_processing && pioctl_req->action == MLAN_ACT_SET) {
+        PRINTM(MCMND, "Scan already in process...\n");
+        LEAVE();
+        return status;
+    }
+    /* Set scan */
+    if (pioctl_req->action == MLAN_ACT_SET) {
+
+        switch (pscan->sub_command) {
+        case MLAN_OID_SCAN_NORMAL:
+            status = wlan_scan_networks(pmpriv, pioctl_req, MNULL);
+            break;
+        case MLAN_OID_SCAN_SPECIFIC_SSID:
+            status = wlan_scan_specific_ssid(pmpriv, pioctl_req,
+                                             &pscan->param.scan_req.scan_ssid);
+            break;
+        case MLAN_OID_SCAN_USER_CONFIG:
+            status = wlan_scan_networks(pmpriv, pioctl_req,
+                                        (wlan_user_scan_cfg *) pscan->param.
+                                        user_scan.scan_cfg_buf);
+            break;
+        case MLAN_OID_SCAN_CONFIG:
+            status = wlan_set_get_scan_cfg(pmadapter, pioctl_req, MLAN_ACT_SET);
+            break;
+        default:
+            status = MLAN_STATUS_FAILURE;
+            break;
+        }
+
+        if ((status == MLAN_STATUS_SUCCESS) &&
+            (pscan->sub_command != MLAN_OID_SCAN_CONFIG)) {
+            PRINTM(MINFO, "wlan_scan_ioctl: return MLAN_STATUS_PENDING\n");
+            status = MLAN_STATUS_PENDING;
+        }
+    }
+    /* Get scan */
+    else {
+        if (pscan->sub_command == MLAN_OID_SCAN_CONFIG) {
+            status = wlan_set_get_scan_cfg(pmadapter, pioctl_req, MLAN_ACT_GET);
+        } else if (pscan->sub_command == MLAN_OID_SCAN_SPECIFIC_SSID) {
+            pscan->param.scan_resp.num_in_scan_table =
+                pmadapter->num_in_scan_table;
+            pscan->param.scan_resp.pscan_table =
+                (t_u8 *) & pmpriv->curr_bss_params.bss_descriptor;
+            pioctl_req->data_read_written =
+                sizeof(mlan_scan_resp) + MLAN_SUB_COMMAND_SIZE;
+        } else {
+            pscan->param.scan_resp.pscan_table =
+                (t_u8 *) pmadapter->pscan_table;
+            pscan->param.scan_resp.num_in_scan_table =
+                pmadapter->num_in_scan_table;
+            pioctl_req->data_read_written =
+                sizeof(mlan_scan_resp) + MLAN_SUB_COMMAND_SIZE;
+        }
+    }
+
+    LEAVE();
+    return status;
+}
+
+/********************************************************
+                Global Functions
+********************************************************/
+/** 
+ *  @brief MLAN station ioctl handler
+ *
+ *  @param adapter 	A pointer to mlan_adapter structure
+ *  @param pioctl_req	A pointer to ioctl request buffer
+ *
+ *  @return		MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+mlan_status
+mlan_sta_ioctl(t_void * adapter, pmlan_ioctl_req pioctl_req)
+{
+    pmlan_adapter pmadapter = (pmlan_adapter) adapter;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+    switch (pioctl_req->req_id) {
+    case MLAN_IOCTL_SCAN:
+        status = wlan_scan_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_BSS:
+        status = wlan_bss_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_RADIO_CFG:
+        status = wlan_radio_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_SNMP_MIB:
+        status = wlan_snmp_mib_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_GET_INFO:
+        status = wlan_get_info_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_SEC_CFG:
+        status = wlan_sec_cfg_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_RATE:
+        status = wlan_rate_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_POWER_CFG:
+        status = wlan_power_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_PM_CFG:
+        status = wlan_pm_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_WMM_CFG:
+        status = wlan_wmm_cfg_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_WPS_CFG:
+        status = wlan_wps_cfg_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_11N_CFG:
+        status = wlan_11n_cfg_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_11D_CFG:
+        status = wlan_11d_cfg_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_REG_MEM:
+        status = wlan_reg_mem_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_BCA_CFG:
+        status = wlan_bca_cfg_ioctl(pmadapter, pioctl_req);
+        break;
+    case MLAN_IOCTL_MISC_CFG:
+        status = wlan_misc_cfg_ioctl(pmadapter, pioctl_req);
+        break;
+    default:
+        status = MLAN_STATUS_FAILURE;
+        break;
+    }
+    LEAVE();
+    return status;
+}
diff --git a/wlan_src/mlan/mlan_sta_rx.c b/wlan_src/mlan/mlan_sta_rx.c
new file mode 100755
index 0000000..3994998
--- /dev/null
+++ b/wlan_src/mlan/mlan_sta_rx.c
@@ -0,0 +1,250 @@
+/** @file mlan_sta_rx.c
+ *
+ *  @brief This file contains the handling of RX in MLAN
+ *  module.
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    10/27/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_11n_aggr.h"
+#include "mlan_11n_rxreorder.h"
+
+/********************************************************
+		Local Variables
+********************************************************/
+
+/** Ethernet II header */
+typedef struct
+{
+    /** Ethernet II header destination address */
+    t_u8 dest_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Ethernet II header source address */
+    t_u8 src_addr[MLAN_MAC_ADDR_LENGTH];
+    /** Ethernet II header length */
+    t_u16 ethertype;
+
+} EthII_Hdr_t;
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/********************************************************
+		Local Functions
+********************************************************/
+
+/********************************************************
+		Global functions
+********************************************************/
+/**
+ *  @brief This function processes received packet and forwards it
+ *  		to kernel/upper layer
+ *  
+ *  @param pmadapter A pointer to mlan_adapter
+ *  @param pmbuf     A pointer to mlan_buffer which includes the received packet
+ *
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_process_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private priv = pmadapter->priv[pmbuf->bss_num];
+    RxPacketHdr_t *prx_pkt;
+    RxPD *prx_pd;
+    int hdr_chop;
+    EthII_Hdr_t *peth_hdr;
+    t_u8 rfc1042_eth_hdr[MLAN_MAC_ADDR_LENGTH] =
+        { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+
+    ENTER();
+    prx_pd = (RxPD *) (pmbuf->pbuf + pmbuf->data_offset);
+
+    prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset);
+
+    DBG_HEXDUMP(MDAT_D, "Rx", pmbuf->pbuf + pmbuf->data_offset,
+                MIN(pmbuf->data_len, MAX_DATA_DUMP_LEN));
+
+/** Rx packet type debugging */
+#define RX_PKT_TYPE_DEBUG  0xEF
+/** Small debug type */
+#define DBG_TYPE_SMALL  2
+/** Size of debugging structure */
+#define SIZE_OF_DBG_STRUCT 4
+    if (prx_pd->rx_pkt_type == RX_PKT_TYPE_DEBUG) {
+        t_u8 dbgType;
+        dbgType = *(t_u8 *) & prx_pkt->eth803_hdr;
+        if (dbgType == DBG_TYPE_SMALL) {
+            PRINTM(MFW_D, "\n");
+            DBG_HEXDUMP(MFW_D, "FWDBG",
+                        (t_s8 *) ((t_u8 *) & prx_pkt->eth803_hdr +
+                                  SIZE_OF_DBG_STRUCT), prx_pd->rx_pkt_length);
+            PRINTM(MFW_D, "FWDBG::\n");
+        }
+        goto done;
+    }
+
+    PRINTM(MINFO, "RX Data: data_len - prx_pd->rx_pkt_offset = %d - %d = %d\n",
+           pmbuf->data_len, prx_pd->rx_pkt_offset,
+           pmbuf->data_len - prx_pd->rx_pkt_offset);
+
+    HEXDUMP("RX Data: Dest", prx_pkt->eth803_hdr.dest_addr,
+            sizeof(prx_pkt->eth803_hdr.dest_addr));
+    HEXDUMP("RX Data: Src", prx_pkt->eth803_hdr.src_addr,
+            sizeof(prx_pkt->eth803_hdr.src_addr));
+
+    if (!memcmp(&prx_pkt->rfc1042_hdr,
+                rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) {
+        /* 
+         *  Replace the 803 header and rfc1042 header (llc/snap) with an 
+         *    EthernetII header, keep the src/dst and snap_type (ethertype).
+         *  The firmware only passes up SNAP frames converting
+         *    all RX Data from 802.11 to 802.2/LLC/SNAP frames.
+         *  To create the Ethernet II, just move the src, dst address right
+         *    before the snap_type.
+         */
+        peth_hdr = (EthII_Hdr_t *)
+            ((t_u8 *) & prx_pkt->eth803_hdr
+             + sizeof(prx_pkt->eth803_hdr) + sizeof(prx_pkt->rfc1042_hdr)
+             - sizeof(prx_pkt->eth803_hdr.dest_addr)
+             - sizeof(prx_pkt->eth803_hdr.src_addr)
+             - sizeof(prx_pkt->rfc1042_hdr.snap_type));
+
+        memcpy(peth_hdr->src_addr, prx_pkt->eth803_hdr.src_addr,
+               sizeof(peth_hdr->src_addr));
+        memcpy(peth_hdr->dest_addr, prx_pkt->eth803_hdr.dest_addr,
+               sizeof(peth_hdr->dest_addr));
+
+        /* Chop off the RxPD + the excess memory from the 802.2/llc/snap header 
+           that was removed. */
+        hdr_chop = (t_u8 *) peth_hdr - (t_u8 *) prx_pd;
+    } else {
+        HEXDUMP("RX Data: LLC/SNAP",
+                (t_u8 *) & prx_pkt->rfc1042_hdr, sizeof(prx_pkt->rfc1042_hdr));
+
+        /* Chop off the RxPD */
+        hdr_chop = (t_u8 *) & prx_pkt->eth803_hdr - (t_u8 *) prx_pd;
+    }
+
+    /* Chop off the leading header bytes so the it points to the start of
+       either the reconstructed EthII frame or the 802.2/llc/snap frame */
+    pmbuf->data_len -= hdr_chop;
+    pmbuf->data_offset += hdr_chop;
+    pmbuf->pparent = MNULL;
+
+    priv->rxpd_rate = prx_pd->rx_rate;
+
+    priv->rxpd_htinfo = prx_pd->ht_info;
+
+    ret = pmadapter->callbacks.moal_recv_packet(pmadapter->pmoal_handle, pmbuf);
+    if (ret == MLAN_STATUS_FAILURE) {
+        PRINTM(MERROR, "RX Error: moal_recv_packet" " returns failure\n");
+    }
+
+    pmadapter->callbacks.moal_get_system_time(&pmbuf->out_ts_sec,
+                                              &pmbuf->out_ts_usec);
+    PRINTM(MDATA, "%lu.%lu : Data => kernel\n", pmbuf->out_ts_sec,
+           pmbuf->out_ts_usec);
+
+    if (ret != MLAN_STATUS_PENDING) {
+        pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle, pmbuf,
+                                                0, ret);
+    }
+
+  done:
+    LEAVE();
+
+    return ret;
+}
+
+/**
+ *   @brief This function processes the received buffer
+ *     
+ *   @param adapter A pointer to mlan_adapter
+ *   @param pmbuf     A pointer to the received buffer
+ *
+ *   @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+mlan_process_sta_rx_packet(IN t_void * adapter, IN pmlan_buffer pmbuf)
+{
+    pmlan_adapter pmadapter = (pmlan_adapter) adapter;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    RxPD *prx_pd;
+    RxPacketHdr_t *prx_pkt;
+    pmlan_private priv = pmadapter->priv[pmbuf->bss_num];
+    t_u8 ta[MLAN_MAC_ADDR_LENGTH];
+    ENTER();
+
+    prx_pd = (RxPD *) (pmbuf->pbuf + pmbuf->data_offset);
+    /* Endian conversion */
+    endian_convert_RxPD(prx_pd);
+    prx_pkt = (RxPacketHdr_t *) ((t_u8 *) prx_pd + prx_pd->rx_pkt_offset);
+
+    if ((prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length) >
+        (t_u16) pmbuf->data_len) {
+        PRINTM(MERROR,
+               "Wrong rx packet: len=%d,rx_pkt_offset=%d,"
+               " rx_pkt_length=%d\n", pmbuf->data_len, prx_pd->rx_pkt_offset,
+               prx_pd->rx_pkt_length);
+        ret = MLAN_STATUS_FAILURE;
+        pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle,
+                                                pmbuf, 0, ret);
+
+        goto done;
+    }
+    pmbuf->data_len = prx_pd->rx_pkt_offset + prx_pd->rx_pkt_length;
+    if (prx_pd->rx_pkt_type == PKT_TYPE_AMSDU) {
+        pmbuf->data_len = prx_pd->rx_pkt_length;
+        pmbuf->data_offset += prx_pd->rx_pkt_offset;
+        wlan_11n_deaggregate_pkt(priv, pmbuf);
+        goto done;
+    }
+    /* 
+     * If the packet is not an unicast packet then send the packet
+     * directly to os. Don't pass thru rx reordering
+     */
+    if (!IS_11N_ENABLED(priv) ||
+        memcmp(priv->curr_addr, prx_pkt->eth803_hdr.dest_addr,
+               MLAN_MAC_ADDR_LENGTH)) {
+        wlan_process_rx_packet(pmadapter, pmbuf);
+        goto done;
+    }
+
+    if (queuing_ra_based(priv)) {
+        memcpy(ta, prx_pkt->eth803_hdr.src_addr, MLAN_MAC_ADDR_LENGTH);
+    } else {
+        memcpy(ta,
+               priv->curr_bss_params.bss_descriptor.mac_address,
+               MLAN_MAC_ADDR_LENGTH);
+    }
+
+    /* Reorder and send to OS */
+    if ((ret = mlan_11n_rxreorder_pkt(priv, prx_pd->seq_num,
+                                      prx_pd->priority, ta,
+                                      (t_u8) prx_pd->rx_pkt_type,
+                                      (void *) pmbuf)) ||
+        (prx_pd->rx_pkt_type == PKT_TYPE_BAR)
+        ) {
+        if ((ret =
+             pmadapter->callbacks.moal_recv_complete(pmadapter->pmoal_handle,
+                                                     pmbuf, 0, ret)))
+            PRINTM(MERROR, "RX Error: moal_recv_complete returns" " failure\n");
+    }
+
+  done:
+
+    LEAVE();
+    return (ret);
+}
diff --git a/wlan_src/mlan/mlan_sta_tx.c b/wlan_src/mlan/mlan_sta_tx.c
new file mode 100755
index 0000000..f153230
--- /dev/null
+++ b/wlan_src/mlan/mlan_sta_tx.c
@@ -0,0 +1,245 @@
+/** @file mlan_sta_tx.c
+ *
+ *  @brief This file contains the handling of data packet
+ *  transmission in MLAN module.
+ * 
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    10/21/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+		Local Variables
+********************************************************/
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/********************************************************
+		Local Functions
+********************************************************/
+
+/********************************************************
+		Global functions
+********************************************************/
+/** 
+ *  @brief This function fill the pxpd for tx packet  
+ *  
+ *  @param priv	   A pointer to mlan_private structure
+ *  @param pmbuf   A pointer to the mlan_buffer for process
+ *
+ *  @return 	   headptr or MNULL
+ */
+t_void *
+mlan_process_sta_txpd(IN t_void * priv, IN pmlan_buffer pmbuf)
+{
+    mlan_private *pmpriv = (mlan_private *) priv;
+    pmlan_adapter pmadapter = pmpriv->adapter;
+    TxPD *plocal_tx_pd;
+    t_u8 *head_ptr = MNULL;
+
+    if (!pmbuf->data_len) {
+        PRINTM(MERROR, "Tx Error: bad packet length: %d\n", pmbuf->data_len);
+        pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
+        goto done;
+    }
+
+    if (pmbuf->data_offset < (sizeof(TxPD) + INTF_HEADER_LEN +
+                              HEADER_ALIGNMENT)) {
+        PRINTM(MERROR, "not enough space for TxPD: %d\n", pmbuf->data_len);
+        pmbuf->status_code = MLAN_ERROR_PKT_SIZE_INVALID;
+        goto done;
+    }
+
+    /* head_ptr should be aligned */
+    head_ptr =
+        pmbuf->pbuf + pmbuf->data_offset - sizeof(TxPD) - INTF_HEADER_LEN;
+    head_ptr = (t_u8 *) ((t_u32) head_ptr & ~((t_u32) (HEADER_ALIGNMENT - 1)));
+
+    plocal_tx_pd = (TxPD *) (head_ptr + INTF_HEADER_LEN);
+    memset(plocal_tx_pd, 0, sizeof(TxPD));
+    /* Set the BSS number to TxPD */
+    plocal_tx_pd->bss_num = pmpriv->bss_num;
+
+    plocal_tx_pd->tx_pkt_length = (t_u16) pmbuf->data_len;
+
+    plocal_tx_pd->priority = (t_u8) pmbuf->priority;
+    plocal_tx_pd->pkt_delay_2ms =
+        wlan_wmm_compute_driver_packet_delay(pmpriv, pmbuf);
+
+    if (plocal_tx_pd->priority < NELEMENTS(pmpriv->wmm.user_pri_pkt_tx_ctrl))
+        /* 
+         * Set the priority specific tx_control field, setting of 0 will
+         *   cause the default value to be used later in this function
+         */
+        plocal_tx_pd->tx_control
+            = pmpriv->wmm.user_pri_pkt_tx_ctrl[plocal_tx_pd->priority];
+
+    if (pmadapter->ps_state != PS_STATE_AWAKE) {
+        if (MTRUE == wlan_check_last_packet_indication(pmpriv)) {
+            pmadapter->tx_lock_flag = MTRUE;
+            plocal_tx_pd->flags = MRVDRV_TxPD_POWER_MGMT_LAST_PACKET;
+        }
+    }
+
+    /* Offset of actual data */
+    plocal_tx_pd->tx_pkt_offset =
+        (t_u16) ((t_u32) pmbuf->pbuf + pmbuf->data_offset -
+                 (t_u32) plocal_tx_pd);
+
+    if (!plocal_tx_pd->tx_control) {
+        /* TxCtrl set by user or default */
+        plocal_tx_pd->tx_control = pmpriv->pkt_tx_ctrl;
+    }
+
+    endian_convert_TxPD(plocal_tx_pd);
+
+    /* Adjust the data offset and length to include TxPD in pmbuf */
+    pmbuf->data_len += pmbuf->data_offset;
+    pmbuf->data_offset = head_ptr - pmbuf->pbuf;
+    pmbuf->data_len -= pmbuf->data_offset;
+
+  done:
+    return head_ptr;
+}
+
+/** 
+ *  @brief This function tells firmware to send a NULL data packet.
+ *  
+ *  @param priv     A pointer to mlan_private structure
+ *  @param flags    Trasmit Pkt Flags
+ *
+ *  @return 	    N/A
+ */
+mlan_status
+wlan_send_null_packet(pmlan_private priv, t_u8 flags)
+{
+    pmlan_adapter pmadapter = priv->adapter;
+    TxPD *ptx_pd;
+/* sizeof(TxPD) + Interface specific header */
+#define NULL_PACKET_HDR 64
+    t_u32 data_len = NULL_PACKET_HDR + HEADER_ALIGNMENT;
+    pmlan_buffer pmbuf = MNULL;
+    t_u8 *ptr;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u32 sec, usec;
+
+    ENTER();
+
+    if (pmadapter->surprise_removed == MTRUE) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    if (priv->media_connected == MFALSE) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    if (pmadapter->data_sent == MTRUE) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    pmbuf = wlan_alloc_mlan_buffer(&pmadapter->callbacks, data_len);
+    if (!pmbuf) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    memset(pmbuf->pbuf, 0, data_len);
+    pmbuf->bss_num = priv->bss_num;
+    pmbuf->buf_type = MLAN_BUF_TYPE_DATA;
+    ptr = (t_u8 *) ALIGN_ADDR(pmbuf->pbuf + pmbuf->data_offset,
+                              HEADER_ALIGNMENT);
+    pmbuf->data_offset = ptr - pmbuf->pbuf;
+    pmbuf->data_len = sizeof(TxPD) + INTF_HEADER_LEN;
+    ptx_pd = (TxPD *) (ptr + INTF_HEADER_LEN);
+    ptx_pd->tx_control = priv->pkt_tx_ctrl;
+    ptx_pd->flags = flags;
+    ptx_pd->priority = WMM_HIGHEST_PRIORITY;
+    ptx_pd->tx_pkt_offset = sizeof(TxPD);
+
+    endian_convert_TxPD(ptx_pd);
+
+    ret = wlan_sdio_host_to_card(pmadapter, MLAN_TYPE_DATA, pmbuf, MNULL);
+
+    switch (ret) {
+    case MLAN_STATUS_RESOURCE:
+        pmadapter->data_sent = MTRUE;
+        /* Fall through FAILURE handling */
+    case MLAN_STATUS_FAILURE:
+        wlan_free_mlan_buffer(&pmadapter->callbacks, pmbuf);
+        PRINTM(MERROR, "TX Error: wlan_send_null_packet failed! ret=%d\n", ret);
+        pmadapter->dbg.num_tx_host_to_card_failure++;
+        goto done;
+    case MLAN_STATUS_SUCCESS:
+        wlan_free_mlan_buffer(&pmadapter->callbacks, pmbuf);
+        PRINTM(MDATA, "TX: wlan_send_null_packet succeeded!\n");
+        pmadapter->tx_lock_flag = MTRUE;
+        break;
+    case MLAN_STATUS_PENDING:
+        break;
+    default:
+        break;
+    }
+
+    pmadapter->callbacks.moal_get_system_time(&sec, &usec);
+    PRINTM(MDATA, "%lu.%lu : Null data => FW\n", sec, usec);
+    DBG_HEXDUMP(MDAT_D, "Null data", ptr, sizeof(TxPD) + INTF_HEADER_LEN);
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function checks if we need to send last packet indication.
+ *  
+ *  @param priv    A pointer to mlan_private structure
+ *
+ *  @return 	   MTRUE or MFALSE
+ */
+t_u8
+wlan_check_last_packet_indication(pmlan_private priv)
+{
+    pmlan_adapter pmadapter = priv->adapter;
+    t_u8 ret = MFALSE;
+    t_u8 prop_ps = MTRUE;
+
+    ENTER();
+
+    if (!pmadapter->sleep_period.period) {
+        LEAVE();
+        return ret;
+    }
+    if (wlan_wmm_lists_empty(pmadapter)) {
+        if ((
+                /* TODO */
+                (priv->curr_bss_params.wmm_uapsd_enabled == MTRUE) &&
+                priv->wmm_qosinfo) || prop_ps)
+
+            ret = MTRUE;
+    }
+    if (ret && !pmadapter->cmd_sent && !pmadapter->curr_cmd
+        && !IS_COMMAND_PENDING(pmadapter)) {
+        pmadapter->delay_null_pkt = MFALSE;
+        ret = MTRUE;
+    } else {
+        ret = MFALSE;
+        pmadapter->delay_null_pkt = MTRUE;
+    }
+    LEAVE();
+    return ret;
+}
diff --git a/wlan_src/mlan/mlan_txrx.c b/wlan_src/mlan/mlan_txrx.c
new file mode 100755
index 0000000..d5b0026
--- /dev/null
+++ b/wlan_src/mlan/mlan_txrx.c
@@ -0,0 +1,243 @@
+/**
+ * @file mlan_txrx.c
+ *
+ *  @brief This file contains the handling of TX/RX in MLAN
+ *
+ *
+ *  Copyright (C) 2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ *   
+ */
+
+/*************************************************************
+Change Log:
+    05/11/2009: initial version
+************************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+                Local Variables
+********************************************************/
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+
+/********************************************************
+                Global Functions
+********************************************************/
+/**
+ *   @brief This function processes the received buffer
+ *     
+ *   @param pmadapter A pointer to mlan_adapter
+ *   @param pmbuf     A pointer to the received buffer
+ *
+ *   @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_handle_rx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_private priv = wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY);
+    t_u32 bss_num = 0;
+    RxPD *prx_pd;
+
+    ENTER();
+
+    prx_pd = (RxPD *) (pmbuf->pbuf + pmbuf->data_offset);
+    /* Get the BSS number from RxPD, get corresponding priv */
+    bss_num = prx_pd->bss_num & (MLAN_MAX_BSS_NUM - 1);
+    priv = pmadapter->priv[bss_num];
+    if (!priv) {
+        bss_num = 0;
+        priv = wlan_get_priv(pmadapter, MLAN_BSS_TYPE_ANY);
+    }
+    pmbuf->bss_num = bss_num;
+    ret = priv->ops.process_rx_packet(pmadapter, pmbuf);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function queues the packet received from
+ *  		kernel/upper layer and wake up the main thread to handle it.
+ *  
+ *  @param pmadapter	A pointer to mlan_adapter structure
+ *  @param pmbuf	A pointer to mlan_buffer includes TX packet
+ *
+ *  @return		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_tx_packet(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    HEXDUMP("TX Data", pmbuf->pbuf + pmbuf->data_offset,
+            MIN(pmbuf->data_len, 100));
+
+    wlan_wmm_add_buf_txqueue(pmadapter, pmbuf);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function checks the conditions and sends packet to device 
+ *  
+ *  @param priv	   A pointer to mlan_private structure
+ *  @param pmbuf   A pointer to the mlan_buffer for process
+ *  @param tx_param A pointer to mlan_tx_param structure
+ *
+ *  @return 	   mlan_status
+ */
+mlan_status
+wlan_process_tx(pmlan_private priv, pmlan_buffer pmbuf,
+                mlan_tx_param * tx_param)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_adapter pmadapter = priv->adapter;
+    t_u8 *head_ptr = MNULL;
+    t_u32 sec, usec;
+
+    ENTER();
+
+    head_ptr = (t_u8 *) priv->ops.process_txpd(priv, pmbuf);
+    if (!head_ptr) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    ret = wlan_sdio_host_to_card(pmadapter, MLAN_TYPE_DATA, pmbuf, tx_param);
+  done:
+    switch (ret) {
+    case MLAN_STATUS_RESOURCE:
+        PRINTM(MDATA, "MLAN_STATUS_RESOURCE is returned\n");
+        break;
+    case MLAN_STATUS_FAILURE:
+        pmadapter->data_sent = MFALSE;
+        PRINTM(MERROR, "Error: moal_write_data_async failed: 0x%X\n", ret);
+        pmadapter->dbg.num_tx_host_to_card_failure++;
+        wlan_write_data_complete(pmadapter, pmbuf, ret);
+        break;
+    case MLAN_STATUS_PENDING:
+        pmadapter->data_sent = MFALSE;
+        break;
+    case MLAN_STATUS_SUCCESS:
+        wlan_write_data_complete(pmadapter, pmbuf, ret);
+        break;
+    default:
+        break;
+    }
+
+    if ((ret == MLAN_STATUS_SUCCESS) || (ret == MLAN_STATUS_PENDING)) {
+        pmadapter->callbacks.moal_get_system_time(&sec, &usec);
+        PRINTM(MDATA, "%lu.%lu : Data => FW\n", sec, usec);
+
+        DBG_HEXDUMP(MDAT_D, "Tx", head_ptr + INTF_HEADER_LEN,
+                    MIN(pmbuf->data_len + sizeof(TxPD), MAX_DATA_DUMP_LEN));
+    }
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Packet send completion handling
+ *
+ *  @param pmadapter		A pointer to mlan_adapter structure
+ *  @param pmbuf		A pointer to mlan_buffer structure
+ *  @param status		Callback status
+ *
+ *  @return			MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_write_data_complete(IN pmlan_adapter pmadapter,
+                         IN pmlan_buffer pmbuf, IN mlan_status status)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    pmlan_callbacks pcb;
+
+    ENTER();
+
+    ASSERT(pmadapter && pmbuf);
+
+    pcb = &pmadapter->callbacks;
+    if (pmbuf->buf_type == MLAN_BUF_TYPE_DATA) {
+        PRINTM(MDATA, "wlan_write_data_complete: DATA\n");
+
+        if (!pmbuf->pdesc) {
+            /* pmbuf was allocated by MLAN */
+            wlan_free_mlan_buffer(&pmadapter->callbacks, pmbuf);
+        } else {
+            /* pmbuf was allocated by MOAL */
+            pcb->moal_send_packet_complete(pmadapter->pmoal_handle,
+                                           pmbuf, status);
+        }
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Packet receive completion callback handler
+ *
+ *  @param pmlan_adapter	A pointer to mlan_adapter structure
+ *  @param pmbuf		A pointer to mlan_buffer structure
+ *  @param status		Callback status
+ *
+ *  @return			MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_recv_packet_complete(IN t_void * pmlan_adapter,
+                          IN pmlan_buffer pmbuf, IN mlan_status status)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_adapter *pmadapter = (mlan_adapter *) pmlan_adapter;
+    pmlan_private pmp;
+    pmlan_callbacks pcb;
+    pmlan_buffer pmbuf_parent;
+
+    ENTER();
+    ASSERT(pmlan_adapter && pmbuf);
+
+    pcb = &pmadapter->callbacks;
+
+    ASSERT(pmbuf->bss_num < MLAN_MAX_BSS_NUM);
+
+    pmp = pmadapter->priv[pmbuf->bss_num];
+
+    if (pmbuf->pparent) {
+        pmbuf_parent = pmbuf->pparent;
+
+        pmadapter->callbacks.moal_spin_lock(pmp->rx_pkt_lock);
+        --pmbuf_parent->use_count;
+        if (!pmbuf_parent->use_count) {
+            pmadapter->callbacks.moal_spin_unlock(pmp->rx_pkt_lock);
+            pcb->moal_recv_complete(pmadapter->pmoal_handle,
+                                    pmbuf_parent, pmadapter->ioport, status);
+        } else {
+            pmadapter->callbacks.moal_spin_unlock(pmp->rx_pkt_lock);
+        }
+
+        pcb->moal_mfree((t_u8 *) pmbuf);
+    } else {
+        pcb->moal_recv_complete(pmadapter->pmoal_handle, pmbuf,
+                                pmadapter->ioport, status);
+    }
+
+    LEAVE();
+    return ret;
+}
diff --git a/wlan_src/mlan/mlan_util.h b/wlan_src/mlan/mlan_util.h
new file mode 100755
index 0000000..704093c
--- /dev/null
+++ b/wlan_src/mlan/mlan_util.h
@@ -0,0 +1,235 @@
+/** @file mlan_util.h
+ *
+ *  @brief This file contains wrappers for linked-list,
+ *  spinlock and timer defines.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/******************************************************
+Change log:
+    10/28/2008: initial version
+******************************************************/
+
+#ifndef _MLAN_UTIL_H_
+#define _MLAN_UTIL_H_
+
+/** Circular doubly linked list */
+typedef struct _mlan_linked_list
+{
+    /** Pointer to previous node */
+    struct _mlan_linked_list *pprev;
+    /** Pointer to next node */
+    struct _mlan_linked_list *pnext;
+} mlan_linked_list, *pmlan_linked_list;
+
+/** List head */
+typedef struct _mlan_list_head
+{
+    /** Pointer to previous node */
+    struct _mlan_linked_list *pprev;
+    /** Pointer to next node */
+    struct _mlan_linked_list *pnext;
+    /** Pointer to lock */
+    t_void *plock;
+} mlan_list_head, *pmlan_list_head;
+
+/** 
+ *  @brief This function initializes a list without locking
+ *  
+ *  @param phead		List head
+ *
+ *  @return			N/A
+ */
+static INLINE t_void
+util_init_list(pmlan_linked_list phead)
+{
+    /* Both next and prev point to self */
+    phead->pprev = phead->pnext = (pmlan_linked_list) phead;
+}
+
+/** 
+ *  @brief This function initializes a list
+ *  
+ *  @param phead		List head
+ *  @param lock_required	A flag for spinlock requirement
+ *  @param moal_init_lock	A pointer to init lock handler
+ *
+ *  @return			N/A
+ */
+static INLINE t_void
+util_init_list_head(pmlan_list_head phead,
+                    t_u8 lock_required,
+                    mlan_status(*moal_init_lock) (t_void ** pplock))
+{
+    /* Both next and prev point to self */
+    util_init_list((pmlan_linked_list) phead);
+    if (lock_required)
+        moal_init_lock(&phead->plock);
+    else
+        phead->plock = 0;
+}
+
+/** 
+ *  @brief This function frees a list
+ *  
+ *  @param phead		List head
+ *  @param moal_free_lock	A pointer to free lock handler
+ *
+ *  @return			N/A
+ */
+static INLINE t_void
+util_free_list_head(pmlan_list_head phead,
+                    mlan_status(*moal_free_lock) (t_void * plock))
+{
+    phead->pprev = phead->pnext = 0;
+    if (phead->plock)
+        moal_free_lock(phead->plock);
+}
+
+/** 
+ *  @brief This function peeks into a list
+ *  
+ *  @param phead		List head
+ *  @param moal_spin_lock	A pointer to spin lock handler
+ *  @param moal_spin_unlock	A pointer to spin unlock handler
+ *
+ *  @return			List node
+ */
+static INLINE pmlan_linked_list
+util_peek_list(pmlan_list_head phead,
+               mlan_status(*moal_spin_lock) (t_void * plock),
+               mlan_status(*moal_spin_unlock) (t_void * plock))
+{
+    pmlan_linked_list pnode = 0;
+
+    if (moal_spin_lock)
+        moal_spin_lock(phead->plock);
+    if (phead->pnext != (pmlan_linked_list) phead) {
+        pnode = phead->pnext;
+    }
+    if (moal_spin_unlock)
+        moal_spin_unlock(phead->plock);
+    return pnode;
+}
+
+/** 
+ *  @brief This function queues a node at the list tail
+ *  
+ *  @param phead		List head
+ *  @param pnode		List node to queue
+ *  @param moal_spin_lock	A pointer to spin lock handler
+ *  @param moal_spin_unlock	A pointer to spin unlock handler
+ *
+ *  @return			N/A
+ */
+static INLINE t_void
+util_enqueue_list_tail(pmlan_list_head phead,
+                       pmlan_linked_list pnode,
+                       mlan_status(*moal_spin_lock) (t_void * plock),
+                       mlan_status(*moal_spin_unlock) (t_void * plock))
+{
+    pmlan_linked_list pold_last;
+
+    if (moal_spin_lock)
+        moal_spin_lock(phead->plock);
+    pold_last = phead->pprev;
+    pnode->pprev = pold_last;
+    pnode->pnext = (pmlan_linked_list) phead;
+
+    phead->pprev = pold_last->pnext = pnode;
+    if (moal_spin_unlock)
+        moal_spin_unlock(phead->plock);
+}
+
+/** 
+ *  @brief This function adds a node at the list head
+ *  
+ *  @param phead		List head
+ *  @param pnode		List node to add
+ *  @param moal_spin_lock	A pointer to spin lock handler
+ *  @param moal_spin_unlock	A pointer to spin unlock handler
+ *
+ *  @return			N/A
+ */
+static INLINE t_void
+util_enqueue_list_head(pmlan_list_head phead,
+                       pmlan_linked_list pnode,
+                       mlan_status(*moal_spin_lock) (t_void * plock),
+                       mlan_status(*moal_spin_unlock) (t_void * plock))
+{
+    pmlan_linked_list pold_first;
+
+    if (moal_spin_lock)
+        moal_spin_lock(phead->plock);
+    pold_first = phead->pnext;
+    pnode->pprev = (pmlan_linked_list) phead;
+    pnode->pnext = pold_first;
+
+    phead->pnext = pold_first->pprev = pnode;
+    if (moal_spin_unlock)
+        moal_spin_unlock(phead->plock);
+}
+
+/** 
+ *  @brief This function removes a node from the list
+ *  
+ *  @param phead		List head
+ *  @param pnode		List node to remove
+ *  @param moal_spin_lock	A pointer to spin lock handler
+ *  @param moal_spin_unlock	A pointer to spin unlock handler
+ *
+ *  @return			N/A
+ */
+static INLINE t_void
+util_unlink_list(pmlan_list_head phead,
+                 pmlan_linked_list pnode,
+                 mlan_status(*moal_spin_lock) (t_void * plock),
+                 mlan_status(*moal_spin_unlock) (t_void * plock))
+{
+    pmlan_linked_list pmy_prev;
+    pmlan_linked_list pmy_next;
+
+    if (moal_spin_lock)
+        moal_spin_lock(phead->plock);
+    pmy_prev = pnode->pprev;
+    pmy_next = pnode->pnext;
+    pmy_next->pprev = pmy_prev;
+    pmy_prev->pnext = pmy_next;
+
+    pnode->pnext = pnode->pprev = 0;
+    if (moal_spin_unlock)
+        moal_spin_unlock(phead->plock);
+}
+
+/** 
+ *  @brief This function dequeues a node from the list
+ *  
+ *  @param phead		List head
+ *  @param moal_spin_lock	A pointer to spin lock handler
+ *  @param moal_spin_unlock	A pointer to spin unlock handler
+ *
+ *  @return			List node
+ */
+static INLINE pmlan_linked_list
+util_dequeue_list(pmlan_list_head phead,
+                  mlan_status(*moal_spin_lock) (t_void * plock),
+                  mlan_status(*moal_spin_unlock) (t_void * plock))
+{
+    pmlan_linked_list pnode;
+
+    if (moal_spin_lock)
+        moal_spin_lock(phead->plock);
+    pnode = phead->pnext;
+    if (pnode != (pmlan_linked_list) phead) {
+        util_unlink_list(phead, pnode, 0, 0);
+    } else {
+        pnode = 0;
+    }
+    if (moal_spin_unlock)
+        moal_spin_unlock(phead->plock);
+    return pnode;
+}
+
+#endif /* !_MLAN_UTIL_H_ */
diff --git a/wlan_src/mlan/mlan_wmm.c b/wlan_src/mlan/mlan_wmm.c
new file mode 100755
index 0000000..6b6dfe9
--- /dev/null
+++ b/wlan_src/mlan/mlan_wmm.c
@@ -0,0 +1,1888 @@
+/** @file mlan_wmm.c
+ *
+ *  @brief This file contains functions for WMM.
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/********************************************************
+Change log:
+    10/24/2008: initial version
+********************************************************/
+
+#include "mlan.h"
+#include "mlan_join.h"
+#include "mlan_util.h"
+#include "mlan_fw.h"
+#include "mlan_main.h"
+#include "mlan_wmm.h"
+#include "mlan_11n.h"
+#include "mlan_sdio.h"
+
+/********************************************************
+    Local Variables
+********************************************************/
+
+/** Maximum value FW can accept for driver delay in packet transmission */
+#define DRV_PKT_DELAY_TO_FW_MAX   512
+
+/*
+ * Upper and Lower threshold for packet queuing in the driver
+ 
+ *    - When the number of packets queued reaches the upper limit,
+ *      the driver will stop the net queue in the app/kernel space.
+ 
+ *    - When the number of packets drops beneath the lower limit after
+ *      having reached the upper limit, the driver will restart the net
+ *      queue.
+ */
+
+/** Lower threshold for packet queuing in the driver.
+  * When the number of packets drops beneath the lower limit after having
+  * reached the upper limit, the driver will restart the net queue.
+  */
+#define WMM_QUEUED_PACKET_LOWER_LIMIT   180
+
+/** Upper threshold for packet queuing in the driver.
+  * When the number of packets queued reaches the upper limit, the driver
+  * will stop the net queue in the app/kernel space.
+  */
+#define WMM_QUEUED_PACKET_UPPER_LIMIT   200
+
+/** Offset for TOS field in the IP header */
+#define IPTOS_OFFSET 5
+
+/** WMM information IE */
+static const t_u8 wmm_info_ie[] = { WMM_IE, 0x07,
+    0x00, 0x50, 0xf2, 0x02,
+    0x00, 0x01, 0x00
+};
+
+/**
+ * AC Priorities go from AC_BK to AC_VO.  The ACI enumeration for AC_BK (1)
+ *   is higher than the enumeration for AC_BE (0); hence the needed
+ *   mapping conversion for wmm AC to priority Queue Index
+ */
+static const t_u8 wmm_aci_to_qidx_map[] = { WMM_AC_BE,
+    WMM_AC_BK,
+    WMM_AC_VI,
+    WMM_AC_VO
+};
+
+/** 
+ * This table will be used to store the tid values based on ACs.
+ * It is initialized to default values per TID.
+ */
+t_u8 tos_to_tid[] = {
+    /* TID DSCP_P2 DSCP_P1 DSCP_P0 WMM_AC */
+    0x01,                       /* 0 1 0 AC_BK */
+    0x02,                       /* 0 0 0 AC_BK */
+    0x00,                       /* 0 0 1 AC_BE */
+    0x03,                       /* 0 1 1 AC_BE */
+    0x04,                       /* 1 0 0 AC_VI */
+    0x05,                       /* 1 0 1 AC_VI */
+    0x06,                       /* 1 1 0 AC_VO */
+    0x07                        /* 1 1 1 AC_VO */
+};
+
+/** 
+ * This table will provide the tid value for given ac. This table does not change
+ * and will be used to copy back the deafult values to tos_to_tid in case of 
+ * disconnect.
+ */
+t_u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} };
+
+/********************************************************
+    Local Functions
+********************************************************/
+#ifdef DEBUG_LEVEL2
+/**
+ *  @brief Debug print function to display the priority parameters for a WMM AC
+ *
+ *  @param pac_param	Pointer to the AC parameters to display
+ *
+ *  @return		N/A
+ */
+static void
+wlan_wmm_ac_debug_print(const IEEEtypes_WmmAcParameters_t * pac_param)
+{
+    const char *ac_str[] = { "BK", "BE", "VI", "VO" };
+
+    ENTER();
+
+    PRINTM(MINFO, "WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, "
+           "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n",
+           ac_str[wmm_aci_to_qidx_map[pac_param->aci_aifsn.aci]],
+           pac_param->aci_aifsn.aci, pac_param->aci_aifsn.acm,
+           pac_param->aci_aifsn.aifsn, pac_param->ecw.ecw_min,
+           pac_param->ecw.ecw_max, wlan_le16_to_cpu(pac_param->tx_op_limit));
+
+    LEAVE();
+}
+
+/** Print the WMM AC for debug purpose */
+#define PRINTM_AC(pac_param) wlan_wmm_ac_debug_print(pac_param)
+#else
+/** Print the WMM AC for debug purpose */
+#define PRINTM_AC(pac_param)
+#endif
+
+/**
+ *  @brief Allocate route address
+ *
+ *  @param pmadapter       Pointer to the mlan_adapter structure
+ *  @param ra              Pointer to the route address
+ *
+ *  @return         ra_list
+ */
+raListTbl *
+wlan_wmm_allocate_ralist_node(pmlan_adapter pmadapter, t_u8 * ra)
+{
+    raListTbl *ra_list;
+
+    ENTER();
+
+    if (pmadapter->callbacks.
+        moal_malloc(sizeof(raListTbl), (t_u8 **) & ra_list)) {
+        PRINTM(MERROR, "Fail to allocate ra_list\n");
+        goto done;
+    }
+    util_init_list((pmlan_linked_list) ra_list);
+    util_init_list_head(&ra_list->buf_head, MTRUE,
+                        pmadapter->callbacks.moal_init_lock);
+
+    memcpy(ra_list->ra, ra, MLAN_MAC_ADDR_LENGTH);
+
+    ra_list->total_pkts_size = 0;
+
+    PRINTM(MINFO, "RAList: Allocating buffers for TID %p\n", ra_list);
+  done:
+    LEAVE();
+    return ra_list;
+}
+
+/**
+ *  @brief  This function cleans Tx/Rx queues
+ *
+ *  @param priv		A pointer to mlan_private
+ *
+ *  @return		N/A
+ */
+t_void
+wlan_clean_txrx(pmlan_private priv)
+{
+    mlan_adapter *pmadapter = priv->adapter;
+
+    ENTER();
+
+    pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+
+    wlan_wmm_cleanup_queues(priv);
+    wlan_11n_cleanup_reorder_tbl(priv);
+    wlan_11n_deleteall_txbastream_tbl(priv);
+#ifdef SDIO_MULTI_PORT_TX_AGGR
+    MP_TX_AGGR_BUF_RESET(priv->adapter);
+#endif
+#ifdef SDIO_MULTI_PORT_RX_AGGR
+    MP_RX_AGGR_BUF_RESET(priv->adapter);
+#endif
+    wlan_wmm_delete_all_ralist(priv);
+    pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+
+    memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid));
+
+    LEAVE();
+}
+
+/**
+ *  @brief  Allocate and add a RA list for all TIDs with the given RA
+ *
+ *  @param priv  Pointer to the mlan_private driver data struct
+ *  @param ra	 Address of the receiver STA (AP in case of infra)
+ *
+ *  @return      N/A
+ */
+void
+wlan_ralist_add(mlan_private * priv, t_u8 * ra)
+{
+    int i;
+    raListTbl *ra_list;
+    pmlan_adapter pmadapter = priv->adapter;
+
+    ENTER();
+
+    for (i = 0; i < MAX_NUM_TID; ++i) {
+        ra_list = wlan_wmm_allocate_ralist_node(pmadapter, ra);
+        PRINTM(MINFO, "Creating RA List %p\n", ra_list);
+        if (!ra_list)
+            break;
+        if (queuing_ra_based(priv))
+            ra_list->is_11n_enabled = wlan_is_11n_enabled(priv, ra);
+        else
+            ra_list->is_11n_enabled = IS_11N_ENABLED(priv);
+        PRINTM(MDATA, "ralist %p: is_11n_enabled=%d\n", ra_list,
+               ra_list->is_11n_enabled);
+        util_enqueue_list_tail(&priv->wmm.tid_tbl_ptr[i].ra_list,
+                               (pmlan_linked_list) ra_list, MNULL, MNULL);
+
+        if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr)
+            priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list;
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Set the WMM queue priorities to their default values
+ *
+ *  @param priv     Pointer to the mlan_private driver data struct
+ *
+ *  @return         N/A
+ */
+void
+wlan_wmm_default_queue_priorities(pmlan_private priv)
+{
+    ENTER();
+
+    /* Default queue priorities: VO->VI->BE->BK */
+    priv->wmm.queue_priority[0] = WMM_AC_VO;
+    priv->wmm.queue_priority[1] = WMM_AC_VI;
+    priv->wmm.queue_priority[2] = WMM_AC_BE;
+    priv->wmm.queue_priority[3] = WMM_AC_BK;
+
+    LEAVE();
+}
+
+/**
+ * @brief Map ACs to TID 
+ *
+ * @param priv                  Pointer to the mlan_private driver data struct
+ * @param queue_priority        Queue_priority structure
+ *
+ * @return 	   N/A
+ */
+static void
+wlan_wmm_queue_priorities_tid(pmlan_private priv, t_u8 queue_priority[])
+{
+    int i;
+
+    ENTER();
+
+    for (i = 0; i < 4; ++i) {
+        tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1];
+        tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0];
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Initialize WMM priority queues
+ *
+ *  @param priv     Pointer to the mlan_private driver data struct
+ *  @param pwmm_ie  Pointer to the IEEEtypes_WmmParameter_t data struct
+ *
+ *  @return         N/A
+ */
+void
+wlan_wmm_setup_queue_priorities(pmlan_private priv,
+                                IEEEtypes_WmmParameter_t * pwmm_ie)
+{
+    t_u16 cw_min, avg_back_off, tmp[4];
+    t_u32 i, j, num_ac;
+    t_u8 ac_idx;
+
+    ENTER();
+
+    if (!pwmm_ie || priv->wmm_enabled == MFALSE) {
+        /* WMM is not enabled, just set the defaults and return */
+        wlan_wmm_default_queue_priorities(priv);
+        LEAVE();
+        return;
+    }
+
+    HEXDUMP("WMM: setup_queue_priorities: param IE",
+            (t_u8 *) pwmm_ie, sizeof(IEEEtypes_WmmParameter_t));
+
+    PRINTM(MINFO, "WMM Parameter IE: version=%d, "
+           "qos_info Parameter Set Count=%d, Reserved=%#x\n",
+           pwmm_ie->vend_hdr.version, pwmm_ie->qos_info.para_set_count,
+           pwmm_ie->reserved);
+
+    for (num_ac = 0; num_ac < NELEMENTS(pwmm_ie->ac_params); num_ac++) {
+        cw_min = (1 << pwmm_ie->ac_params[num_ac].ecw.ecw_min) - 1;
+        avg_back_off =
+            (cw_min >> 1) + pwmm_ie->ac_params[num_ac].aci_aifsn.aifsn;
+
+        ac_idx = wmm_aci_to_qidx_map[pwmm_ie->ac_params[num_ac].aci_aifsn.aci];
+        priv->wmm.queue_priority[ac_idx] = ac_idx;
+        tmp[ac_idx] = avg_back_off;
+
+        PRINTM(MINFO, "WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n",
+               (1 << pwmm_ie->ac_params[num_ac].ecw.ecw_max) - 1,
+               cw_min, avg_back_off);
+        PRINTM_AC(&pwmm_ie->ac_params[num_ac]);
+    }
+
+    HEXDUMP("WMM: avg_back_off", (t_u8 *) tmp, sizeof(tmp));
+    HEXDUMP("WMM: queue_priority", priv->wmm.queue_priority,
+            sizeof(priv->wmm.queue_priority));
+
+    /* Bubble sort */
+    for (i = 0; i < num_ac; i++) {
+        for (j = 1; j < num_ac - i; j++) {
+            if (tmp[j - 1] > tmp[j]) {
+                SWAP_U16(tmp[j - 1], tmp[j]);
+                SWAP_U8(priv->wmm.queue_priority[j - 1],
+                        priv->wmm.queue_priority[j]);
+            } else if (tmp[j - 1] == tmp[j]) {
+                if (priv->wmm.queue_priority[j - 1]
+                    < priv->wmm.queue_priority[j]) {
+                    SWAP_U8(priv->wmm.queue_priority[j - 1],
+                            priv->wmm.queue_priority[j]);
+                }
+            }
+        }
+    }
+
+    wlan_wmm_queue_priorities_tid(priv, priv->wmm.queue_priority);
+
+    HEXDUMP("WMM: avg_back_off, sort", (t_u8 *) tmp, sizeof(tmp));
+    HEXDUMP("WMM: queue_priority, sort", priv->wmm.queue_priority,
+            sizeof(priv->wmm.queue_priority));
+    LEAVE();
+}
+
+/**
+ *  @brief Evaluate whether or not an AC is to be downgraded
+ *
+ *  @param priv     Pointer to the mlan_private driver data struct
+ *  @param eval_ac  AC to evaluate for downgrading
+ *
+ *  @return WMM AC  The eval_ac traffic is to be sent on.
+ */
+static mlan_wmm_ac_e
+wlan_wmm_eval_downgrade_ac(pmlan_private priv, mlan_wmm_ac_e eval_ac)
+{
+    int down_ac;
+    mlan_wmm_ac_e ret_ac;
+    WmmAcStatus_t *pac_status;
+
+    ENTER();
+
+    pac_status = &priv->wmm.ac_status[eval_ac];
+
+    if (pac_status->disabled == MFALSE) {
+        LEAVE();
+        /* Okay to use this AC, its enabled */
+        return eval_ac;
+    }
+
+    /* Setup a default return value of the lowest priority */
+    ret_ac = WMM_AC_BK;
+
+    /* 
+     *  Find the highest AC that is enabled and does not require admission
+     *    control.  The spec disallows downgrading to an AC, which is enabled
+     *    due to a completed admission control.  Unadmitted traffic is not
+     *    to be sent on an AC with admitted traffic.
+     */
+    for (down_ac = WMM_AC_BK; down_ac < eval_ac; down_ac++) {
+        pac_status = &priv->wmm.ac_status[down_ac];
+
+        if ((pac_status->disabled == MFALSE)
+            && (pac_status->flow_required == MFALSE))
+            /* AC is enabled and does not require admission control */
+            ret_ac = (mlan_wmm_ac_e) down_ac;
+    }
+
+    LEAVE();
+    return ret_ac;
+}
+
+/**
+ *  @brief Downgrade WMM priority queue
+ *
+ *  @param priv     Pointer to the mlan_private driver data struct
+ *
+ *  @return         N/A
+ */
+void
+wlan_wmm_setup_ac_downgrade(pmlan_private priv)
+{
+    int ac_val;
+
+    ENTER();
+
+    PRINTM(MINFO, "WMM: AC Priorities: BK(0), BE(1), VI(2), VO(3)\n");
+
+    if (priv->wmm_enabled == MFALSE) {
+        /* WMM is not enabled, default priorities */
+        for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) {
+            for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) {
+                priv->wmm.ac_down_graded_vals[ac_val] = (mlan_wmm_ac_e) ac_val;
+            }
+        }
+    } else {
+        for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) {
+            priv->wmm.ac_down_graded_vals[ac_val]
+                = wlan_wmm_eval_downgrade_ac(priv, (mlan_wmm_ac_e) ac_val);
+            PRINTM(MINFO, "WMM: AC PRIO %d maps to %d\n",
+                   ac_val, priv->wmm.ac_down_graded_vals[ac_val]);
+        }
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Convert the IP TOS field to an WMM AC Queue assignment
+ *
+ *  @param pmadapter A pointer to mlan_adapter structure
+ *  @param tos       IP TOS field
+ *
+ *  @return     WMM AC Queue mapping of the IP TOS field
+ */
+static mlan_wmm_ac_e
+wlan_wmm_convert_tos_to_ac(pmlan_adapter pmadapter, t_u32 tos)
+{
+    /* Map of TOS UP values to WMM AC */
+    const mlan_wmm_ac_e tos_to_ac[] = { WMM_AC_BE,
+        WMM_AC_BK,
+        WMM_AC_BK,
+        WMM_AC_BE,
+        WMM_AC_VI,
+        WMM_AC_VI,
+        WMM_AC_VO,
+        WMM_AC_VO
+    };
+
+    ENTER();
+
+    if (tos >= NELEMENTS(tos_to_ac)) {
+        LEAVE();
+        return WMM_AC_BE;
+    }
+
+    LEAVE();
+    return tos_to_ac[tos];
+}
+
+/**
+ *  @brief  Evaluate a given TID and downgrade it to a lower TID if the
+ *          WMM Parameter IE received from the AP indicates that the AP
+ *          is disabled (due to call admission control (ACM bit). Mapping
+ * 			of TID to AC is taken care internally
+ *
+ *  @param priv		Pointer to the mlan_private data struct
+ *  @param tid  	tid to evaluate for downgrading
+ *
+ *  @return       Same tid as input if downgrading not required or
+ *                the tid the traffic for the given tid should be downgraded to
+ */
+static t_u8 INLINE
+wlan_wmm_downgrade_tid(pmlan_private priv, t_u32 tid)
+{
+    mlan_wmm_ac_e ac_down;
+    pmlan_adapter pmadapter = priv->adapter;
+
+    ENTER();
+
+    ac_down =
+        priv->wmm.
+        ac_down_graded_vals[wlan_wmm_convert_tos_to_ac(pmadapter, tid)];
+
+    LEAVE();
+    /* 
+     * Send the index to tid array, picking from the array will be
+     * taken care by dequeuing function
+     */
+    return ac_to_tid[ac_down][tid % 2];
+}
+
+/********************************************************
+    Global Functions
+********************************************************/
+/**
+ *  @brief Initialize the WMM state information and the WMM data path queues.
+ *
+ *  @param pmadapter  Pointer to the mlan_adapter data structure
+ *
+ *  @return         N/A
+ */
+t_void
+wlan_wmm_init(pmlan_adapter pmadapter)
+{
+    int i, j;
+    pmlan_private priv;
+
+    ENTER();
+
+    for (j = 0; j < MLAN_MAX_BSS_NUM; ++j) {
+        if ((priv = pmadapter->priv[j])) {
+            memset(&priv->wmm, 0x00, sizeof(priv->wmm));
+            for (i = 0; i < MAX_NUM_TID; ++i) {
+                priv->aggr_prio_tbl[i].amsdu = tos_to_tid[i];
+                priv->aggr_prio_tbl[i].ampdu_ap =
+                    priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid[i];
+
+                priv->wmm.tid_tbl_ptr[i].ra_list_curr = MNULL;
+                util_init_list_head(&priv->wmm.tid_tbl_ptr[i].ra_list, MTRUE,
+                                    priv->adapter->callbacks.moal_init_lock);
+            }
+
+            priv->aggr_prio_tbl[6].amsdu = priv->aggr_prio_tbl[6].ampdu_ap
+                = priv->aggr_prio_tbl[6].ampdu_user = BA_STREAM_NOT_ALLOWED;
+
+            priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap
+                = priv->aggr_prio_tbl[7].ampdu_user = BA_STREAM_NOT_ALLOWED;
+
+            priv->add_ba_param.timeout = MLAN_DEFAULT_BLOCK_ACK_TIMEOUT;
+            priv->add_ba_param.tx_win_size = MLAN_AMPDU_DEF_TXWINSIZE;
+            priv->add_ba_param.rx_win_size = MLAN_AMPDU_DEF_RXWINSIZE;
+            priv->adapter->callbacks.moal_init_lock(&priv->wmm.
+                                                    ra_list_spinlock);
+        }
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Setup the queue priorities and downgrade any queues as required
+ *         by the WMM info.  Setups default values if WMM is not active
+ *         for this association.
+ *
+ *  @param priv     Pointer to the mlan_private driver data struct
+ *
+ *  @return         N/A
+ */
+void
+wlan_wmm_setup_queues(pmlan_private priv)
+{
+    ENTER();
+    wlan_wmm_setup_queue_priorities(priv, MNULL);
+    wlan_wmm_setup_ac_downgrade(priv);
+    LEAVE();
+}
+
+/**
+ *  @brief  Send a command to firmware to retrieve the current WMM status
+ *
+ *  @param priv     Pointer to the mlan_private driver data struct
+ *
+ *  @return         MLAN_STATUS_SUCCESS; MLAN_STATUS_FAILURE
+ */
+int
+wlan_cmd_wmm_status_change(pmlan_private priv)
+{
+    return wlan_prepare_cmd(priv, HostCmd_CMD_WMM_GET_STATUS, 0, 0, 0, MNULL);
+}
+
+/**
+ *  @brief  Check if RA list is empty or not
+ *
+ *  @param pmadapter		A pointer to mlan_adapter structure
+ *  @param ra_list_hhead	RA list header
+ *
+ *  @return		MFALSE if not empty; MTRUE if empty
+ */
+static INLINE t_u8
+wlan_wmm_is_ra_list_empty(pmlan_adapter pmadapter,
+                          mlan_list_head * ra_list_hhead)
+{
+    raListTbl *ra_list;
+
+    ra_list = (raListTbl *) ra_list_hhead->pnext;
+
+    while (ra_list != (raListTbl *) ra_list_hhead) {
+        if (util_peek_list(&ra_list->buf_head,
+                           pmadapter->callbacks.moal_spin_lock,
+                           pmadapter->callbacks.moal_spin_unlock)) {
+            LEAVE();
+            return MFALSE;
+        }
+
+        ra_list = (raListTbl *) ra_list->pnext;
+    }
+
+    return MTRUE;
+}
+
+/**
+ *  @brief Check if wmm TX queue is empty
+ *
+ *  @param pmadapter  Pointer to the mlan_adapter driver data struct
+ *
+ *  @return         MFALSE if not empty; MTRUE if empty
+ */
+int
+wlan_wmm_lists_empty(pmlan_adapter pmadapter)
+{
+    int i, j;
+    pmlan_private priv;
+
+    ENTER();
+
+    for (j = 0; j < MLAN_MAX_BSS_NUM; ++j) {
+        if ((priv = pmadapter->priv[j])) {
+
+            for (i = 0; i < MAX_NUM_TID; i++) {
+                if (!wlan_wmm_is_ra_list_empty(pmadapter,
+                                               &priv->wmm.tid_tbl_ptr[i].
+                                               ra_list)) {
+                    LEAVE();
+                    return MFALSE;
+                }
+            }
+        }
+    }
+
+    LEAVE();
+    return MTRUE;
+}
+
+/**
+ *  @brief Delete packets in RA node
+ *
+ *  @param priv			Pointer to the mlan_private driver data struct
+ *  @param ra_list	    	Pointer to raListTbl
+ *
+ *  @return		N/A
+ */
+static INLINE void
+wlan_wmm_del_pkts_in_ralist_node(pmlan_private priv, raListTbl * ra_list)
+{
+    pmlan_buffer pmbuf;
+    pmlan_adapter pmadapter = priv->adapter;
+
+    ENTER();
+    while ((pmbuf = (pmlan_buffer) util_peek_list(&ra_list->buf_head,
+                                                  MNULL, MNULL))) {
+        util_unlink_list(&ra_list->buf_head, (pmlan_linked_list) pmbuf, MNULL,
+                         MNULL);
+
+        pmadapter->callbacks.moal_send_packet_complete(pmadapter->pmoal_handle,
+                                                       pmbuf,
+                                                       MLAN_STATUS_FAILURE);
+    }
+    util_free_list_head(&ra_list->buf_head,
+                        pmadapter->callbacks.moal_free_lock);
+
+    LEAVE();
+}
+
+/**
+ *  @brief Delete packets in RA list
+ *
+ *  @param priv			Pointer to the mlan_private driver data struct
+ *  @param ra_list_head	ra list header
+ *
+ *  @return		N/A
+ */
+static INLINE void
+wlan_wmm_del_pkts_in_ralist(pmlan_private priv, mlan_list_head * ra_list_head)
+{
+    raListTbl *ra_list;
+
+    ENTER();
+
+    ra_list = (raListTbl *) util_peek_list(ra_list_head, MNULL, MNULL);
+
+    while (ra_list && ra_list != (raListTbl *) ra_list_head) {
+        wlan_wmm_del_pkts_in_ralist_node(priv, ra_list);
+
+        ra_list = ra_list->pnext;
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Clean up the wmm queue
+ *
+ *  @param priv  Pointer to the mlan_private driver data struct
+ *
+ *  @return      N/A
+ */
+void
+wlan_wmm_cleanup_queues(pmlan_private priv)
+{
+    int i;
+
+    ENTER();
+
+    for (i = 0; i < MAX_NUM_TID; i++) {
+        wlan_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i].ra_list);
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Clean up initilized queues
+ *
+ *  @param priv  Pointer to the mlan_private driver data struct
+ *
+ *  @return      N/A
+ */
+void
+wlan_wmm_cleanup_node(pmlan_private priv)
+{
+    int i;
+
+    for (i = 0; i < MAX_NUM_TID; ++i)
+        util_free_list_head(&priv->wmm.tid_tbl_ptr[i].ra_list,
+                            priv->adapter->callbacks.moal_free_lock);
+    util_free_list_head(&priv->tx_ba_stream_tbl_ptr,
+                        priv->adapter->callbacks.moal_free_lock);
+    util_free_list_head(&priv->rx_reorder_tbl_ptr,
+                        priv->adapter->callbacks.moal_free_lock);
+}
+
+/**
+ *  @brief Delete all route address from RA list
+ *
+ *  @param priv     Pointer to the mlan_private driver data struct
+ *
+ *  @return         N/A
+ */
+void
+wlan_wmm_delete_all_ralist(pmlan_private priv)
+{
+    raListTbl *ra_list;
+    int i;
+    pmlan_adapter pmadapter = priv->adapter;
+
+    ENTER();
+
+    for (i = 0; i < MAX_NUM_TID; ++i) {
+        PRINTM(MINFO, "RAList: Freeing buffers for TID %d\n", i);
+        while ((ra_list =
+                (raListTbl *) util_peek_list(&priv->wmm.tid_tbl_ptr[i].ra_list,
+                                             MNULL, MNULL))) {
+            util_unlink_list(&priv->wmm.tid_tbl_ptr[i].ra_list,
+                             (pmlan_linked_list) ra_list, MNULL, MNULL);
+
+            pmadapter->callbacks.moal_mfree((t_u8 *) ra_list);
+        }
+
+        util_init_list((pmlan_linked_list)
+                       & priv->wmm.tid_tbl_ptr[i].ra_list);
+        priv->wmm.tid_tbl_ptr[i].ra_list_curr = MNULL;
+    }
+
+    LEAVE();
+}
+
+/**
+ *   @brief Get ralist node
+ *  
+ *   @param priv     Pointer to the mlan_private driver data struct
+ *   @param tid      TID
+ *   @param ra_addr  Pointer to the route address
+ * 
+ *   @return         ra_list or MNULL
+ */
+raListTbl *
+wlan_wmm_get_ralist_node(pmlan_private priv, t_u8 tid, t_u8 * ra_addr)
+{
+    raListTbl *ra_list;
+    ENTER();
+    ra_list = (raListTbl *) util_peek_list(&priv->wmm.tid_tbl_ptr[tid].ra_list,
+                                           MNULL, MNULL);
+    while (ra_list && (ra_list != (raListTbl *)
+                       & priv->wmm.tid_tbl_ptr[tid].ra_list)) {
+        if (!memcmp(ra_list->ra, ra_addr, MLAN_MAC_ADDR_LENGTH)) {
+            LEAVE();
+            return ra_list;
+        }
+        ra_list = ra_list->pnext;
+    }
+    LEAVE();
+    return MNULL;
+}
+
+/**
+ *   @brief Get queue RA pointer
+ *  
+ *   @param priv     Pointer to the mlan_private driver data struct
+ *   @param tid      TID
+ *   @param ra_addr  Pointer to the route address
+ * 
+ *   @return         ra_list
+ */
+raListTbl *
+wlan_wmm_get_queue_raptr(pmlan_private priv, t_u8 tid, t_u8 * ra_addr)
+{
+    raListTbl *ra_list;
+
+    ENTER();
+
+    ra_list = wlan_wmm_get_ralist_node(priv, tid, ra_addr);
+    if (ra_list) {
+        LEAVE();
+        return ra_list;
+    }
+    wlan_ralist_add(priv, ra_addr);
+
+    LEAVE();
+    return wlan_wmm_get_ralist_node(priv, tid, ra_addr);
+}
+
+int
+wlan_is_ralist_valid(mlan_private * priv, raListTbl * ra_list, int ptrindex)
+{
+    raListTbl *rlist;
+
+    rlist = (raListTbl *) util_peek_list(&priv->wmm.
+                                         tid_tbl_ptr[ptrindex].ra_list, MNULL,
+                                         MNULL);
+
+    while (rlist && (rlist != (raListTbl *)
+                     & priv->wmm.tid_tbl_ptr[ptrindex].ra_list)) {
+        if (rlist == ra_list)
+            return MTRUE;
+
+        rlist = rlist->pnext;
+    }
+
+    return MFALSE;
+}
+
+/**
+ *  @brief Add packet to WMM queue
+ *
+ *  @param pmadapter  Pointer to the mlan_adapter driver data struct
+ *  @param pmbuf      Pointer to the mlan_buffer data struct
+ *
+ *  @return         N/A
+ */
+t_void
+wlan_wmm_add_buf_txqueue(pmlan_adapter pmadapter, pmlan_buffer pmbuf)
+{
+    pmlan_private priv = pmadapter->priv[pmbuf->bss_num];
+    t_u32 tid;
+    raListTbl *ra_list;
+    t_u8 ra[MLAN_MAC_ADDR_LENGTH], tid_down;
+
+    ENTER();
+    pmbuf->buf_type = MLAN_BUF_TYPE_DATA;
+    pmbuf->flags = 0;
+
+    tid = pmbuf->priority;
+    tid_down = wlan_wmm_downgrade_tid(priv, tid);
+
+    pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+
+    /* In case of infra as we have already created the list during association
+       we just don't have to call get_queue_raptr, we will have only 1 raptr
+       for a tid in case of infra */
+    if (!queuing_ra_based(priv)) {
+        ra_list =
+            (raListTbl *) util_peek_list(&priv->wmm.tid_tbl_ptr[tid_down].
+                                         ra_list, MNULL, MNULL);
+    } else {
+        memcpy(ra, pmbuf->pbuf + pmbuf->data_offset, MLAN_MAC_ADDR_LENGTH);
+        ra_list = wlan_wmm_get_queue_raptr(priv, tid_down, ra);
+    }
+
+    if (!ra_list) {
+        pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+        LEAVE();
+        return;
+    }
+
+    PRINTM(MDAT_D, "Adding pkt to ra_list %p %p\n", ra_list, pmbuf);
+    util_enqueue_list_tail(&ra_list->buf_head,
+                           (pmlan_linked_list) pmbuf, MNULL, MNULL);
+
+    ra_list->total_pkts_size += pmbuf->data_len;
+//      PRINTM(MERROR, "[+%d->%u] ", pmbuf->data_len, ra_list->total_pkts_size);
+
+    /* Record the current time the packet was queued; used to determine the
+       amount of time the packet was queued in the driver before it was sent to 
+       the firmware.  The delay is then sent along with the packet to the
+       firmware for aggregate delay calculation for stats and MSDU lifetime
+       expiry. */
+    pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+    pmadapter->callbacks.moal_get_system_time(&pmbuf->in_ts_sec,
+                                              &pmbuf->in_ts_usec);
+
+    LEAVE();
+}
+
+/**
+ *  @brief Process the GET_WMM_STATUS command response from firmware
+ *
+ *  The GET_WMM_STATUS command returns multiple TLVs for:
+ *      - Each AC Queue status
+ *      - Current WMM Parameter IE
+ *
+ *  This function parses the TLVs and then calls further functions
+ *   to process any changes in the queue prioritize or state.
+ *
+ *  @param priv    Pointer to the mlan_private driver data struct
+ *  @param resp    Pointer to the command response buffer including TLVs
+ *                 TLVs for each queue and the WMM Parameter IE.
+ *
+ *  @return MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_wmm_get_status(pmlan_private priv, const HostCmd_DS_COMMAND * resp)
+{
+    t_u8 *pcurrent = (t_u8 *) & resp->params.get_wmm_status;
+    t_u32 resp_len = resp->size;
+    int valid = MTRUE;
+
+    MrvlIEtypes_Data_t *pTlvHdr;
+    MrvlIEtypes_WmmQueueStatus_t *pTlvWmmQStatus;
+    IEEEtypes_WmmParameter_t *pWmmParamIe = MNULL;
+    WmmAcStatus_t *pac_status;
+
+    ENTER();
+
+    PRINTM(MINFO, "WMM: WMM_GET_STATUS cmdresp received: %d\n", resp_len);
+    HEXDUMP("CMD_RESP: WMM_GET_STATUS", pcurrent, resp_len);
+
+    while ((resp_len >= sizeof(pTlvHdr->header)) && valid) {
+        pTlvHdr = (MrvlIEtypes_Data_t *) pcurrent;
+        pTlvHdr->header.len = wlan_le16_to_cpu(pTlvHdr->header.len);
+
+        switch (wlan_le16_to_cpu(pTlvHdr->header.type)) {
+        case TLV_TYPE_WMMQSTATUS:
+            pTlvWmmQStatus = (MrvlIEtypes_WmmQueueStatus_t *) pTlvHdr;
+            PRINTM(MINFO, "CMD_RESP: WMM_GET_STATUS: QSTATUS TLV: %d, %d, %d\n",
+                   pTlvWmmQStatus->queue_index,
+                   pTlvWmmQStatus->flow_required, pTlvWmmQStatus->disabled);
+
+            pac_status = &priv->wmm.ac_status[pTlvWmmQStatus->queue_index];
+            pac_status->disabled = pTlvWmmQStatus->disabled;
+            pac_status->flow_required = pTlvWmmQStatus->flow_required;
+            pac_status->flow_created = pTlvWmmQStatus->flow_created;
+            break;
+
+        case WMM_IE:
+            /* 
+             * Point the regular IEEE IE 2 bytes into the Marvell IE
+             *   and setup the IEEE IE type and length byte fields
+             */
+
+            HEXDUMP("WMM: WMM TLV:", (t_u8 *) pTlvHdr, pTlvHdr->header.len + 4);
+
+            pWmmParamIe = (IEEEtypes_WmmParameter_t *) (pcurrent + 2);
+            pWmmParamIe->vend_hdr.len = (t_u8) pTlvHdr->header.len;
+            pWmmParamIe->vend_hdr.element_id = WMM_IE;
+
+            PRINTM(MINFO, "CMD_RESP: WMM_GET_STATUS: WMM Parameter Set: %d\n",
+                   pWmmParamIe->qos_info.para_set_count);
+
+            memcpy((t_u8 *) & priv->curr_bss_params.bss_descriptor.wmm_ie,
+                   pWmmParamIe, pWmmParamIe->vend_hdr.len + 2);
+
+            break;
+
+        default:
+            valid = MFALSE;
+            break;
+        }
+
+        pcurrent += (pTlvHdr->header.len + sizeof(pTlvHdr->header));
+        resp_len -= (pTlvHdr->header.len + sizeof(pTlvHdr->header));
+    }
+
+    wlan_wmm_setup_queue_priorities(priv, pWmmParamIe);
+    wlan_wmm_setup_ac_downgrade(priv);
+
+    wlan_recv_event(priv, MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE, MNULL);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Call back from the command module to allow insertion of a WMM TLV
+ *
+ *  If the BSS we are associating to supports WMM, add the required WMM
+ *    Information IE to the association request command buffer in the form
+ *    of a Marvell extended IEEE IE.
+ *
+ *  @param priv        Pointer to the mlan_private driver data struct
+ *  @param ppAssocBuf  Output parameter: Pointer to the TLV output buffer,
+ *                     modified on return to point after the appended WMM TLV
+ *  @param pWmmIE      Pointer to the WMM IE for the BSS we are joining
+ *  @param pHTCap      Pointer to the HT IE for the BSS we are joining
+ *
+ *  @return Length of data appended to the association tlv buffer
+ */
+t_u32
+wlan_wmm_process_association_req(pmlan_private priv,
+                                 t_u8 ** ppAssocBuf,
+                                 IEEEtypes_WmmParameter_t * pWmmIE,
+                                 IEEEtypes_HTCap_t * pHTCap)
+{
+    MrvlIEtypes_WmmParamSet_t *pwmm_tlv;
+    t_u32 ret_len = 0;
+
+    ENTER();
+
+    /* Null checks */
+    if (!ppAssocBuf) {
+        LEAVE();
+        return 0;
+    }
+    if (!(*ppAssocBuf)) {
+        LEAVE();
+        return 0;
+    }
+
+    if (!pWmmIE) {
+        LEAVE();
+        return 0;
+    }
+
+    PRINTM(MINFO, "WMM: process assoc req: bss->wmmIe=0x%x\n",
+           pWmmIE->vend_hdr.element_id);
+
+    if ((priv->wmm_required
+         || (pHTCap && (pHTCap->ieee_hdr.element_id == HT_CAPABILITY)
+             && (priv->adapter->config_bands & BAND_GN
+                 || priv->adapter->config_bands & BAND_AN))
+        )
+        && pWmmIE->vend_hdr.element_id == WMM_IE) {
+        pwmm_tlv = (MrvlIEtypes_WmmParamSet_t *) * ppAssocBuf;
+        pwmm_tlv->header.type = (t_u16) wmm_info_ie[0];
+        pwmm_tlv->header.type = wlan_cpu_to_le16(pwmm_tlv->header.type);
+        pwmm_tlv->header.len = (t_u16) wmm_info_ie[1];
+        memcpy(pwmm_tlv->wmm_ie, &wmm_info_ie[2], pwmm_tlv->header.len);
+        if (pWmmIE->qos_info.qos_uapsd)
+            memcpy((t_u8 *) (pwmm_tlv->wmm_ie + pwmm_tlv->header.len
+                             - sizeof(priv->wmm_qosinfo)),
+                   &priv->wmm_qosinfo, sizeof(priv->wmm_qosinfo));
+
+        ret_len = sizeof(pwmm_tlv->header) + pwmm_tlv->header.len;
+        pwmm_tlv->header.len = wlan_cpu_to_le16(pwmm_tlv->header.len);
+
+        HEXDUMP("ASSOC_CMD: WMM IE", (t_u8 *) pwmm_tlv, ret_len);
+        *ppAssocBuf += ret_len;
+    }
+
+    LEAVE();
+    return ret_len;
+}
+
+/**
+ *   @brief Compute the time delay in the driver queues for a given packet.
+ *
+ *   When the packet is received at the OS/Driver interface, the current
+ *     time is set in the packet structure.  The difference between the present
+ *     time and that received time is computed in this function and limited
+ *     based on pre-compiled limits in the driver.
+ *
+ *   @param priv    Pointer to the mlan_private driver data struct
+ *   @param pmbuf   Pointer to the mlan_buffer which has been previously timestamped
+ *
+ *   @return        Time delay of the packet in 2ms units after having limit applied
+ */
+t_u8
+wlan_wmm_compute_driver_packet_delay(pmlan_private priv,
+                                     const pmlan_buffer pmbuf)
+{
+    t_u8 retVal = 0;
+    t_u32 out_ts_sec, out_ts_usec, queue_delay;
+
+    ENTER();
+
+    priv->adapter->callbacks.moal_get_system_time(&out_ts_sec, &out_ts_usec);
+
+    queue_delay = (out_ts_sec - pmbuf->in_ts_sec) * 1000;
+    queue_delay += (out_ts_usec - pmbuf->in_ts_usec) / 1000;
+
+    /* 
+     * Queue delay is passed as a uint8 in units of 2ms (ms shifted
+     *  by 1). Min value (other than 0) is therefore 2ms, max is 510ms.
+     *
+     * Pass max value if queue_delay is beyond the uint8 range
+     */
+    retVal = (t_u8) (MIN(queue_delay, priv->wmm.drv_pkt_delay_max) >> 1);
+
+    PRINTM(MDATA, "WMM: Pkt Delay: %d ms, %d ms sent to FW\n",
+           queue_delay, retVal);
+
+    LEAVE();
+    return retVal;
+}
+
+/**
+ *  @brief This function gets the highest priority list pointer
+ *  
+ *  @param pmadapter      A pointer to mlan_adapter
+ *  @param priv           A pointer to mlan_private
+ *  @param tid            A pointer to return tid
+ *
+ *  @return             raListTbl
+ */
+static raListTbl *
+wlan_wmm_get_highest_priolist_ptr(pmlan_adapter pmadapter,
+                                  pmlan_private * priv, int *tid)
+{
+    pmlan_private priv_tmp;
+    raListTbl *ptr, *head;
+    mlan_bssprio_node *bssprio_node, *bssprio_head;
+    tid_tbl_t *tid_ptr;
+    int i, j;
+
+    ENTER();
+
+    PRINTM(MDAT_D, "POP\n");
+    for (j = MLAN_MAX_BSS_NUM - 1; j >= 0; --j) {
+        if (!(util_peek_list(&pmadapter->bssprio_tbl[j].bssprio_head,
+                             pmadapter->callbacks.moal_spin_lock,
+                             pmadapter->callbacks.moal_spin_unlock)))
+            continue;
+
+        if (pmadapter->bssprio_tbl[j].bssprio_cur == (mlan_bssprio_node *)
+            & pmadapter->bssprio_tbl[j].bssprio_head)
+            bssprio_head = bssprio_node =
+                pmadapter->bssprio_tbl[j].bssprio_cur->pnext;
+        else
+            bssprio_head = bssprio_node = pmadapter->bssprio_tbl[j].bssprio_cur;
+
+        do {
+            priv_tmp = bssprio_node->priv;
+
+            for (i = HIGH_PRIO_TID; i >= LOW_PRIO_TID; --i) {
+
+                tid_ptr = &(priv_tmp)->wmm.tid_tbl_ptr[tos_to_tid[i]];
+                if (!util_peek_list(&tid_ptr->ra_list,
+                                    pmadapter->callbacks.moal_spin_lock,
+                                    pmadapter->callbacks.moal_spin_unlock))
+                    continue;
+
+                /* 
+                 * Always choose the next ra we transmitted 
+                 * last time, this way we pick the ra's in 
+                 * round robin fashion.
+                 */
+                if (tid_ptr->ra_list_curr->pnext !=
+                    (raListTbl *) & tid_ptr->ra_list)
+                    head = ptr = tid_ptr->ra_list_curr->pnext;
+                else
+                    head = ptr = tid_ptr->ra_list_curr;
+
+                do {
+                    if (util_peek_list(&ptr->buf_head,
+                                       pmadapter->callbacks.moal_spin_lock,
+                                       pmadapter->callbacks.moal_spin_unlock)) {
+                        *priv = priv_tmp;
+                        *tid = tos_to_tid[i];
+                        LEAVE();
+                        return ptr;
+                    }
+
+                    if ((ptr = ptr->pnext) == (raListTbl *) & tid_ptr->ra_list)
+                        ptr = ptr->pnext;
+                } while (ptr != head);
+            }
+
+            if ((bssprio_node = bssprio_node->pnext) == (mlan_bssprio_node *)
+                & pmadapter->bssprio_tbl[j].bssprio_head)
+                bssprio_node = bssprio_node->pnext;
+        } while (bssprio_node != bssprio_head);
+    }
+
+    LEAVE();
+    return MNULL;
+}
+
+/**
+ *  @brief This function gets the number of packets in the Tx queue
+ *  
+ *  @param priv         A pointer to mlan_private
+ *  @param ptr          A pointer to RA list table
+ *  @param maxBufSize   Maximum buffer size
+ *
+ *  @return             Packet count
+ */
+static int
+wlan_num_pkts_in_txq(mlan_private * priv, raListTbl * ptr, int maxBufSize)
+{
+    int count = 0, total_size = 0;
+    pmlan_buffer pmbuf;
+
+    ENTER();
+
+    for (pmbuf = (pmlan_buffer) ptr->buf_head.pnext;
+         pmbuf != (pmlan_buffer) (&ptr->buf_head); pmbuf = pmbuf->pnext) {
+
+        total_size += pmbuf->data_len;
+        if (total_size < maxBufSize)
+            ++count;
+        else
+            break;
+    }
+
+    LEAVE();
+    return count;
+}
+
+/**
+ *  @brief This function sends a single packet
+ *  
+ *  @param priv         A pointer to mlan_private
+ *  @param ptr          A pointer to RA list table
+ *
+ *  @return             N/A
+ */
+static void INLINE
+wlan_send_single_packet(pmlan_private priv, raListTbl * ptr, int ptrindex)
+{
+    pmlan_buffer pmbuf;
+    pmlan_buffer pmbuf_next;
+    mlan_tx_param tx_param;
+    pmlan_adapter pmadapter = priv->adapter;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    if ((pmbuf = (pmlan_buffer) util_dequeue_list(&ptr->buf_head,
+                                                  pmadapter->callbacks.
+                                                  moal_spin_lock,
+                                                  pmadapter->callbacks.
+                                                  moal_spin_unlock))) {
+        PRINTM(MDATA, "Dequeuing the packet %p %p\n", ptr, pmbuf);
+
+        ptr->total_pkts_size -= pmbuf->data_len;
+        pmbuf_next =
+            (pmlan_buffer) util_peek_list(&ptr->buf_head, MNULL, MNULL);
+        pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+
+        tx_param.next_pkt_len =
+            ((pmbuf_next) ? pmbuf_next->data_len + sizeof(TxPD) : 0);
+        status = wlan_process_tx(priv, pmbuf, &tx_param);
+
+        if (status == MLAN_STATUS_RESOURCE) {
+                        /** Queue the packet back at the head */
+            PRINTM(MDAT_D, "Queuing pkt back to raList %p %p\n", ptr, pmbuf);
+            pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+
+            if (!wlan_is_ralist_valid(priv, ptr, ptrindex)) {
+                pmadapter->callbacks.moal_spin_unlock(priv->wmm.
+                                                      ra_list_spinlock);
+                wlan_write_data_complete(pmadapter, pmbuf, MLAN_STATUS_FAILURE);
+                LEAVE();
+                return;
+            }
+            util_enqueue_list_head(&ptr->buf_head,
+                                   (pmlan_linked_list) pmbuf,
+                                   pmadapter->callbacks.moal_spin_lock,
+                                   pmadapter->callbacks.moal_spin_unlock);
+
+            ptr->total_pkts_size += pmbuf->data_len;
+            pmbuf->flags = MLAN_BUF_FLAG_REQUEUED_PKT;
+            pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+        } else {
+            pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+            if (!wlan_is_ralist_valid(priv, ptr, ptrindex)) {
+                priv->wmm.packets_out[ptrindex]++;
+                priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = ptr;
+            }
+            pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur =
+                pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur->pnext;
+            pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+        }
+    } else {
+        pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+        PRINTM(MDATA, "Nothing to send\n");
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief This function checks if this mlan_buffer is already processed.
+ *  
+ *  @param priv     A pointer to mlan_private
+ *  @param ptr      A pointer to RA list table
+ *
+ *  @return 	    MTRUE or MFALSE
+ */
+static int INLINE
+wlan_is_ptr_processed(mlan_private * priv, raListTbl * ptr)
+{
+    pmlan_buffer pmbuf;
+
+    if ((pmbuf = (pmlan_buffer) util_peek_list(&ptr->buf_head, MNULL, MNULL))
+        && (pmbuf->flags == MLAN_BUF_FLAG_REQUEUED_PKT))
+        return MTRUE;
+
+    return MFALSE;
+}
+
+/**
+ *  @brief This function sends a single packet
+ *  
+ *  @param priv         A pointer to mlan_private
+ *  @param ptr          A pointer to RA list table
+ *
+ *  @return             N/A
+ */
+static void INLINE
+wlan_send_processed_packet(pmlan_private priv, raListTbl * ptr, int ptrindex)
+{
+    pmlan_buffer pmbuf_next;
+    mlan_tx_param tx_param;
+    pmlan_buffer pmbuf;
+    pmlan_adapter pmadapter = priv->adapter;
+    mlan_status ret = MLAN_STATUS_FAILURE;
+
+    if ((pmbuf = (pmlan_buffer) util_dequeue_list(&ptr->buf_head,
+                                                  priv->adapter->callbacks.
+                                                  moal_spin_lock,
+                                                  priv->adapter->callbacks.
+                                                  moal_spin_unlock))) {
+        pmbuf_next =
+            (pmlan_buffer) util_peek_list(&ptr->buf_head, MNULL, MNULL);
+        pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+        tx_param.next_pkt_len =
+            ((pmbuf_next) ? pmbuf_next->data_len + sizeof(TxPD) : 0);
+        ret =
+            wlan_sdio_host_to_card(pmadapter, MLAN_TYPE_DATA, pmbuf, &tx_param);
+        switch (ret) {
+        case MLAN_STATUS_RESOURCE:
+            PRINTM(MDATA, "MLAN_STATUS_RESOURCE is returned\n");
+            pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+
+            if (!wlan_is_ralist_valid(priv, ptr, ptrindex)) {
+                pmadapter->callbacks.moal_spin_unlock(priv->wmm.
+                                                      ra_list_spinlock);
+                wlan_write_data_complete(pmadapter, pmbuf, MLAN_STATUS_FAILURE);
+                LEAVE();
+                return;
+            }
+            util_enqueue_list_head(&ptr->buf_head,
+                                   (pmlan_linked_list) pmbuf,
+                                   priv->adapter->callbacks.moal_spin_lock,
+                                   priv->adapter->callbacks.moal_spin_unlock);
+
+            pmbuf->flags = MLAN_BUF_FLAG_REQUEUED_PKT;
+            pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+            break;
+        case MLAN_STATUS_FAILURE:
+            pmadapter->data_sent = MFALSE;
+            PRINTM(MERROR, "Error: moal_write_data failed: 0x%X\n", ret);
+            pmadapter->dbg.num_tx_host_to_card_failure++;
+            wlan_write_data_complete(pmadapter, pmbuf, ret);
+            break;
+        case MLAN_STATUS_PENDING:
+            pmadapter->data_sent = MFALSE;
+        default:
+            break;
+        }
+        if (ret != MLAN_STATUS_RESOURCE) {
+            pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+            if (wlan_is_ralist_valid(priv, ptr, ptrindex)) {
+                priv->wmm.packets_out[ptrindex]++;
+                priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = ptr;
+            }
+            pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur =
+                pmadapter->bssprio_tbl[priv->bss_priority].bssprio_cur->pnext;
+            pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+        }
+    } else {
+        pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+    }
+}
+
+/**
+ *  @brief This function dequeues a packet
+ *  
+ *  @param pmadapter  A pointer to mlan_adapter
+ *
+ *  @return 	    MLAN_STATUS_SUCCESS;
+ */
+static int
+wlan_dequeue_tx_packet(pmlan_adapter pmadapter)
+{
+    raListTbl *ptr;
+    pmlan_private priv = MNULL;
+    int ptrindex = 0;
+    t_u8 ra[MLAN_MAC_ADDR_LENGTH];
+    int tid = 0;
+    t_u8 avail_ports = 0;
+    int i;
+
+    ENTER();
+
+    if (!(ptr = wlan_wmm_get_highest_priolist_ptr(pmadapter, &priv, &ptrindex))) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    tid = wlan_get_tid(priv->adapter, ptr);
+    for (i = 1; i < pmadapter->mp_end_port; i++) {
+        if ((pmadapter->mp_wr_bitmap >> i) & 1)
+            avail_ports++;
+    }
+
+    PRINTM(MDATA,
+           "mp_wr_bitmap=0x%04x avail_ports=%d tid=%d tx_eligibility[%d]=%d\n",
+           pmadapter->mp_wr_bitmap, avail_ports, tid, tid,
+           pmadapter->tx_eligibility[tid]);
+
+    if (avail_ports < pmadapter->tx_eligibility[tid]) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    pmadapter->callbacks.moal_spin_lock(priv->wmm.ra_list_spinlock);
+    if (!wlan_is_ralist_valid(priv, ptr, ptrindex)) {
+        pmadapter->callbacks.moal_spin_unlock(priv->wmm.ra_list_spinlock);
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Note:- Spinlock are unlocked in wlan_send_processed_packet ,
+       wlan_send_single_packet or wlan_11n_aggregate_pkt. The spinlock would
+       be required for some parts of both of function.  But, the the bulk of
+       these function will execute w/o spinlock.  Unlocking the spinlock
+       inside these function will help us avoid taking the spinlock again,
+       check to see if the ptr is still valid and then proceed. This is done
+       purely to increase execution time. */
+
+    /* Note:- Also, anybody adding code which does not get into
+       wlan_send_processed_packet, wlan_send_single_packet, or
+       wlan_11n_aggregate_pkt should make sure ra_list_spinlock is freed.
+       Otherwise there would be a lock up. */
+
+    if (wlan_is_ptr_processed(priv, ptr)) {
+        wlan_send_processed_packet(priv, ptr, ptrindex);
+        LEAVE();
+        return MLAN_STATUS_SUCCESS;
+    }
+
+    if (!ptr->is_11n_enabled || wlan_is_bastream_setup(priv, ptr)
+        || ((priv->sec_info.ewpa_enabled == MFALSE) &&
+            ((priv->sec_info.wpa_enabled
+              || priv->sec_info.wpa2_enabled) &&
+             priv->wpa_is_gtk_set == MFALSE))
+        ) {
+        wlan_send_single_packet(priv, ptr, ptrindex);
+    } else {
+        if (wlan_is_ampdu_allowed(priv, ptr)) {
+            if (wlan_is_bastream_avail(priv)) {
+                tid = wlan_get_tid(priv->adapter, ptr);
+                wlan_11n_create_txbastream_tbl(priv,
+                                               ptr->ra, tid,
+                                               BA_STREAM_SETUP_INPROGRESS);
+                wlan_send_addba(priv, tid, ptr->ra);
+            } else if (wlan_find_stream_to_delete(priv, ptr, &tid, ra)) {
+                wlan_11n_create_txbastream_tbl(priv,
+                                               ptr->ra,
+                                               wlan_get_tid(priv->adapter, ptr),
+                                               BA_STREAM_SETUP_INPROGRESS);
+
+                wlan_send_delba(priv, tid, ra, 1);
+            }
+        }
+/** Minimum number of AMSDU */
+#define MIN_NUM_AMSDU 2
+        if (wlan_is_amsdu_allowed(priv, ptr) &&
+            (wlan_num_pkts_in_txq(priv, ptr,
+                                  pmadapter->tx_buf_size) >= MIN_NUM_AMSDU)) {
+            wlan_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, ptrindex);
+        } else {
+            wlan_send_single_packet(priv, ptr, ptrindex);
+        }
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Transmit the highest priority packet awaiting in the WMM Queues
+ *
+ *  @param pmadapter Pointer to the mlan_adapter driver data struct
+ *
+ *  @return        N/A
+ */
+void
+wlan_wmm_process_tx(pmlan_adapter pmadapter)
+{
+    ENTER();
+
+    do {
+        /* Check if busy */
+        if (pmadapter->data_sent || pmadapter->tx_lock_flag)
+            break;
+
+        if (wlan_dequeue_tx_packet(pmadapter))
+            break;
+    } while (MTRUE);
+
+    LEAVE();
+    return;
+}
+
+/**
+ *  @brief This function prepares the command of ADDTS
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf    A pointer to data buffer
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_wmm_addts_req(IN pmlan_private pmpriv,
+                       OUT HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_ds_wmm_addts *paddts = (mlan_ds_wmm_addts *) pdata_buf;
+    HostCmd_DS_WMM_ADDTS_REQ *pcmd_addts = &cmd->params.add_ts;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_ADDTS_REQ);
+    cmd->size = wlan_cpu_to_le16(sizeof(pcmd_addts->dialog_token)
+                                 + sizeof(pcmd_addts->timeout_ms)
+                                 + sizeof(pcmd_addts->command_result)
+                                 + sizeof(pcmd_addts->ieee_status_code)
+                                 + paddts->tspec_data_len + S_DS_GEN);
+    cmd->result = 0;
+
+    pcmd_addts->timeout_ms = wlan_cpu_to_le32(paddts->timeout);
+    pcmd_addts->dialog_token = paddts->dialog_tok;
+    memcpy(pcmd_addts->tspec_data, paddts->tspec_data, paddts->tspec_data_len);
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles the command response of ADDTS
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_wmm_addts_req(IN pmlan_private pmpriv,
+                       const IN HostCmd_DS_COMMAND * resp,
+                       OUT mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_wmm_cfg *pwmm = MNULL;
+    mlan_ds_wmm_addts *paddts = MNULL;
+    const HostCmd_DS_WMM_ADDTS_REQ *presp_addts = &resp->params.add_ts;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        pwmm = (mlan_ds_wmm_cfg *) pioctl_buf->pbuf;
+        paddts = (mlan_ds_wmm_addts *) & pwmm->param.addts;
+        paddts->result = presp_addts->command_result;
+        paddts->dialog_tok = presp_addts->dialog_token;
+        paddts->status_code = (t_u32) presp_addts->ieee_status_code;
+
+        if (presp_addts->command_result == MLAN_CMD_RESULT_SUCCESS) {
+            /* The tspecData field is potentially variable in size due to extra 
+               IEs that may have been in the ADDTS response action frame.
+               Calculate the data length from the firmware command response. */
+            paddts->tspec_data_len = (t_u8) (resp->size
+                                             -
+                                             sizeof(presp_addts->command_result)
+                                             - sizeof(presp_addts->timeout_ms)
+                                             - sizeof(presp_addts->dialog_token)
+                                             -
+                                             sizeof(presp_addts->
+                                                    ieee_status_code)
+                                             - S_DS_GEN);
+
+            /* Copy the TSPEC data include any extra IEs after the TSPEC */
+            memcpy(paddts->tspec_data, presp_addts->tspec_data,
+                   paddts->tspec_data_len);
+        } else {
+            paddts->tspec_data_len = 0;
+        }
+        PRINTM(MINFO, "TSPEC: ADDTS ret = %d,%d sz=%d\n",
+               paddts->result, paddts->status_code, paddts->tspec_data_len);
+
+        HEXDUMP("TSPEC: ADDTS data",
+                paddts->tspec_data, paddts->tspec_data_len);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function prepares the command of DELTS
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf    A pointer to data buffer
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_wmm_delts_req(IN pmlan_private pmpriv,
+                       OUT HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_ds_wmm_delts *pdelts = (mlan_ds_wmm_delts *) pdata_buf;
+    HostCmd_DS_WMM_DELTS_REQ *pcmd_delts = &cmd->params.del_ts;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_DELTS_REQ);
+    cmd->size = wlan_cpu_to_le16(sizeof(pcmd_delts->dialog_token)
+                                 + sizeof(pcmd_delts->command_result)
+                                 + sizeof(pcmd_delts->ieee_reason_code)
+                                 + pdelts->tspec_data_len + S_DS_GEN);
+    cmd->result = 0;
+    pcmd_delts->ieee_reason_code = (t_u8) pdelts->status_code;
+    memcpy(pcmd_delts->tspec_data, pdelts->tspec_data, pdelts->tspec_data_len);
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles the command response of DELTS
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_wmm_delts_req(IN pmlan_private pmpriv,
+                       const IN HostCmd_DS_COMMAND * resp,
+                       OUT mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_wmm_cfg *pwmm = MNULL;
+    const HostCmd_DS_WMM_DELTS_REQ *presp_delts = &resp->params.del_ts;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        pwmm = (mlan_ds_wmm_cfg *) pioctl_buf->pbuf;
+        pwmm->param.delts.result = presp_delts->command_result;
+        PRINTM(MINFO, "TSPEC: DELTS result = %d\n",
+               presp_delts->command_result);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function prepares the command of WMM_QUEUE_CONFIG
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf    A pointer to data buffer
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_wmm_queue_config(IN pmlan_private pmpriv,
+                          OUT HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_ds_wmm_queue_config *pqcfg = (mlan_ds_wmm_queue_config *) pdata_buf;
+    HostCmd_DS_WMM_QUEUE_CONFIG *pcmd_qcfg = &cmd->params.queue_config;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_QUEUE_CONFIG);
+    cmd->size = wlan_cpu_to_le16(sizeof(pcmd_qcfg->action)
+                                 + sizeof(pcmd_qcfg->access_category)
+                                 + sizeof(pcmd_qcfg->msdu_lifetime_expiry)
+                                 + S_DS_GEN);
+    cmd->result = 0;
+
+    pcmd_qcfg->action = pqcfg->action;
+    pcmd_qcfg->access_category = pqcfg->access_category;
+    pcmd_qcfg->msdu_lifetime_expiry =
+        wlan_cpu_to_le16(pqcfg->msdu_lifetime_expiry);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles the command response of WMM_QUEUE_CONFIG
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_wmm_queue_config(IN pmlan_private pmpriv,
+                          const IN HostCmd_DS_COMMAND * resp,
+                          OUT mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_wmm_cfg *pwmm = MNULL;
+    const HostCmd_DS_WMM_QUEUE_CONFIG *presp_qcfg = &resp->params.queue_config;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        pwmm = (mlan_ds_wmm_cfg *) pioctl_buf->pbuf;
+        pwmm->param.q_cfg.action = presp_qcfg->action;
+        pwmm->param.q_cfg.access_category = presp_qcfg->access_category;
+        pwmm->param.q_cfg.msdu_lifetime_expiry =
+            wlan_le16_to_cpu(presp_qcfg->msdu_lifetime_expiry);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function prepares the command of WMM_QUEUE_STATS
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf    A pointer to data buffer
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_wmm_queue_stats(IN pmlan_private pmpriv,
+                         OUT HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_ds_wmm_queue_stats *pqstats = (mlan_ds_wmm_queue_stats *) pdata_buf;
+    HostCmd_DS_WMM_QUEUE_STATS *pcmd_qstats = &cmd->params.queue_stats;
+    t_u8 id;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_QUEUE_STATS);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_WMM_QUEUE_STATS)
+                                 + S_DS_GEN);
+    cmd->result = 0;
+
+    pcmd_qstats->action = pqstats->action;
+    pcmd_qstats->access_category = pqstats->access_category;
+    pcmd_qstats->pkt_count = wlan_cpu_to_le16(pqstats->pkt_count);
+    pcmd_qstats->pkt_loss = wlan_cpu_to_le16(pqstats->pkt_loss);
+    pcmd_qstats->avg_queue_delay = wlan_cpu_to_le32(pqstats->avg_queue_delay);
+    pcmd_qstats->avg_tx_delay = wlan_cpu_to_le32(pqstats->avg_tx_delay);
+    pcmd_qstats->used_time = wlan_cpu_to_le16(pqstats->used_time);
+    pcmd_qstats->policed_time = wlan_cpu_to_le16(pqstats->policed_time);
+    for (id = 0; id < MLAN_WMM_STATS_PKTS_HIST_BINS; id++) {
+        pcmd_qstats->delay_histogram[id] =
+            wlan_cpu_to_le16(pqstats->delay_histogram[id]);
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles the command response of WMM_QUEUE_STATS
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_wmm_queue_stats(IN pmlan_private pmpriv,
+                         const IN HostCmd_DS_COMMAND * resp,
+                         OUT mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_wmm_cfg *pwmm = MNULL;
+    mlan_ds_wmm_queue_stats *pqstats = MNULL;
+    const HostCmd_DS_WMM_QUEUE_STATS *presp_qstats = &resp->params.queue_stats;
+    t_u8 id;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        pwmm = (mlan_ds_wmm_cfg *) pioctl_buf->pbuf;
+        pqstats = (mlan_ds_wmm_queue_stats *) & pwmm->param.q_stats;
+
+        pqstats->action = presp_qstats->action;
+        pqstats->access_category = presp_qstats->access_category;
+        pqstats->pkt_count = wlan_le16_to_cpu(presp_qstats->pkt_count);
+        pqstats->pkt_loss = wlan_le16_to_cpu(presp_qstats->pkt_loss);
+        pqstats->avg_queue_delay =
+            wlan_le32_to_cpu(presp_qstats->avg_queue_delay);
+        pqstats->avg_tx_delay = wlan_le32_to_cpu(presp_qstats->avg_tx_delay);
+        pqstats->used_time = wlan_le16_to_cpu(presp_qstats->used_time);
+        pqstats->policed_time = wlan_le16_to_cpu(presp_qstats->policed_time);
+        for (id = 0; id < MLAN_WMM_STATS_PKTS_HIST_BINS; id++) {
+            pqstats->delay_histogram[id] =
+                wlan_le16_to_cpu(presp_qstats->delay_histogram[id]);
+        }
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function prepares the command of WMM_TS_STATUS
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param cmd          A pointer to HostCmd_DS_COMMAND structure
+ *  @param pdata_buf    A pointer to data buffer
+ *  @return             MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+wlan_cmd_wmm_ts_status(IN pmlan_private pmpriv,
+                       OUT HostCmd_DS_COMMAND * cmd, IN t_void * pdata_buf)
+{
+    mlan_ds_wmm_ts_status *pts_status = (mlan_ds_wmm_ts_status *) pdata_buf;
+    HostCmd_DS_WMM_TS_STATUS *pcmd_ts_status = &cmd->params.ts_status;
+
+    ENTER();
+
+    cmd->command = wlan_cpu_to_le16(HostCmd_CMD_WMM_TS_STATUS);
+    cmd->size = wlan_cpu_to_le16(sizeof(HostCmd_DS_WMM_TS_STATUS)
+                                 + S_DS_GEN);
+    cmd->result = 0;
+
+    memcpy((t_void *) pcmd_ts_status, (t_void *) pts_status,
+           sizeof(HostCmd_DS_WMM_TS_STATUS));
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief This function handles the command response of WMM_TS_STATUS
+ *
+ *  @param pmpriv       A pointer to mlan_private structure
+ *  @param resp         A pointer to HostCmd_DS_COMMAND
+ *  @param pioctl_buf   A pointer to mlan_ioctl_req structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS
+ */
+mlan_status
+wlan_ret_wmm_ts_status(IN pmlan_private pmpriv,
+                       IN HostCmd_DS_COMMAND * resp,
+                       OUT mlan_ioctl_req * pioctl_buf)
+{
+    mlan_ds_wmm_cfg *pwmm = MNULL;
+    HostCmd_DS_WMM_TS_STATUS *presp_ts_status = &resp->params.ts_status;
+
+    ENTER();
+
+    if (pioctl_buf) {
+        pwmm = (mlan_ds_wmm_cfg *) pioctl_buf->pbuf;
+        presp_ts_status->medium_time =
+            wlan_le16_to_cpu(presp_ts_status->medium_time);
+        memcpy((t_void *) & pwmm->param.ts_status, (t_void *) presp_ts_status,
+               sizeof(mlan_ds_wmm_ts_status));
+    }
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
diff --git a/wlan_src/mlan/mlan_wmm.h b/wlan_src/mlan/mlan_wmm.h
new file mode 100755
index 0000000..055d7e0
--- /dev/null
+++ b/wlan_src/mlan/mlan_wmm.h
@@ -0,0 +1,161 @@
+/** @file mlan_wmm.h
+ *
+ *  @brief This file contains related macros, enum, and struct
+ *  of wmm functionalities
+ *
+ *  Copyright (C) 2008-2009, Marvell International Ltd. 
+ *  All Rights Reserved
+ */
+
+/****************************************************
+Change log:
+    10/24/2008: initial version
+****************************************************/
+
+#ifndef _MLAN_WMM_H_
+#define _MLAN_WMM_H_
+
+/**
+ *  @brief This function gets the TID
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param ptr          A pointer to RA list table
+ *
+ *  @return 	    TID
+ */
+static INLINE int
+wlan_get_tid(pmlan_adapter pmadapter, raListTbl * ptr)
+{
+    pmlan_buffer mbuf;
+
+    ENTER();
+
+    mbuf = (pmlan_buffer) util_peek_list(&ptr->buf_head,
+                                         pmadapter->callbacks.moal_spin_lock,
+                                         pmadapter->callbacks.moal_spin_unlock);
+    LEAVE();
+    return mbuf->priority;
+}
+
+/**
+ *  @brief This function gets the length of a list
+ *  
+ *  @param pmadapter    A pointer to mlan_adapter structure
+ *  @param head         A pointer to mlan_list_head
+ *
+ *  @return 	    Length of list
+ */
+static INLINE int
+wlan_wmm_list_len(pmlan_adapter pmadapter, pmlan_list_head head)
+{
+    pmlan_linked_list pos;
+    int count = 0;
+
+    ENTER();
+
+    pos = head->pnext;
+
+    while (pos != (pmlan_linked_list) head) {
+        ++count;
+        pos = pos->pnext;
+    }
+
+    LEAVE();
+    return count;
+}
+
+/** Allocate RA list node */
+raListTbl *wlan_wmm_allocate_ralist_node(pmlan_adapter pmadapter, t_u8 * ra);
+/** Add buffer to WMM Tx queue */
+void wlan_wmm_add_buf_txqueue(pmlan_adapter pmadapter, pmlan_buffer pmbuf);
+/** Delete all RA lists */
+void wlan_wmm_delete_all_ralist(pmlan_private priv);
+/** Add to RA list */
+void wlan_ralist_add(mlan_private * priv, t_u8 * ra);
+
+/** Clean up WMM node */
+void wlan_wmm_cleanup_node(pmlan_private priv);
+/** WMM status change command handler */
+int wlan_cmd_wmm_status_change(pmlan_private priv);
+/** Check if WMM lists are empty */
+int wlan_wmm_lists_empty(pmlan_adapter pmadapter);
+/** Clean up WMM queues */
+t_void wlan_wmm_cleanup_queues(pmlan_private priv);
+/** Process WMM transmission */
+t_void wlan_wmm_process_tx(pmlan_adapter pmadapter);
+/** Test to see if the ralist ptr is valid */
+int wlan_is_ralist_valid(mlan_private * priv, raListTbl * ra_list, int tid);
+
+/** Compute driver packet delay */
+t_u8 wlan_wmm_compute_driver_packet_delay(pmlan_private priv,
+                                          const pmlan_buffer pmbuf);
+/** Initialize WMM */
+t_void wlan_wmm_init(pmlan_adapter pmadapter);
+/** Setup WMM queues */
+extern void wlan_wmm_setup_queues(pmlan_private priv);
+/* Setup default queues */
+void wlan_wmm_default_queue_priorities(pmlan_private priv);
+
+/** Process WMM association request */
+extern t_u32 wlan_wmm_process_association_req(pmlan_private priv,
+                                              t_u8 ** ppAssocBuf,
+                                              IEEEtypes_WmmParameter_t * pWmmIE,
+                                              IEEEtypes_HTCap_t * pHTCap);
+
+/** setup wmm queue priorities */
+void wlan_wmm_setup_queue_priorities(pmlan_private priv,
+                                     IEEEtypes_WmmParameter_t * wmm_ie);
+/** Downgrade WMM priority queue */
+void wlan_wmm_setup_ac_downgrade(pmlan_private priv);
+/* 
+ *  Functions used in the cmd handling routine
+ */
+/** WMM ADDTS request command handler */
+extern mlan_status wlan_cmd_wmm_addts_req(IN pmlan_private pmpriv,
+                                          OUT HostCmd_DS_COMMAND * cmd,
+                                          IN t_void * pdata_buf);
+/** WMM DELTS request command handler */
+extern mlan_status wlan_cmd_wmm_delts_req(IN pmlan_private pmpriv,
+                                          OUT HostCmd_DS_COMMAND * cmd,
+                                          IN t_void * pdata_buf);
+/** WMM QUEUE_CONFIG command handler */
+extern mlan_status wlan_cmd_wmm_queue_config(IN pmlan_private pmpriv,
+                                             OUT HostCmd_DS_COMMAND * cmd,
+                                             IN t_void * pdata_buf);
+/** WMM QUEUE_STATS command handler */
+extern mlan_status wlan_cmd_wmm_queue_stats(IN pmlan_private pmpriv,
+                                            OUT HostCmd_DS_COMMAND * cmd,
+                                            IN t_void * pdata_buf);
+/** WMM TS_STATUS command handler */
+extern mlan_status wlan_cmd_wmm_ts_status(IN pmlan_private pmpriv,
+                                          OUT HostCmd_DS_COMMAND * cmd,
+                                          IN t_void * pdata_buf);
+
+/* 
+ *  Functions used in the cmdresp handling routine
+ */
+/** WMM get status command response handler */
+extern mlan_status wlan_ret_wmm_get_status(pmlan_private priv,
+                                           const HostCmd_DS_COMMAND * resp);
+/** WMM ADDTS request command response handler */
+extern mlan_status wlan_ret_wmm_addts_req(IN pmlan_private pmpriv,
+                                          const IN HostCmd_DS_COMMAND * resp,
+                                          OUT mlan_ioctl_req * pioctl_buf);
+/** WMM DELTS request command response handler */
+extern mlan_status wlan_ret_wmm_delts_req(IN pmlan_private pmpriv,
+                                          const IN HostCmd_DS_COMMAND * resp,
+                                          OUT mlan_ioctl_req * pioctl_buf);
+/** WMM QUEUE_CONFIG command response handler */
+extern mlan_status wlan_ret_wmm_queue_config(IN pmlan_private pmpriv,
+                                             const IN HostCmd_DS_COMMAND * resp,
+                                             OUT mlan_ioctl_req * pioctl_buf);
+/** WMM QUEUE_STATS command response handler */
+extern mlan_status wlan_ret_wmm_queue_stats(IN pmlan_private pmpriv,
+                                            const IN HostCmd_DS_COMMAND * resp,
+                                            OUT mlan_ioctl_req * pioctl_buf);
+/** WMM TS_STATUS command response handler */
+extern mlan_status wlan_ret_wmm_ts_status(IN pmlan_private pmpriv,
+                                          IN HostCmd_DS_COMMAND * resp,
+                                          OUT mlan_ioctl_req * pioctl_buf);
+
+#endif /* !_MLAN_WMM_H_ */
diff --git a/wlan_src/mlinux/moal_debug.c b/wlan_src/mlinux/moal_debug.c
new file mode 100755
index 0000000..41d2849
--- /dev/null
+++ b/wlan_src/mlinux/moal_debug.c
@@ -0,0 +1,393 @@
+/** @file moal_debug.c
+  *
+  * @brief This file contains functions for debug proc file.
+  *
+  * Copyright (C) 2008-2009, Marvell International Ltd.
+  *
+  * This software file (the "File") is distributed by Marvell International
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+  * (the "License").  You may use, redistribute and/or modify this File in
+  * accordance with the terms and conditions of the License, a copy of which
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+  * this warranty disclaimer.
+  *
+  */
+
+/********************************************************
+Change log:
+    11/03/2008: initial version
+********************************************************/
+
+#include	"moal_main.h"
+
+/********************************************************
+		Local Variables
+********************************************************/
+#ifdef CONFIG_PROC_FS
+/** MLAN debug info */
+static mlan_debug_info info;
+
+/** Get info item size */
+#define item_size(n) (sizeof(info.n))
+/** Get info item address */
+#define item_addr(n) ((t_u32) &(info.n))
+
+/** Get moal_private member size */
+#define item_priv_size(n) (sizeof ((moal_private *)0)->n)
+/** Get moal_private member address */
+#define item_priv_addr(n) ((t_u32) &((moal_private *)0)->n)
+
+/** Get moal_handle member size */
+#define item_handle_size(n) (sizeof ((moal_handle *)0)->n)
+/** Get moal_handle member address */
+#define item_handle_addr(n) ((t_u32) &((moal_handle *)0)->n)
+
+/** Debug data */
+struct debug_data
+{
+    /** Name */
+    char name[32];
+    /** Size */
+    t_u32 size;
+    /** Address */
+    t_u32 addr;
+};
+
+/** Private debug data */
+struct debug_data_priv
+{
+    /** moal_private handle */
+    moal_private *priv;
+    /** Debug items */
+    struct debug_data *items;
+    /** numbre of item */
+    int num_of_items;
+};
+
+static struct debug_data items[] = {
+    {"int_counter", item_size(int_counter), item_addr(int_counter)},
+    {"wmm_ac_vo", item_size(packets_out[WMM_AC_VO]),
+     item_addr(packets_out[WMM_AC_VO])},
+    {"wmm_ac_vi", item_size(packets_out[WMM_AC_VI]),
+     item_addr(packets_out[WMM_AC_VI])},
+    {"wmm_ac_be", item_size(packets_out[WMM_AC_BE]),
+     item_addr(packets_out[WMM_AC_BE])},
+    {"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]),
+     item_addr(packets_out[WMM_AC_BK])},
+    {"max_tx_buf_size", item_size(max_tx_buf_size), item_addr(max_tx_buf_size)},
+    {"tx_buf_size", item_size(tx_buf_size), item_addr(tx_buf_size)},
+    {"ps_mode", item_size(ps_mode), item_addr(ps_mode)},
+    {"ps_state", item_size(ps_state), item_addr(ps_state)},
+    {"is_deep_sleep", item_size(is_deep_sleep), item_addr(is_deep_sleep)},
+    {"wakeup_dev_req", item_size(pm_wakeup_card_req),
+     item_addr(pm_wakeup_card_req)},
+    {"wakeup_tries", item_size(pm_wakeup_fw_try), item_addr(pm_wakeup_fw_try)},
+    {"hs_configured", item_size(is_hs_configured), item_addr(is_hs_configured)},
+    {"hs_activated", item_size(hs_activated), item_addr(hs_activated)},
+    {"num_tx_timeout", item_size(num_tx_timeout), item_addr(num_tx_timeout)},
+    {"num_cmd_timeout", item_size(num_cmd_timeout), item_addr(num_cmd_timeout)},
+    {"timeout_cmd_id", item_size(timeout_cmd_id), item_addr(timeout_cmd_id)},
+    {"timeout_cmd_act", item_size(timeout_cmd_act), item_addr(timeout_cmd_act)},
+    {"last_cmd_id", item_size(last_cmd_id), item_addr(last_cmd_id)},
+    {"last_cmd_act", item_size(last_cmd_act), item_addr(last_cmd_act)},
+    {"last_cmd_index", item_size(last_cmd_index), item_addr(last_cmd_index)},
+    {"last_cmd_resp_id", item_size(last_cmd_resp_id),
+     item_addr(last_cmd_resp_id)},
+    {"last_cmd_resp_index", item_size(last_cmd_resp_index),
+     item_addr(last_cmd_resp_index)},
+    {"last_event", item_size(last_event), item_addr(last_event)},
+    {"last_event_index", item_size(last_event_index),
+     item_addr(last_event_index)},
+    {"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
+     item_addr(num_cmd_host_to_card_failure)},
+    {"num_cmd_sleep_cfm_fail",
+     item_size(num_cmd_sleep_cfm_host_to_card_failure),
+     item_addr(num_cmd_sleep_cfm_host_to_card_failure)},
+    {"num_tx_h2c_fail", item_size(num_tx_host_to_card_failure),
+     item_addr(num_tx_host_to_card_failure)},
+    {"num_evt_deauth", item_size(num_event_deauth),
+     item_addr(num_event_deauth)},
+    {"num_evt_disassoc", item_size(num_event_disassoc),
+     item_addr(num_event_disassoc)},
+    {"num_evt_link_lost", item_size(num_event_link_lost),
+     item_addr(num_event_link_lost)},
+    {"num_cmd_deauth", item_size(num_cmd_deauth), item_addr(num_cmd_deauth)},
+    {"num_cmd_assoc_ok", item_size(num_cmd_assoc_success),
+     item_addr(num_cmd_assoc_success)},
+    {"num_cmd_assoc_fail", item_size(num_cmd_assoc_failure),
+     item_addr(num_cmd_assoc_failure)},
+    {"cmd_sent", item_size(cmd_sent), item_addr(cmd_sent)},
+    {"data_sent", item_size(data_sent), item_addr(data_sent)},
+    {"mp_rd_bitmap", item_size(mp_rd_bitmap), item_addr(mp_rd_bitmap)},
+    {"curr_rd_port", item_size(curr_rd_port), item_addr(curr_rd_port)},
+    {"mp_wr_bitmap", item_size(mp_wr_bitmap), item_addr(mp_wr_bitmap)},
+    {"curr_wr_port", item_size(curr_wr_port), item_addr(curr_wr_port)},
+    {"cmd_resp_received", item_size(cmd_resp_received),
+     item_addr(cmd_resp_received)},
+    {"event_received", item_size(event_received), item_addr(event_received)},
+
+    {"ioctl_pending", item_handle_size(ioctl_pending),
+     item_handle_addr(ioctl_pending)},
+    {"tx_pending", item_handle_size(tx_pending), item_handle_addr(tx_pending)},
+    {"rx_pending", item_handle_size(rx_pending), item_handle_addr(rx_pending)},
+    {"malloc_count", item_handle_size(malloc_count),
+     item_handle_addr(malloc_count)},
+    {"lock_count", item_handle_size(lock_count), item_handle_addr(lock_count)},
+};
+
+/** Private debug data */
+static struct debug_data_priv items_priv;
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/********************************************************
+		Local Functions
+********************************************************/
+/**
+ *  @brief Proc read function
+ *
+ *  @param page	   Pointer to buffer
+ *  @param s       Read data starting position
+ *  @param off     Offset
+ *  @param cnt     Counter
+ *  @param eof     End of file flag
+ *  @param data    Output data
+ *
+ *  @return 	   Number of output data
+ */
+static int
+woal_debug_read(char *page, char **s, off_t off, int cnt, int *eof, void *data)
+{
+    int val = 0;
+    int i;
+    char *p = page;
+    struct debug_data *d = ((struct debug_data_priv *) data)->items;
+    moal_private *priv = ((struct debug_data_priv *) data)->priv;
+
+    if (MODULE_GET == 0)
+        return MLAN_STATUS_FAILURE;
+
+    /* Get debug information */
+    if (woal_get_debug_info(priv, MOAL_PROC_WAIT, &info)) {
+        *eof = 1;
+        goto exit;
+    }
+    for (i = 0; i < ((struct debug_data_priv *) data)->num_of_items; i++) {
+        if (d[i].size == 1)
+            val = *((t_u8 *) d[i].addr);
+        else if (d[i].size == 2)
+            val = *((t_u16 *) d[i].addr);
+        else if (d[i].size == 4)
+            val = *((t_u32 *) d[i].addr);
+        else {
+            int j;
+            p += sprintf(p, "%s=", d[i].name);
+            for (j = 0; j < d[i].size; j += 2) {
+                val = *(t_u16 *) (d[i].addr + j);
+                p += sprintf(p, "0x%x ", val);
+            }
+            p += sprintf(p, "\n");
+            continue;
+        }
+        if (strstr(d[i].name, "id"))
+            p += sprintf(p, "%s=0x%x\n", d[i].name, val);
+        else
+            p += sprintf(p, "%s=%d\n", d[i].name, val);
+    }
+    if (info.tx_tbl_num) {
+        p += sprintf(p, "Tx BA stream table:\n");
+        for (i = 0; i < info.tx_tbl_num; i++) {
+            p += sprintf(p, "tid = %d, ra = %02x:%02x:%02x:%02x:%02x:%02x\n",
+                         (int) info.tx_tbl[i].tid, info.tx_tbl[i].ra[0],
+                         info.tx_tbl[i].ra[1], info.tx_tbl[i].ra[2],
+                         info.tx_tbl[i].ra[3], info.tx_tbl[i].ra[4],
+                         info.tx_tbl[i].ra[5]);
+        }
+    }
+    if (info.rx_tbl_num) {
+        p += sprintf(p, "Rx reorder table:\n");
+        for (i = 0; i < info.rx_tbl_num; i++) {
+            int j;
+
+            p += sprintf(p,
+                         "tid = %d, ta =  %02x:%02x:%02x:%02x:%02x:%02x, start_win = %d, "
+                         "win_size = %d, buffer: ", (int) info.rx_tbl[i].tid,
+                         info.rx_tbl[i].ta[0], info.rx_tbl[i].ta[1],
+                         info.rx_tbl[i].ta[2], info.rx_tbl[i].ta[3],
+                         info.rx_tbl[i].ta[4], info.rx_tbl[i].ta[5],
+                         (int) info.rx_tbl[i].start_win,
+                         (int) info.rx_tbl[i].win_size);
+            for (j = 0; j < info.rx_tbl[i].win_size; j++) {
+                if (info.rx_tbl[i].buffer[j] == MTRUE)
+                    p += sprintf(p, "1 ");
+                else
+                    p += sprintf(p, "0 ");
+            }
+            p += sprintf(p, "\n");
+        }
+    }
+  exit:
+    MODULE_PUT;
+    return p - page;
+}
+
+/**
+ *  @brief Proc write function
+ *
+ *  @param f	   File pointer
+ *  @param buf     Pointer to data buffer
+ *  @param cnt     Data number to write
+ *  @param data    Data to write
+ *
+ *  @return 	   Number of data
+ */
+static int
+woal_debug_write(struct file *f, const char *buf, unsigned long cnt, void *data)
+{
+    int r, i;
+    char *pdata;
+    char *p;
+    char *p0;
+    char *p1;
+    char *p2;
+    struct debug_data *d = ((struct debug_data_priv *) data)->items;
+    moal_private *priv = ((struct debug_data_priv *) data)->priv;
+
+    if (MODULE_GET == 0)
+        return MLAN_STATUS_FAILURE;
+
+    pdata = (char *) kmalloc(cnt, GFP_ATOMIC);
+    if (pdata == NULL) {
+        MODULE_PUT;
+        return 0;
+    }
+
+    if (copy_from_user(pdata, buf, cnt)) {
+        PRINTM(MERROR, "Copy from user failed\n");
+        kfree(pdata);
+        MODULE_PUT;
+        return 0;
+    }
+
+    p0 = pdata;
+    for (i = 0; i < ((struct debug_data_priv *) data)->num_of_items; i++) {
+        do {
+            p = strstr(p0, d[i].name);
+            if (p == NULL)
+                break;
+            p1 = strchr(p, '\n');
+            if (p1 == NULL)
+                break;
+            p0 = p1++;
+            p2 = strchr(p, '=');
+            if (!p2)
+                break;
+            p2++;
+            r = woal_string_to_number(p2);
+            if (d[i].size == 1)
+                *((t_u8 *) d[i].addr) = (t_u8) r;
+            else if (d[i].size == 2)
+                *((t_u16 *) d[i].addr) = (t_u16) r;
+            else if (d[i].size == 4)
+                *((t_u32 *) d[i].addr) = (t_u32) r;
+            break;
+        } while (MTRUE);
+    }
+    kfree(pdata);
+
+    /* Set debug information */
+    if (woal_set_debug_info(priv, MOAL_IOCTL_WAIT, &info)) {
+        MODULE_PUT;
+        return 0;
+    }
+
+    MODULE_PUT;
+    return cnt;
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+/**
+ *  @brief Create debug proc file
+ *
+ *  @param priv	   A pointer to a moal_private structure
+ *
+ *  @return 	   None
+ */
+void
+woal_debug_entry(moal_private * priv)
+{
+    struct proc_dir_entry *r;
+
+    ENTER();
+
+    if (priv->proc_entry == NULL)
+        return;
+
+    if (woal_get_debug_info(priv, MOAL_PROC_WAIT, &info)) {
+        LEAVE();
+        return;
+    }
+    /* Setup MOAL debug info */
+    if (priv->bss_type == MLAN_BSS_TYPE_STA) {
+        items_priv.priv = priv;
+        items_priv.items = items;
+        items_priv.num_of_items = sizeof(items) / sizeof(items[0]);
+        items[items_priv.num_of_items - 1].addr += (t_u32) (priv->phandle);
+        items[items_priv.num_of_items - 2].addr += (t_u32) (priv->phandle);
+        items[items_priv.num_of_items - 3].addr += (t_u32) (priv->phandle);
+        items[items_priv.num_of_items - 4].addr += (t_u32) (priv->phandle);
+        items[items_priv.num_of_items - 5].addr += (t_u32) (priv->phandle);
+    }
+    /* Create proc entry */
+    r = create_proc_entry("debug", 0644, priv->proc_entry);
+    if (r == NULL) {
+        LEAVE();
+        return;
+    }
+    /* Populate proc entry handlers */
+    if (priv->bss_type == MLAN_BSS_TYPE_STA)
+        r->data = &items_priv;
+    r->read_proc = woal_debug_read;
+    r->write_proc = woal_debug_write;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
+    r->owner = THIS_MODULE;
+#endif
+
+    LEAVE();
+}
+
+/**
+ *  @brief Remove proc file
+ *
+ *  @param priv	 A pointer to a moal_private structure
+ *
+ *  @return 	 None
+ */
+void
+woal_debug_remove(moal_private * priv)
+{
+    ENTER();
+    if (priv->bss_type == MLAN_BSS_TYPE_STA) {
+        /* Reset MOAL debug info */
+        items[items_priv.num_of_items - 1].addr -= (t_u32) (priv->phandle);
+        items[items_priv.num_of_items - 2].addr -= (t_u32) (priv->phandle);
+        items[items_priv.num_of_items - 3].addr -= (t_u32) (priv->phandle);
+        items[items_priv.num_of_items - 4].addr -= (t_u32) (priv->phandle);
+        items[items_priv.num_of_items - 5].addr -= (t_u32) (priv->phandle);
+    }
+    /* Remove proc entry */
+    remove_proc_entry("debug", priv->proc_entry);
+
+    LEAVE();
+}
+#endif
diff --git a/wlan_src/mlinux/moal_ioctl.c b/wlan_src/mlinux/moal_ioctl.c
new file mode 100755
index 0000000..46c176e
--- /dev/null
+++ b/wlan_src/mlinux/moal_ioctl.c
@@ -0,0 +1,733 @@
+/** @file moal_ioctl.c
+  *
+  * @brief This file contains ioctl function to MLAN
+  * 
+  * Copyright (C) 2008-2009, Marvell International Ltd. 
+  *
+  * This software file (the "File") is distributed by Marvell International 
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+  * (the "License").  You may use, redistribute and/or modify this File in 
+  * accordance with the terms and conditions of the License, a copy of which 
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+  * this warranty disclaimer.
+  *
+  */
+
+/********************************************************
+Change log:
+    10/21/2008: initial version
+********************************************************/
+
+#include        "moal_main.h"
+
+/********************************************************
+                Local Variables
+********************************************************/
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+/** 
+ *  @brief Copy multicast table
+ *   
+ *  @param mlist    A pointer to mlan_multicast_list structure
+ *  @param dev      A pointer to net_device structure                 
+ *
+ *  @return         Number of mulitcast address
+ */
+static inline int
+woal_copy_mcast_addr(mlan_multicast_list * mlist, struct net_device *dev)
+{
+    int i = 0;
+    struct dev_mc_list *mcptr = dev->mc_list;
+
+    for (i = 0; i < dev->mc_count; i++) {
+        memcpy(&mlist->mac_list[i], mcptr->dmi_addr, ETH_ALEN);
+        mcptr = mcptr->next;
+    }
+    return i;
+}
+
+/** 
+ *  @brief Fill in wait queue 
+ *   
+ *  @param priv         A pointer to moal_private structure
+ *  @param wait         A pointer to wait_queue structure                 
+ *  @param wait_option  Wait option
+ *
+ *  @return             None
+ */
+static inline void
+woal_fill_wait_queue(moal_private * priv, wait_queue * wait, t_u8 wait_option)
+{
+    ENTER();
+    wait->start_time = jiffies;
+    switch (wait_option) {
+    case MOAL_NO_WAIT:
+        break;
+    case MOAL_IOCTL_WAIT:
+        priv->ioctl_wait_q_woken = MFALSE;
+        wait->wait = &priv->ioctl_wait_q;
+        wait->condition = &priv->ioctl_wait_q_woken;
+        break;
+    case MOAL_CMD_WAIT:
+        priv->cmd_wait_q_woken = MFALSE;
+        wait->wait = &priv->cmd_wait_q;
+        wait->condition = &priv->cmd_wait_q_woken;
+        break;
+    case MOAL_PROC_WAIT:
+        priv->proc_wait_q_woken = MFALSE;
+        wait->wait = &priv->proc_wait_q;
+        wait->condition = &priv->proc_wait_q_woken;
+        break;
+    case MOAL_WSTATS_WAIT:
+        priv->w_stats_wait_q_woken = MFALSE;
+        wait->wait = &priv->w_stats_wait_q;
+        wait->condition = &priv->w_stats_wait_q_woken;
+        break;
+    }
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief Wait mlan ioctl complete
+ *   
+ *  @param priv         A pointer to moal_private structure
+ *  @param req          A pointer to mlan_ioctl_req structure   
+ *  @param wait_option  Wait option
+ *
+ *  @return             None
+ */
+static inline void
+woal_wait_ioctl_complete(moal_private * priv, mlan_ioctl_req * req,
+                         t_u8 wait_option)
+{
+    BOOLEAN cancel_flag = MFALSE;
+    ENTER();
+
+    switch (wait_option) {
+    case MOAL_NO_WAIT:
+        break;
+    case MOAL_IOCTL_WAIT:
+        wait_event_interruptible(priv->ioctl_wait_q, priv->ioctl_wait_q_woken);
+        if (priv->ioctl_wait_q_woken == MFALSE)
+            cancel_flag = MTRUE;
+        break;
+    case MOAL_CMD_WAIT:
+        wait_event_interruptible(priv->cmd_wait_q, priv->cmd_wait_q_woken);
+        if (priv->cmd_wait_q_woken == MFALSE)
+            cancel_flag = MTRUE;
+        break;
+    case MOAL_PROC_WAIT:
+        wait_event_interruptible(priv->proc_wait_q, priv->proc_wait_q_woken);
+        if (priv->proc_wait_q_woken == MFALSE)
+            cancel_flag = MTRUE;
+        break;
+    case MOAL_WSTATS_WAIT:
+        wait_event_interruptible(priv->w_stats_wait_q,
+                                 priv->w_stats_wait_q_woken);
+        if (priv->w_stats_wait_q_woken == MFALSE)
+            cancel_flag = MTRUE;
+        break;
+    }
+    if (cancel_flag == MTRUE) {
+        req->action = MLAN_ACT_CANCEL;
+        mlan_ioctl(priv->phandle->pmlan_adapter, req);
+        PRINTM(MCMND,
+               "IOCTL cancel: id=0x%lx, sub_id=0x%lx wait_option=%d, action=%d\n",
+               req->req_id, (*(t_u32 *) req->pbuf), wait_option,
+               (int) req->action);
+    }
+    LEAVE();
+    return;
+}
+
+/********************************************************
+                Global Functions
+********************************************************/
+/** 
+ *  @brief Send open request to MLAN
+ *   
+ *  @param priv   A pointer to moal_private structure
+ *
+ *  @return       MLAN_STATUS_SUCCESS
+ */
+mlan_status
+woal_request_open(moal_private * priv)
+{
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Send close request to MLAN
+ *   
+ *  @param priv   A pointer to moal_private structure
+ *
+ *  @return       MLAN_STATUS_SUCCESS
+ */
+mlan_status
+woal_request_close(moal_private * priv)
+{
+    if (!netif_queue_stopped(priv->netdev))
+        netif_stop_queue(priv->netdev);
+    if (netif_carrier_ok(priv->netdev))
+        netif_carrier_off(priv->netdev);
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Send ioctl request to MLAN
+ *   
+ *  @param priv          A pointer to moal_private structure
+ *  @param req           A pointer to mlan_ioctl_req buffer
+ *  @param wait_option   Wait option (MOAL_WAIT or MOAL_NO_WAIT)
+ *
+ *  @return              MLAN_STATUS_SUCCESS -- success, otherwise fail
+ */
+mlan_status
+woal_request_ioctl(moal_private * priv, mlan_ioctl_req * req, t_u8 wait_option)
+{
+    wait_queue *wait;
+    mlan_status status;
+
+    ENTER();
+    if (priv->phandle->surprise_removed == MTRUE) {
+        PRINTM(MERROR, "IOCTL is not allowed while surprise_removed = TRUE\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    wait = (wait_queue *) req->reserved_1;
+    req->bss_num = priv->bss_num;
+    if (wait_option)
+        woal_fill_wait_queue(priv, wait, wait_option);
+    else
+        req->reserved_1 = 0;
+
+    /* Call MLAN ioctl handle */
+    status = mlan_ioctl(priv->phandle->pmlan_adapter, req);
+    switch (status) {
+    case MLAN_STATUS_PENDING:
+        PRINTM(MCMND,
+               "IOCTL pending: id=0x%lx, sub_id=0x%lx wait_option=%d, action=%d\n",
+               req->req_id, (*(t_u32 *) req->pbuf), wait_option,
+               (int) req->action);
+        atomic_inc(&priv->phandle->ioctl_pending);
+        /* Status pending, wake up main process */
+        queue_work(priv->phandle->workqueue, &priv->phandle->main_work);
+
+        /* Wait for completion */
+        if (wait_option) {
+            woal_wait_ioctl_complete(priv, req, wait_option);
+            status = wait->status;
+        }
+        break;
+    case MLAN_STATUS_SUCCESS:
+    case MLAN_STATUS_FAILURE:
+    case MLAN_STATUS_RESOURCE:
+    default:
+        break;
+    }
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Send set MAC address request to MLAN
+ *   
+ *  @param priv   A pointer to moal_private structure
+ *
+ *  @return       MLAN_STATUS_SUCCESS -- success, otherwise fail
+ */
+mlan_status
+woal_request_set_mac_address(moal_private * priv)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_bss *bss = NULL;
+    mlan_status status;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        status = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_BSS_MAC_ADDR;
+    memcpy(&bss->param.mac_addr, priv->current_addr,
+           sizeof(mlan_802_11_mac_addr));
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_SET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, MOAL_CMD_WAIT);
+    if (status == MLAN_STATUS_SUCCESS) {
+        memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
+        HEXDUMP("priv->MacAddr:", priv->current_addr, ETH_ALEN);
+    } else {
+        PRINTM(MERROR, "set mac address failed! status=%d, error_code=0x%lx\n",
+               status, req->status_code);
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Send multicast list request to MLAN
+ *   
+ *  @param priv   A pointer to moal_private structure
+ *  @param dev    A pointer to net_device structure                 
+ *
+ *  @return       None
+ */
+void
+woal_request_set_multicast_list(moal_private * priv, struct net_device *dev)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_bss *bss = NULL;
+    mlan_status status;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        PRINTM(MERROR, "%s:Fail to alloc ioctl req buffer\n", __FUNCTION__);
+        goto done;
+    }
+
+    /* Fill request buffer */
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_BSS_MULTICAST_LIST;
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_SET;
+    if (dev->flags & IFF_PROMISC) {
+        bss->param.multicast_list.mode = MLAN_PROMISC_MODE;
+    } else if (dev->flags & IFF_ALLMULTI ||
+               dev->mc_count > MLAN_MAX_MULTICAST_LIST_SIZE) {
+        bss->param.multicast_list.mode = MLAN_ALL_MULTI_MODE;
+    } else {
+        bss->param.multicast_list.mode = MLAN_MULTICAST_MODE;
+        if (dev->mc_count)
+            bss->param.multicast_list.num_multicast_addr =
+                woal_copy_mcast_addr(&bss->param.multicast_list, dev);
+    }
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, MOAL_NO_WAIT);
+    if (status != MLAN_STATUS_PENDING)
+        kfree(req);
+  done:
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief Send deauth command to MLAN
+ *   
+ *  @param priv          A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param mac           MAC address to deauthenticate
+ *
+ *  @return              MLAN_STATUS_SUCCESS -- success, otherwise fail
+ */
+mlan_status
+woal_disconnect(moal_private * priv, t_u8 wait_option, t_u8 * mac)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_bss *bss = NULL;
+    mlan_status status;
+
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        status = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_BSS_STOP;
+    if (mac)
+        memcpy((t_u8 *) & bss->param.bssid, mac, sizeof(mlan_802_11_mac_addr));
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_SET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+
+  done:
+    if (req)
+        kfree(req);
+#ifdef REASSOCIATION
+    priv->reassoc_required = MFALSE;
+#endif /* REASSOCIATION */
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Send bss_start command to MLAN
+ *   
+ *  @param priv          A pointer to moal_private structure
+ *  @param wait_option          Wait option  
+ *  @param ssid_bssid    A point to mlan_ssid_bssid structure
+ *
+ *  @return              MLAN_STATUS_SUCCESS -- success, otherwise fail
+ */
+mlan_status
+woal_bss_start(moal_private * priv, t_u8 wait_option,
+               mlan_ssid_bssid * ssid_bssid)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_bss *bss = NULL;
+    mlan_status status;
+
+    ENTER();
+
+    /* Stop the O.S. TX queue if needed */
+    if (!netif_queue_stopped(priv->netdev))
+        netif_stop_queue(priv->netdev);
+
+    /* Allocate an IOCTL request buffer */
+    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        status = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_BSS_START;
+    if (ssid_bssid)
+        memcpy(&bss->param.ssid_bssid, ssid_bssid, sizeof(mlan_ssid_bssid));
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_SET;
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get BSS info
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param bss_info             A pointer to mlan_bss_info structure
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_bss_info(moal_private * priv, t_u8 wait_option,
+                  mlan_bss_info * bss_info)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_get_info *info = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    info = (mlan_ds_get_info *) req->pbuf;
+    info->sub_command = MLAN_OID_GET_BSS_INFO;
+    req->req_id = MLAN_IOCTL_GET_INFO;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS) {
+        if (bss_info) {
+            memcpy(bss_info, &info->param.bss_info, sizeof(mlan_bss_info));
+        }
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+#ifdef PROC_DEBUG
+/** 
+ *  @brief Get debug info
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param debug_info           A pointer to mlan_debug_info structure
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_debug_info(moal_private * priv, t_u8 wait_option,
+                    mlan_debug_info * debug_info)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_get_info *info = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    info = (mlan_ds_get_info *) req->pbuf;
+    info->sub_command = MLAN_OID_GET_DEBUG_INFO;
+    req->req_id = MLAN_IOCTL_GET_INFO;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS) {
+        if (debug_info) {
+            memcpy(debug_info, &info->param.debug_info,
+                   sizeof(mlan_debug_info));
+        }
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set debug info
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param debug_info           A pointer to mlan_debug_info structure
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_set_debug_info(moal_private * priv, t_u8 wait_option,
+                    mlan_debug_info * debug_info)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_get_info *info = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    if (!debug_info) {
+        ret = -EINVAL;
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    info = (mlan_ds_get_info *) req->pbuf;
+    info->sub_command = MLAN_OID_GET_DEBUG_INFO;
+    memcpy(&info->param.debug_info, debug_info, sizeof(mlan_debug_info));
+    req->req_id = MLAN_IOCTL_GET_INFO;
+    req->action = MLAN_ACT_SET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+#endif /* PROC_DEBUG */
+
+/** 
+ *  @brief ioctl function get BSS type
+ *   
+ *  @param dev      A pointer to net_device structure
+ *  @param req      A pointer to ifreq structure
+ *  @return         MLAN_STATUS_SUCCESS -- success, otherwise fail
+ */
+mlan_status
+woal_get_bss_type(struct net_device * dev, struct ifreq * req)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    int bss_type;
+
+    ENTER();
+
+    bss_type = (int) priv->bss_type;
+    if (copy_to_user(req->ifr_data, &bss_type, sizeof(int))) {
+        PRINTM(MINFO, "Copy to user failed!\n");
+        ret = -EFAULT;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get Host Sleep parameters
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wait_option  Wait option (MOAL_WAIT or MOAL_NO_WAIT)   
+ *  @param hscfg        A pointer to mlan_ds_hs_cfg structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_hs_params(moal_private * priv, t_u8 wait_option,
+                   mlan_ds_hs_cfg * hscfg)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ds_pm_cfg *pmcfg = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    pmcfg = (mlan_ds_pm_cfg *) req->pbuf;
+    pmcfg->sub_command = MLAN_OID_PM_CFG_HS_CFG;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    ret = woal_request_ioctl(priv, req, wait_option);
+    if (ret == MLAN_STATUS_SUCCESS) {
+        if (hscfg) {
+            memcpy(hscfg, &pmcfg->param.hs_cfg, sizeof(mlan_ds_hs_cfg));
+        }
+    }
+  done:
+    if (req && (ret != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Cancel Host Sleep configuration
+ *
+ *  @param priv             A pointer to moal_private structure
+ *  @param wait_option      wait option
+ *
+ *  @return      MLAN_STATUS_SUCCESS, MLAN_STATUS_PENDING,
+ *                      or MLAN_STATUS_FAILURE          
+ */
+mlan_status
+woal_hs_cfg_cancel(moal_private * priv, t_u8 wait_option)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_pm_cfg *pmcfg = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    pmcfg = (mlan_ds_pm_cfg *) req->pbuf;
+    pmcfg->sub_command = MLAN_OID_PM_CFG_HS_CFG;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+    req->action = MLAN_ACT_SET;
+
+    /* Get current Host Sleep configuration */
+    woal_get_hs_params(priv, wait_option, &pmcfg->param.hs_cfg);
+
+    pmcfg->param.hs_cfg.conditions = HOST_SLEEP_CFG_CANCEL;
+    pmcfg->param.hs_cfg.is_invoke_hostcmd = MTRUE;
+
+    ret = woal_request_ioctl(priv, req, wait_option);
+
+    if (ret != MLAN_STATUS_PENDING)
+        kfree(req);
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set wapi enable
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param enable               MTRUE or MFALSE
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_set_wapi_enable(moal_private * priv, t_u8 wait_option, t_u32 enable)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_WAPI_ENABLED;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_SET;
+    sec->param.wapi_enabled = enable;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
diff --git a/wlan_src/mlinux/moal_main.c b/wlan_src/mlinux/moal_main.c
new file mode 100755
index 0000000..1eee3e1
--- /dev/null
+++ b/wlan_src/mlinux/moal_main.c
@@ -0,0 +1,1620 @@
+/** @file moal_main.c
+  *
+  * @brief This file contains the major functions in WLAN
+  * driver. 
+  *
+  * Copyright (C) 2008-2009, Marvell International Ltd. 
+  * 
+  * This software file (the "File") is distributed by Marvell International 
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+  * (the "License").  You may use, redistribute and/or modify this File in 
+  * accordance with the terms and conditions of the License, a copy of which 
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+  * this warranty disclaimer.
+  *
+  */
+
+/********************************************************
+Change log:
+    10/21/2008: initial version
+********************************************************/
+
+#include	"moal_main.h"
+#include 	"moal_sdio.h"
+
+/********************************************************
+		Local Variables
+********************************************************/
+
+/** Driver version */
+const char driver_version[] =
+    "SD8787-%s-M2614" MLAN_RELEASE_VERSION "-GPL" "-(" "FP" FPNUM ")"
+#ifdef	DEBUG_LEVEL2
+    "-dbg"
+#endif
+    " ";
+
+/** Firmware name */
+char *fw_name = NULL;
+
+#ifdef MFG_CMD_SUPPORT
+/** Mfg mode */
+int mfg_mode = 0;
+#endif
+
+/** woal_callbacks */
+static mlan_callbacks woal_callbacks = {
+    .moal_init_fw_complete = moal_init_fw_complete,
+    .moal_shutdown_fw_complete = moal_shutdown_fw_complete,
+    .moal_send_packet_complete = moal_send_packet_complete,
+    .moal_recv_complete = moal_recv_complete,
+    .moal_recv_packet = moal_recv_packet,
+    .moal_recv_event = moal_recv_event,
+    .moal_ioctl_complete = moal_ioctl_complete,
+    .moal_alloc_mlan_buffer = moal_alloc_mlan_buffer,
+    .moal_free_mlan_buffer = moal_free_mlan_buffer,
+    .moal_write_reg = moal_write_reg,
+    .moal_read_reg = moal_read_reg,
+    .moal_write_data_sync = moal_write_data_sync,
+    .moal_read_data_sync = moal_read_data_sync,
+    .moal_malloc = moal_malloc,
+    .moal_mfree = moal_mfree,
+    .moal_memset = moal_memset,
+    .moal_memcpy = moal_memcpy,
+    .moal_memmove = moal_memmove,
+    .moal_memcmp = moal_memcmp,
+    .moal_get_system_time = moal_get_system_time,
+    .moal_init_timer = moal_init_timer,
+    .moal_free_timer = moal_free_timer,
+    .moal_start_timer = moal_start_timer,
+    .moal_stop_timer = moal_stop_timer,
+    .moal_init_lock = moal_init_lock,
+    .moal_free_lock = moal_free_lock,
+    .moal_spin_lock = moal_spin_lock,
+    .moal_spin_unlock = moal_spin_unlock,
+    .moal_print = moal_print,
+};
+
+/** BSS attributes */
+static mlan_bss_attr woal_bss_sta[] = {
+    {MLAN_BSS_TYPE_STA, MLAN_DATA_FRAME_TYPE_ETH_II, MTRUE, 0},
+};
+
+int drv_mode = DRV_MODE_STA;
+
+/** Supported drv_mode table */
+static moal_drv_mode drv_mode_tbl[] = {
+    {
+     /* drv_mode */
+     .drv_mode = DRV_MODE_STA,
+     /* intf number */
+     .intf_num = sizeof(woal_bss_sta) / sizeof(woal_bss_sta[0]),
+     /* bss_attr */
+     .bss_attr = woal_bss_sta,
+     /* fw name */
+     .fw_name = DEFAULT_FW_NAME,
+     }
+    ,
+};
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/** Semaphore for add/remove card */
+struct semaphore AddRemoveCardSem;
+/**
+ * The global variable of a pointer to moal_handle
+ * structure variable
+ */
+moal_handle *m_handle = NULL;
+
+#ifdef DEBUG_LEVEL1
+#ifdef DEBUG_LEVEL2
+#define	DEFAULT_DEBUG_MASK	(0xffffffff & ~MEVENT)
+#else
+#define DEFAULT_DEBUG_MASK	(MMSG | MFATAL | MERROR)
+#endif /* DEBUG_LEVEL2 */
+t_u32 drvdbg = DEFAULT_DEBUG_MASK;
+t_u32 ifdbg = 0;
+#endif /* DEBUG_LEVEL1 */
+
+/********************************************************
+		Local Functions
+********************************************************/
+/** 
+ *  @brief This function initializes software
+ *  
+ *  @param handle A pointer to moal_handle structure
+ *
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_init_sw(moal_handle * handle)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    int i;
+    mlan_device device;
+    t_void *pmlan;
+
+    ENTER();
+
+    /* find moal_drv_mode entry from drv_mode_tbl */
+    handle->drv_mode = NULL;
+    for (i = 0; i < (sizeof(drv_mode_tbl) / sizeof(drv_mode_tbl[0])); i++) {
+        if (drv_mode_tbl[i].drv_mode == drv_mode) {
+            handle->drv_mode = &drv_mode_tbl[i];
+            break;
+        }
+    }
+
+    if (!handle->drv_mode) {
+        PRINTM(MERROR, "Invalid drv_mode=%d\n", drv_mode);
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    /* Initialize moal_handle structure */
+    handle->hardware_status = HardwareStatusInitializing;
+    /* PnP and power profile */
+    handle->surprise_removed = MFALSE;
+    init_waitqueue_head(&handle->init_wait_q);
+
+#ifdef REASSOCIATION
+    MOAL_INIT_SEMAPHORE(&handle->reassoc_sem);
+
+#if (WIRELESS_EXT >= 18)
+    handle->reassoc_on = MFALSE;
+#else
+    handle->reassoc_on = MTRUE;
+#endif
+
+    /* Initialize the timer for the reassociation */
+    woal_initialize_timer(&handle->reassoc_timer,
+                          woal_reassoc_timer_func, handle);
+    handle->is_reassoc_timer_set = MFALSE;
+#endif /* REASSOCIATION */
+    /* Register to MLAN */
+    memset(&device, 0, sizeof(mlan_device));
+    device.pmoal_handle = handle;
+
+#ifdef MFG_CMD_SUPPORT
+    device.mfg_mode = (t_u32) mfg_mode;
+#endif
+    for (i = 0; i < handle->drv_mode->intf_num; i++) {
+        device.bss_attr[i].bss_type = handle->drv_mode->bss_attr[i].bss_type;
+        device.bss_attr[i].frame_type =
+            handle->drv_mode->bss_attr[i].frame_type;
+        device.bss_attr[i].active = handle->drv_mode->bss_attr[i].active;
+        device.bss_attr[i].bss_priority =
+            handle->drv_mode->bss_attr[i].bss_priority;
+    }
+    memcpy(&device.callbacks, &woal_callbacks, sizeof(mlan_callbacks));
+    sdio_claim_host(((struct sdio_mmc_card *) handle->card)->func);
+    if (MLAN_STATUS_SUCCESS == mlan_register(&device, &pmlan))
+        handle->pmlan_adapter = pmlan;
+    else
+        ret = MLAN_STATUS_FAILURE;
+    sdio_release_host(((struct sdio_mmc_card *) handle->card)->func);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function frees the structure of moal_handle
+ *    
+ *  @param handle   A pointer to moal_handle structure
+ *
+ *  @return 	    N/A
+ */
+void
+woal_free_moal_handle(moal_handle * handle)
+{
+    ENTER();
+    if (!handle) {
+        PRINTM(MERROR, "The handle is NULL.\n");
+        LEAVE();
+        return;
+    }
+
+    if ((handle->nl_sk) && ((handle->nl_sk)->sk_socket)) {
+        sock_release((handle->nl_sk)->sk_socket);
+        handle->nl_sk = NULL;
+    }
+
+    if (handle->pmlan_adapter)
+        mlan_unregister(handle->pmlan_adapter);
+    PRINTM(MINFO, "Free Adapter\n");
+    if (handle->malloc_count || handle->lock_count) {
+        PRINTM(MERROR,
+               "mlan has memory leak: malloc_count=%lu lock_count=%lu\n",
+               handle->malloc_count, handle->lock_count);
+    }
+    /* Free the moal handle itself */
+    kfree(handle);
+    m_handle = NULL;
+    LEAVE();
+}
+
+/** 
+ *  @brief This function initializes firmware
+ *  
+ *  @param handle  A pointer to moal_handle structure
+ *
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_init_fw(moal_handle * handle)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    int err;
+    mlan_fw_image fw;
+
+    ENTER();
+
+    memset(&fw, 0, sizeof(mlan_fw_image));
+
+    if ((err =
+         request_firmware(&handle->firmware, handle->drv_mode->fw_name,
+                          handle->hotplug_device)) < 0) {
+        PRINTM(MFATAL, "request_firmware() failed, error code = %#x\n", err);
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    fw.pfw_buf = (t_u8 *) handle->firmware->data;
+    fw.fw_len = handle->firmware->size;
+    sdio_claim_host(((struct sdio_mmc_card *) handle->card)->func);
+    ret = mlan_dnld_fw(handle->pmlan_adapter, &fw);
+    sdio_release_host(((struct sdio_mmc_card *) handle->card)->func);
+    if (ret == MLAN_STATUS_FAILURE)
+        goto done;
+    PRINTM(MMSG, "WLAN FW is active\n");
+
+    handle->hardware_status = HardwareStatusFwReady;
+    if (ret != MLAN_STATUS_SUCCESS)
+        goto done;
+
+    handle->init_wait_q_woken = MFALSE;
+    sdio_claim_host(((struct sdio_mmc_card *) handle->card)->func);
+    ret = mlan_init_fw(handle->pmlan_adapter);
+    sdio_release_host(((struct sdio_mmc_card *) handle->card)->func);
+    if (ret == MLAN_STATUS_FAILURE) {
+        goto done;
+    } else if (ret == MLAN_STATUS_SUCCESS) {
+        handle->hardware_status = HardwareStatusReady;
+        goto done;
+    }
+    /* Wait for mlan_init to complete */
+    wait_event_interruptible(handle->init_wait_q, handle->init_wait_q_woken);
+    if (handle->hardware_status != HardwareStatusReady) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    ret = MLAN_STATUS_SUCCESS;
+
+  done:
+    if (handle->firmware)
+        release_firmware(handle->firmware);
+    if (ret != MLAN_STATUS_SUCCESS) {
+        ret = MLAN_STATUS_FAILURE;
+    }
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function will fill in the mlan_buffer
+ *  
+ *  @param pmbuf   A pointer to mlan_buffer
+ *  @param skb     A pointer to struct sk_buff 
+ *
+ *  @return        N/A
+ */
+static void
+woal_fill_mlan_buffer(mlan_buffer * pmbuf, struct sk_buff *skb)
+{
+    struct ethhdr *eth = NULL;
+    struct timeval tstamp;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+    struct iphdr *iph;
+#endif
+    t_u8 tid = 0;
+
+    ENTER();
+
+    eth = (struct ethhdr *) skb->data;
+    switch (eth->h_proto) {
+    case __constant_htons(ETH_P_IP):
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+        iph = ip_hdr(skb);
+        tid = IPTOS_PREC(iph->tos);
+#else
+        tid = IPTOS_PREC(skb->nh.iph->tos);
+#endif
+        PRINTM(MDATA, "packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
+               eth->h_proto, tid, skb->priority);
+        break;
+    case __constant_htons(ETH_P_ARP):
+        PRINTM(MDATA, "ARP packet %04x\n", eth->h_proto);
+    default:
+        break;
+    }
+/** Offset for TOS field in the IP header */
+#define IPTOS_OFFSET 5
+    skb->priority = tid = (tid >> IPTOS_OFFSET);
+    /* Record the current time the packet was queued; used to determine the
+       amount of time the packet was queued in the driver before it was sent to 
+       the firmware.  The delay is then sent along with the packet to the
+       firmware for aggregate delay calculation for stats and MSDU lifetime
+       expiry. */
+    do_gettimeofday(&tstamp);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+    skb->tstamp = timeval_to_ktime(tstamp);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
+    skb_set_timestamp(skb, &tstamp);
+#else
+    memcpy(&skb->stamp, &tstamp, sizeof(skb->stamp));
+#endif
+    pmbuf->pdesc = skb;
+    pmbuf->pbuf = skb->head + sizeof(mlan_buffer);
+    pmbuf->data_offset = skb->data - (skb->head + sizeof(mlan_buffer));
+    pmbuf->data_len = skb->len;
+    pmbuf->priority = skb->priority;
+    pmbuf->in_ts_sec = (t_u32) tstamp.tv_sec;
+    pmbuf->in_ts_usec = (t_u32) tstamp.tv_usec;
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function opens the network device
+ *  
+ *  @param dev     A pointer to net_device structure
+ *
+ *  @return        0 --success, otherwise fail
+ */
+static int
+woal_open(struct net_device *dev)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    t_u8 carrier_on = MFALSE;
+
+    ENTER();
+
+    if (!MODULE_GET) {
+        LEAVE();
+        return -EFAULT;
+    }
+    if ((priv->bss_type == MLAN_BSS_TYPE_STA) &&
+        (priv->media_connected || priv->is_adhoc_link_sensed))
+        carrier_on = MTRUE;
+    if (carrier_on == MTRUE) {
+        netif_carrier_on(priv->netdev);
+        if (netif_queue_stopped(priv->netdev))
+            netif_wake_queue(priv->netdev);
+    } else
+        netif_carrier_off(priv->netdev);
+    woal_request_open(priv);
+
+    LEAVE();
+    return 0;
+}
+
+/** 
+ *  @brief This function closes the network device
+ *  
+ *  @param dev     A pointer to net_device structure
+ *
+ *  @return        0
+ */
+static int
+woal_close(struct net_device *dev)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+
+    ENTER();
+
+    woal_request_close(priv);
+    MODULE_PUT;
+
+    LEAVE();
+    return 0;
+}
+
+/** 
+ *  @brief This function handles packet transmission
+ *  
+ *  @param skb     A pointer to sk_buff structure
+ *  @param dev     A pointer to net_device structure
+ *
+ *  @return        0 --success, otherwise fail
+ */
+int
+woal_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_buffer *pmbuf = NULL;
+    mlan_status status;
+    struct sk_buff *new_skb = NULL;
+
+    ENTER();
+
+    PRINTM(MDATA, "%lu BSS(%d): Data <= kernel\n", jiffies, priv->bss_num);
+
+    if (priv->phandle->surprise_removed == MTRUE) {
+        kfree(skb);
+        priv->stats.tx_dropped++;
+        goto done;
+    }
+    if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
+        PRINTM(MERROR, "Tx Error: Bad skb length %d : %d\n",
+               skb->len, ETH_FRAME_LEN);
+        kfree(skb);
+        priv->stats.tx_dropped++;
+        goto done;
+    }
+    if (skb_headroom(skb) < (MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer))) {
+        PRINTM(MWARN, "Tx: Insufficient skb headroom %d\n", skb_headroom(skb));
+        /* Insufficient skb headroom - allocate a new skb */
+        new_skb =
+            skb_realloc_headroom(skb,
+                                 MLAN_MIN_DATA_HEADER_LEN +
+                                 sizeof(mlan_buffer));
+        if (unlikely(!new_skb)) {
+            PRINTM(MERROR, "Tx: Cannot allocate skb\n");
+            kfree(skb);
+            priv->stats.tx_dropped++;
+            goto done;
+        }
+        kfree_skb(skb);
+        skb = new_skb;
+        PRINTM(MINFO, "new skb headroom %d\n", skb_headroom(skb));
+    }
+    pmbuf = (mlan_buffer *) skb->head;
+    pmbuf->bss_num = priv->bss_num;
+    woal_fill_mlan_buffer(pmbuf, skb);
+    status = mlan_send_packet(priv->phandle->pmlan_adapter, pmbuf);
+    switch (status) {
+    case MLAN_STATUS_PENDING:
+        atomic_inc(&priv->phandle->tx_pending);
+        if (atomic_read(&priv->phandle->tx_pending) >= MAX_TX_PENDING) {
+            netif_stop_queue(priv->netdev);
+            dev->trans_start = jiffies;
+        }
+        queue_work(priv->phandle->workqueue, &priv->phandle->main_work);
+        break;
+    case MLAN_STATUS_SUCCESS:
+        priv->stats.tx_packets++;
+        priv->stats.tx_bytes += skb->len;
+        woal_free_mlan_buffer(pmbuf);
+        break;
+    case MLAN_STATUS_FAILURE:
+    default:
+        priv->stats.tx_dropped++;
+        woal_free_mlan_buffer(pmbuf);
+        break;
+    }
+  done:
+    LEAVE();
+    return 0;
+}
+
+/** 
+ *  @brief This function sets the MAC address to firmware.
+ *  
+ *  @param dev     A pointer to mlan_private structure
+ *  @param addr    MAC address to set
+ *
+ *  @return        0 --success, otherwise fail
+ */
+static int
+woal_set_mac_address(struct net_device *dev, void *addr)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    struct sockaddr *phw_addr = (struct sockaddr *) addr;
+
+    ENTER();
+
+    memset(priv->current_addr, 0, ETH_ALEN);
+    /* dev->dev_addr is 6 bytes */
+    HEXDUMP("dev->dev_addr:", dev->dev_addr, ETH_ALEN);
+
+    HEXDUMP("addr:", (t_u8 *) phw_addr->sa_data, ETH_ALEN);
+    memcpy(priv->current_addr, phw_addr->sa_data, ETH_ALEN);
+    if (MLAN_STATUS_SUCCESS != woal_request_set_mac_address(priv)) {
+        PRINTM(MERROR, "Set MAC address failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    HEXDUMP("priv->MacAddr:", priv->current_addr, ETH_ALEN);
+    memcpy(dev->dev_addr, priv->current_addr, ETH_ALEN);
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function sets multicast addresses to firmware
+ *  
+ *  @param dev     A pointer to net_device structure
+ *
+ *  @return        N/A
+ */
+static void
+woal_set_multicast_list(struct net_device *dev)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    ENTER();
+    woal_request_set_multicast_list(priv, dev);
+    LEAVE();
+}
+
+/** 
+ *  @brief This function handles the timeout of packet
+ *  		transmission
+ *  
+ *  @param dev     A pointer to net_device structure
+ *
+ *  @return        N/A
+ */
+static void
+woal_tx_timeout(struct net_device *dev)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    ENTER();
+    PRINTM(MERROR, "%lu : Tx timeout, bss_num=%d\n", jiffies, priv->bss_num);
+    dev->trans_start = jiffies;
+    priv->num_tx_timeout++;
+    LEAVE();
+}
+
+/** 
+ *  @brief This function returns the network statistics
+ *  
+ *  @param dev     A pointer to net_device structure
+ *
+ *  @return        A pointer to net_device_stats structure
+ */
+static struct net_device_stats *
+woal_get_stats(struct net_device *dev)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    return &priv->stats;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+/** Network device handlers */
+static const struct net_device_ops woal_netdev_ops = {
+    .ndo_open = woal_open,
+    .ndo_start_xmit = woal_hard_start_xmit,
+    .ndo_stop = woal_close,
+    .ndo_do_ioctl = woal_do_ioctl,
+    .ndo_set_mac_address = woal_set_mac_address,
+    .ndo_tx_timeout = woal_tx_timeout,
+    .ndo_get_stats = woal_get_stats,
+    .ndo_set_multicast_list = woal_set_multicast_list,
+};
+#endif
+
+/**
+ *  @brief This function initializes the private structure 
+ *  		and dev structure for station mode
+ *  
+ *  @param dev     A pointer to net_device structure
+ *  @param priv    A pointer to moal_private structure
+ *
+ *  @return 	   MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+woal_init_sta_dev(struct net_device *dev, moal_private * priv)
+{
+    ENTER();
+
+    /* Setup the OS Interface to our functions */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+    dev->open = woal_open;
+    dev->hard_start_xmit = woal_hard_start_xmit;
+    dev->stop = woal_close;
+    dev->do_ioctl = woal_do_ioctl;
+    dev->set_mac_address = woal_set_mac_address;
+    dev->tx_timeout = woal_tx_timeout;
+    dev->get_stats = woal_get_stats;
+    dev->set_multicast_list = woal_set_multicast_list;
+#else
+    dev->netdev_ops = &woal_netdev_ops;
+#endif
+    dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT;
+    dev->hard_header_len += MLAN_MIN_DATA_HEADER_LEN + sizeof(mlan_buffer);
+#ifdef  WIRELESS_EXT
+#if WIRELESS_EXT < 21
+    dev->get_wireless_stats = woal_get_wireless_stats;
+#endif
+    dev->wireless_handlers = (struct iw_handler_def *) &woal_handler_def;
+#endif
+/** Netif dynamic alloc */
+#define NETIF_F_DYNALLOC 16
+    dev->features |= NETIF_F_DYNALLOC;
+    dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+
+    /* Initialize private structure */
+    init_waitqueue_head(&priv->ioctl_wait_q);
+    init_waitqueue_head(&priv->cmd_wait_q);
+    init_waitqueue_head(&priv->proc_wait_q);
+    init_waitqueue_head(&priv->w_stats_wait_q);
+    priv->current_key_index = 0;
+    priv->rate_index = AUTO_RATE;
+    priv->media_connected = MFALSE;
+    priv->is_adhoc_link_sensed = MFALSE;
+    memset(&priv->current_addr, 0, sizeof(priv->current_addr));
+    memset(&priv->nick_name, 0, sizeof(priv->nick_name));
+    priv->num_tx_timeout = 0;
+    woal_request_get_fw_info(priv);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ * @brief This function adds a new interface. It will
+ * 		allocate, initialize and register the device.
+ *  
+ *  @param handle    A pointer to moal_handle structure
+ *  @param bss_num   BSS number (0-7)
+ *  @param bss_type  BSS type
+ *
+ *  @return          A pointer to the new priv structure
+ */
+moal_private *
+woal_add_interface(moal_handle * handle, t_u8 bss_num, t_u8 bss_type)
+{
+    struct net_device *dev = NULL;
+    moal_private *priv = NULL;
+
+    ENTER();
+
+    /* Allocate an Ethernet device */
+    if (!(dev = alloc_etherdev(sizeof(moal_private)))) {
+        PRINTM(MFATAL, "Init virtual ethernet device failed!\n");
+        goto error;
+    }
+    /* Allocate device name */
+    if ((bss_type == MLAN_BSS_TYPE_STA) && (dev_alloc_name(dev, "mlan%d") < 0)) {
+        PRINTM(MERROR, "Could not allocate device name!\n");
+        goto error;
+    }
+    priv = (moal_private *) netdev_priv(dev);
+    /* Save the priv to handle */
+    bss_num &= BSS_NUM_MASK;
+    handle->priv[bss_num] = priv;
+
+    /* Use the same handle structure */
+    priv->phandle = handle;
+    priv->netdev = dev;
+    priv->bss_num = bss_num;
+    priv->bss_type = bss_type;
+    MOAL_INIT_SEMAPHORE(&priv->async_sem);
+    priv->scan_pending_on_block = MFALSE;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+    SET_MODULE_OWNER(dev);
+#endif
+    if (bss_type == MLAN_BSS_TYPE_STA)
+        woal_init_sta_dev(dev, priv);
+
+    /* Register network device */
+    if (register_netdev(dev)) {
+        PRINTM(MERROR, "Cannot register virtual network device!\n");
+        goto error;
+    }
+
+    PRINTM(MINFO, "%s: Marvell 802.11 Adapter\n", dev->name);
+#ifdef CONFIG_PROC_FS
+    woal_create_proc_entry(priv);
+#ifdef PROC_DEBUG
+    woal_debug_entry(priv);
+#endif /* PROC_DEBUG */
+#endif /* CONFIG_PROC_FS */
+    LEAVE();
+    return priv;
+  error:
+    if (dev)
+        free_netdev(dev);
+    LEAVE();
+    return NULL;
+}
+
+/** 
+ *  @brief This function removes an interface.
+ *  
+ *  @param handle   A pointer to the moal_handle structure
+ *  @param bss_num  BSS number
+ *
+ *  @return        N/A
+ */
+void
+woal_remove_interface(moal_handle * handle, t_u8 bss_num)
+{
+    struct net_device *dev = NULL;
+    moal_private *priv = handle->priv[bss_num];
+    union iwreq_data wrqu;
+
+    ENTER();
+    if (!priv)
+        goto error;
+    dev = priv->netdev;
+
+    if (priv->media_connected == MTRUE) {
+        priv->media_connected = MFALSE;
+        if (priv->bss_type == MLAN_BSS_TYPE_STA) {
+            memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
+            wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+            wireless_send_event(priv->netdev, SIOCGIWAP, &wrqu, NULL);
+        }
+    }
+#ifdef CONFIG_PROC_FS
+#ifdef PROC_DEBUG
+    /* Remove proc debug */
+    woal_debug_remove(priv);
+#endif /* PROC_DEBUG */
+    woal_proc_remove(priv);
+#endif /* CONFIG_PROC_FS */
+    /* Last reference is our one */
+    PRINTM(MINFO, "refcnt = %d\n", atomic_read(&dev->refcnt));
+
+    PRINTM(MINFO, "netdev_finish_unregister: %s%s\n", dev->name,
+           (dev->features & NETIF_F_DYNALLOC) ? "" : ", old style");
+
+    if (dev->reg_state == NETREG_REGISTERED)
+        unregister_netdev(dev);
+
+    /* Clear the priv in handle */
+    priv->phandle->priv[priv->bss_num] = NULL;
+    priv->phandle = NULL;
+    priv->netdev = NULL;
+    free_netdev(dev);
+  error:
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief Send FW shutdown command to MLAN
+ *   
+ *  @param priv          A pointer to moal_private structure
+ *  @param wait_option   Wait option
+ *
+ *  @return              MLAN_STATUS_SUCCESS -- success, otherwise fail
+ */
+mlan_status
+woal_shutdown_fw(moal_private * priv, t_u8 wait_option)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_misc_cfg *misc = NULL;
+    mlan_status status;
+
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req =
+        (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        status = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    misc = (mlan_ds_misc_cfg *) req->pbuf;
+    misc->sub_command = MLAN_OID_MISC_INIT_SHUTDOWN;
+    misc->param.func_init_shutdown = MLAN_FUNC_SHUTDOWN;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+    req->action = MLAN_ACT_SET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+/**
+ *  @brief This function initializes the private structure
+ *  		and set default value to the member of moal_private.
+ *  
+ *  @param priv    A pointer to moal_private structure
+ *
+ *  @return 	   N/A
+ */
+void
+woal_init_priv(moal_private * priv)
+{
+    ENTER();
+    if (priv->bss_type == MLAN_BSS_TYPE_STA) {
+        priv->current_key_index = 0;
+        priv->rate_index = AUTO_RATE;
+        priv->media_connected = MFALSE;
+        priv->is_adhoc_link_sensed = MFALSE;
+        memset(&priv->current_addr, 0, sizeof(priv->current_addr));
+        memset(&priv->nick_name, 0, sizeof(priv->nick_name));
+        priv->num_tx_timeout = 0;
+        woal_request_get_fw_info(priv);
+    }
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function return the point to structure moal_private 
+ *  
+ *  @param handle   Pointer to structure moal_handle
+ *  @param bss_num  BSS number
+ *
+ *  @return         moal_private pointer or NULL
+ */
+moal_private *
+woal_bss_num_to_priv(moal_handle * handle, t_u8 bss_num)
+{
+    ENTER();
+    if (!handle || (bss_num >= MLAN_MAX_BSS_NUM)) {
+        LEAVE();
+        return NULL;
+    }
+    LEAVE();
+    return handle->priv[bss_num];
+}
+
+/** 
+ *  @brief This function alloc mlan_buffer.
+ *
+ *  @param size	   buffer size to allocate
+ *
+ *  @return        mlan_buffer pointer or NULL
+ */
+pmlan_buffer
+woal_alloc_mlan_buffer(int size)
+{
+    mlan_buffer *pmbuf = NULL;
+    struct sk_buff *skb;
+
+    ENTER();
+    if (!(pmbuf = kzalloc(sizeof(mlan_buffer), GFP_ATOMIC))) {
+        PRINTM(MERROR, "%s: Fail to alloc mlan buffer", __FUNCTION__);
+        return NULL;
+    }
+    if (!(skb = dev_alloc_skb(size))) {
+        kfree(pmbuf);
+        return NULL;
+    }
+    pmbuf->pdesc = (t_void *) skb;
+    pmbuf->pbuf = (t_u8 *) skb->tail;
+    LEAVE();
+    return pmbuf;
+}
+
+/** 
+ *  @brief This function alloc mlan_ioctl_req.
+ *
+ *  @param size	   buffer size to allocate
+ *
+ *  @return        mlan_ioctl_req pointer or NULL
+ */
+pmlan_ioctl_req
+woal_alloc_mlan_ioctl_req(int size)
+{
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    if (!
+        (req =
+         (mlan_ioctl_req *)
+         kzalloc((sizeof(mlan_ioctl_req) + size + sizeof(int) +
+                  sizeof(wait_queue)), GFP_ATOMIC))) {
+        PRINTM(MERROR, "%s: Fail to alloc ioctl buffer", __FUNCTION__);
+        LEAVE();
+        return NULL;
+    }
+    req->pbuf = (t_u8 *) req + sizeof(mlan_ioctl_req);
+    req->buf_len = (t_u32) size;
+    req->reserved_1 =
+        ALIGN_ADDR((t_u8 *) req + sizeof(mlan_ioctl_req) + size, sizeof(int));
+
+    LEAVE();
+    return req;
+}
+
+/** 
+ *  @brief This function frees mlan_buffer.
+ *
+ *  @param pmbuf   Pointer to mlan_buffer
+ *
+ *  @return        N/A
+ */
+void
+woal_free_mlan_buffer(pmlan_buffer pmbuf)
+{
+    ENTER();
+    if (!pmbuf)
+        return;
+    if (pmbuf->pdesc)
+        dev_kfree_skb_any((struct sk_buff *) pmbuf->pdesc);
+    kfree(pmbuf);
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief This function handles events generated by firmware
+ *  
+ *  @param priv    A pointer to moal_private structure
+ *  @param payload A pointer to payload buffer
+ *  @param len	   Length of the payload
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_broadcast_event(moal_private * priv, t_u8 * payload, t_u32 len)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    struct sk_buff *skb = NULL;
+    struct nlmsghdr *nlh = NULL;
+    moal_handle *handle = priv->phandle;
+    struct sock *sk = handle->nl_sk;
+
+    ENTER();
+    if (len > NL_MAX_PAYLOAD) {
+        PRINTM(MERROR, "event size is too big!!! len=%d\n", (int) len);
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    if (sk) {
+        /* Allocate skb */
+        if (!(skb = alloc_skb(NLMSG_SPACE(NL_MAX_PAYLOAD), GFP_ATOMIC))) {
+            PRINTM(MERROR, "Could not allocate skb for netlink.\n");
+            ret = MLAN_STATUS_FAILURE;
+            goto done;
+        }
+        nlh = (struct nlmsghdr *) skb->data;
+        nlh->nlmsg_len = NLMSG_SPACE(len);
+
+        /* From kernel */
+        nlh->nlmsg_pid = 0;
+        nlh->nlmsg_flags = 0;
+
+        /* Data */
+        skb_put(skb, nlh->nlmsg_len);
+        memcpy(NLMSG_DATA(nlh), payload, len);
+
+        /* From Kernel */
+        NETLINK_CB(skb).pid = 0;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+        /* Multicast message */
+        NETLINK_CB(skb).dst_pid = 0;
+#endif
+
+        /* Multicast group number */
+        NETLINK_CB(skb).dst_group = NL_MULTICAST_GROUP;
+
+        /* Send message */
+        netlink_broadcast(sk, skb, 0, NL_MULTICAST_GROUP, GFP_KERNEL);
+
+        ret = MLAN_STATUS_SUCCESS;
+    } else {
+        PRINTM(MERROR, "Could not send event through NETLINK. Link down.\n");
+        ret = MLAN_STATUS_FAILURE;
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+#ifdef REASSOCIATION
+/**
+ *  @brief This function handles re-association. it is triggered
+ *  by re-assoc timer.
+ *
+ *  @param data    A pointer to wlan_thread structure
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+int
+woal_reassociation_thread(void *data)
+{
+    moal_thread *pmoal_thread = data;
+    moal_private *priv = NULL;
+    moal_handle *handle = (moal_handle *) pmoal_thread->handle;
+    wait_queue_t wait;
+    int i;
+    BOOLEAN reassoc_timer_req;
+    mlan_802_11_ssid req_ssid;
+    mlan_ssid_bssid ssid_bssid;
+    mlan_status status;
+    mlan_bss_info bss_info;
+
+    ENTER();
+
+    woal_activate_thread(pmoal_thread);
+    init_waitqueue_entry(&wait, current);
+
+    current->flags |= PF_NOFREEZE;
+
+    for (;;) {
+        add_wait_queue(&pmoal_thread->wait_q, &wait);
+        set_current_state(TASK_INTERRUPTIBLE);
+
+        schedule();
+
+        set_current_state(TASK_RUNNING);
+        remove_wait_queue(&pmoal_thread->wait_q, &wait);
+
+        /* Cancel re-association timer */
+        if (handle->is_reassoc_timer_set == MTRUE) {
+            woal_cancel_timer(&handle->reassoc_timer);
+            handle->is_reassoc_timer_set = MFALSE;
+        }
+
+        if (handle->surprise_removed)
+            break;
+        if (kthread_should_stop())
+            break;
+
+        if (handle->hardware_status != HardwareStatusReady) {
+            PRINTM(MINFO, "Reassoc: Hardware status is not correct\n");
+            continue;
+        }
+        PRINTM(MINFO, "Reassoc: Thread waking up...\n");
+        reassoc_timer_req = MFALSE;
+
+        for (i = 0; i < handle->priv_num && (priv = handle->priv[i]); i++) {
+            if (priv->reassoc_required == MFALSE)
+                continue;
+            memset(&bss_info, 0, sizeof(bss_info));
+            if (MLAN_STATUS_SUCCESS !=
+                woal_get_bss_info(priv, MOAL_CMD_WAIT, &bss_info)) {
+                PRINTM(MINFO, "Ressoc: Fail to get bss info\n");
+                priv->reassoc_required = MFALSE;
+                continue;
+            }
+            if (bss_info.bss_mode != MLAN_BSS_MODE_INFRA ||
+                priv->media_connected != MFALSE) {
+                PRINTM(MINFO, "Reassoc: ad-hoc mode or media connected\n");
+                priv->reassoc_required = MFALSE;
+                continue;
+            }
+
+            /* The semaphore is used to avoid reassociation thread and
+               wlan_set_scan/wlan_set_essid interrupting each other.
+               Reassociation should be disabled completely by application if
+               wlan_set_user_scan_ioctl/wlan_set_wap is used. */
+            if (MOAL_ACQ_SEMAPHORE_BLOCK(&handle->reassoc_sem)) {
+                PRINTM(MERROR,
+                       "Acquire semaphore error, reassociation thread\n");
+                reassoc_timer_req = MTRUE;
+                break;
+            }
+            PRINTM(MINFO, "Reassoc: Required ESSID: %s\n",
+                   priv->prev_ssid_bssid.ssid.ssid);
+            PRINTM(MINFO, "Reassoc: Performing Active Scan\n");
+
+            memset(&req_ssid, 0, sizeof(mlan_802_11_ssid));
+            memcpy(&req_ssid, &priv->prev_ssid_bssid.ssid,
+                   sizeof(mlan_802_11_ssid));
+
+            /* Do specific SSID scanning */
+            if (MLAN_STATUS_SUCCESS !=
+                woal_request_scan(priv, MOAL_CMD_WAIT, &req_ssid)) {
+                PRINTM(MERROR, "Reassoc: Fail to do specific scan\n");
+                reassoc_timer_req = MTRUE;
+                MOAL_REL_SEMAPHORE(&handle->reassoc_sem);
+                break;
+            }
+
+            if (handle->surprise_removed) {
+                MOAL_REL_SEMAPHORE(&handle->reassoc_sem);
+                break;
+            }
+            status =
+                woal_set_ewpa_mode(priv, MOAL_CMD_WAIT, &priv->prev_ssid_bssid);
+            /* Search AP by BSSID first */
+            PRINTM(MINFO, "Reassoc: Search AP by BSSID first\n");
+            memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid));
+            memcpy(&ssid_bssid.bssid, &priv->prev_ssid_bssid.bssid,
+                   MLAN_MAC_ADDR_LENGTH);
+            status = woal_find_best_network(priv, MOAL_CMD_WAIT, &ssid_bssid);
+            if (MLAN_STATUS_SUCCESS != status) {
+                PRINTM(MINFO, "Reassoc: AP not found in scan list\n");
+                PRINTM(MINFO, "Reassoc: Search AP by SSID\n");
+                /* Search AP by SSID */
+                memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid));
+                memcpy(&ssid_bssid.ssid, &priv->prev_ssid_bssid.ssid,
+                       sizeof(mlan_802_11_ssid));
+                status =
+                    woal_find_best_network(priv, MOAL_CMD_WAIT, &ssid_bssid);
+            }
+            if (status == MLAN_STATUS_SUCCESS) {
+                /* set the wep key */
+                if (bss_info.wep_status)
+                    woal_enable_wep_key(priv, MOAL_IOCTL_WAIT);
+                /* Zero SSID implies use BSSID to connect */
+                memset(&ssid_bssid.ssid, 0, sizeof(mlan_802_11_ssid));
+                status = woal_bss_start(priv, MOAL_CMD_WAIT, &ssid_bssid);
+            }
+            if (priv->media_connected == MFALSE)
+                reassoc_timer_req = MTRUE;
+            else {
+                mlan_ds_rate *rate = NULL;
+                mlan_ioctl_req *req = NULL;
+
+                reassoc_timer_req = MFALSE;
+
+                if (priv->rate_index != AUTO_RATE) {
+                    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
+
+                    if (req == NULL) {
+                        LEAVE();
+                        return MLAN_STATUS_FAILURE;
+                    }
+
+                    rate = (mlan_ds_rate *) req->pbuf;
+                    rate->param.rate_cfg.rate_type = MLAN_RATE_INDEX;
+                    rate->sub_command = MLAN_OID_RATE_CFG;
+                    req->req_id = MLAN_IOCTL_RATE;
+
+                    req->action = MLAN_ACT_SET;
+
+                    rate->param.rate_cfg.rate = priv->rate_index;
+
+                    if (MLAN_STATUS_SUCCESS !=
+                        woal_request_ioctl(priv, req, MOAL_CMD_WAIT)) {
+                        kfree(req);
+                        LEAVE();
+                        return MLAN_STATUS_FAILURE;
+                    }
+                    if (req)
+                        kfree(req);
+                }
+            }
+            MOAL_REL_SEMAPHORE(&handle->reassoc_sem);
+        }
+        if (handle->surprise_removed)
+            break;
+        if (reassoc_timer_req == MTRUE) {
+            PRINTM(MINFO,
+                   "Reassoc: No AP found or assoc failed. Restarting re-assoc Timer.\n");
+            handle->is_reassoc_timer_set = MTRUE;
+            woal_mod_timer(&handle->reassoc_timer, MOAL_TIMER_10S);
+        }
+    }
+    woal_deactivate_thread(pmoal_thread);
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function triggers re-association by waking up
+ *  re-assoc thread.
+ *  
+ *  @param context	A pointer to context
+ *  @return		n/a
+ */
+void
+woal_reassoc_timer_func(void *context)
+{
+    moal_handle *handle = (moal_handle *) context;
+
+    ENTER();
+
+    PRINTM(MINFO, "reassoc_timer fired.\n");
+    handle->is_reassoc_timer_set = MFALSE;
+
+    PRINTM(MINFO, "Waking Up the Reassoc Thread\n");
+    wake_up_interruptible(&handle->reassoc_thread.wait_q);
+
+    LEAVE();
+    return;
+}
+#endif /* REASSOCIATION */
+
+/**
+ *  @brief This workqueue function handles main_process
+ *  
+ *  @param work    A pointer to work_struct
+ *
+ *  @return        N/A
+ */
+t_void
+woal_main_work_queue(struct work_struct * work)
+{
+    moal_handle *handle = container_of(work, moal_handle, main_work);
+
+    ENTER();
+
+    if (handle->surprise_removed == MTRUE) {
+        LEAVE();
+        return;
+    }
+    sdio_claim_host(((struct sdio_mmc_card *) handle->card)->func);
+    /* Call MLAN main process */
+    mlan_main_process(handle->pmlan_adapter);
+    sdio_release_host(((struct sdio_mmc_card *) handle->card)->func);
+
+    LEAVE();
+}
+
+/**
+ *  @brief This function cancel all works in the queue
+ *  and destroy the main workqueue.
+ *  
+ *  @param handle    A pointer to moal_handle
+ *
+ *  @return        N/A
+ */
+static void
+woal_terminate_workqueue(moal_handle * handle)
+{
+    ENTER();
+
+    flush_workqueue(handle->workqueue);
+    destroy_workqueue(handle->workqueue);
+    handle->workqueue = NULL;
+
+    LEAVE();
+}
+
+void
+woal_interrupt(moal_handle * handle)
+{
+    ENTER();
+
+    PRINTM(MINTR, "*\n");
+    if (handle->surprise_removed == MTRUE) {
+        LEAVE();
+        return;
+    }
+    /* call mlan_interrupt to read int status */
+    mlan_interrupt(handle->pmlan_adapter);
+    queue_work(handle->workqueue, &handle->main_work);
+    LEAVE();
+}
+
+/**
+ * @brief This function adds the card. it will probe the
+ * 		card, allocate the mlan_private and initialize the device. 
+ *  
+ *  @param card    A pointer to card
+ *
+ *  @return        A pointer to moal_handle structure
+ */
+moal_handle *
+woal_add_card(void *card)
+{
+    moal_handle *handle = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    int i;
+
+    ENTER();
+
+    if (down_interruptible(&AddRemoveCardSem))
+        goto exit_sem_err;
+
+    /* Allocate buffer for moal_handle */
+    if (!(handle = kmalloc(sizeof(moal_handle), GFP_ATOMIC))) {
+        PRINTM(MERROR, "Allocate buffer for moal_handle failed!\n");
+        goto err_handle;
+    }
+
+    /* Init moal_handle */
+    memset(handle, 0, sizeof(moal_handle));
+    handle->card = card;
+    m_handle = handle;
+    ((struct sdio_mmc_card *) card)->handle = handle;
+
+    /* Init SW */
+    if (MLAN_STATUS_SUCCESS != woal_init_sw(handle)) {
+        PRINTM(MFATAL, "Software Init Failed\n");
+        goto err_kmalloc;
+    }
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
+    handle->nl_sk =
+        netlink_kernel_create(NETLINK_MARVELL, NL_MULTICAST_GROUP, NULL,
+                              THIS_MODULE);
+#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+    handle->nl_sk =
+        netlink_kernel_create(NETLINK_MARVELL, NL_MULTICAST_GROUP, NULL, NULL,
+                              THIS_MODULE);
+#else
+    handle->nl_sk =
+        netlink_kernel_create(&init_net, NETLINK_MARVELL, NL_MULTICAST_GROUP,
+                              NULL, NULL, THIS_MODULE);
+#endif
+#endif
+    if (handle->nl_sk == NULL) {
+        PRINTM(MERROR,
+               "Could not initialize netlink event passing mechanism!\n");
+        goto err_kmalloc;
+    }
+
+    /** Create workqueue */
+    handle->workqueue = create_workqueue("MOAL_WORK_QUEUE");
+    if (!handle->workqueue)
+        goto err_kmalloc;
+
+    MLAN_INIT_WORK(&handle->main_work, woal_main_work_queue);
+
+#ifdef REASSOCIATION
+    PRINTM(MINFO, "Starting re-association thread...\n");
+    handle->reassoc_thread.handle = handle;
+    woal_create_thread(woal_reassociation_thread, &handle->reassoc_thread,
+                       "woal_reassoc_service");
+
+    while (!handle->reassoc_thread.pid) {
+        woal_sched_timeout(2);
+    }
+#endif /* REASSOCIATION */
+
+    /* Register the device. Fill up the private data structure with relevant
+       information from the card and request for the required IRQ. */
+    if (woal_register_dev(handle) != MLAN_STATUS_SUCCESS) {
+        PRINTM(MFATAL, "Failed to register wlan device!\n");
+        goto err_registerdev;
+    }
+
+    /* Init FW and HW */
+    if (MLAN_STATUS_SUCCESS != woal_init_fw(handle)) {
+        PRINTM(MFATAL, "Firmware Init Failed\n");
+        goto err_init_fw;
+    }
+#ifdef CONFIG_PROC_FS
+    /* Initialize proc fs */
+    woal_proc_init(handle);
+#endif /* CONFIG_PROC_FS */
+    /* Add interfaces */
+    for (i = 0; i < handle->drv_mode->intf_num; i++) {
+        if (!woal_add_interface
+            (handle, handle->priv_num,
+             handle->drv_mode->bss_attr[i].bss_type)) {
+            status = MLAN_STATUS_FAILURE;
+            break;
+        }
+        handle->priv_num++;
+    }
+    if (status != MLAN_STATUS_SUCCESS)
+        goto err_add_intf;
+    up(&AddRemoveCardSem);
+    LEAVE();
+    return handle;
+  err_add_intf:
+    for (i = 0; i < handle->priv_num; i++)
+        woal_remove_interface(handle, i);
+#ifdef CONFIG_PROC_FS
+    woal_proc_exit(handle);
+#endif
+  err_init_fw:
+    /* Unregister device */
+    PRINTM(MINFO, "unregister device\n");
+    woal_unregister_dev(handle);
+  err_registerdev:
+    handle->surprise_removed = MTRUE;
+    woal_terminate_workqueue(handle);
+#ifdef REASSOCIATION
+    if (handle->reassoc_thread.pid) {
+        wake_up_interruptible(&handle->reassoc_thread.wait_q);
+    }
+    /* waiting for main thread quit */
+    while (handle->reassoc_thread.pid) {
+        woal_sched_timeout(2);
+    }
+#endif /* REASSOCIATION */
+  err_kmalloc:
+    if ((handle->hardware_status == HardwareStatusFwReady) ||
+        (handle->hardware_status == HardwareStatusReady)) {
+        PRINTM(MINFO, "shutdown mlan\n");
+        handle->init_wait_q_woken = MFALSE;
+        status = mlan_shutdown_fw(handle->pmlan_adapter);
+        if (status == MLAN_STATUS_PENDING)
+            wait_event_interruptible(handle->init_wait_q,
+                                     handle->init_wait_q_woken);
+    }
+    woal_free_moal_handle(handle);
+    m_handle = NULL;
+    ((struct sdio_mmc_card *) card)->handle = NULL;
+  err_handle:
+    up(&AddRemoveCardSem);
+  exit_sem_err:
+    LEAVE();
+    return NULL;
+}
+
+/** 
+ *  @brief This function removes the card.
+ *  
+ *  @param card    A pointer to card
+ *
+ *  @return        MLAN_STATUS_SUCCESS
+ */
+mlan_status
+woal_remove_card(void *card)
+{
+    moal_handle *handle = NULL;
+    moal_private *priv = NULL;
+    mlan_status status;
+    int i;
+
+    ENTER();
+    if (down_interruptible(&AddRemoveCardSem))
+        goto exit_sem_err;
+
+    handle = m_handle;
+    if (!handle)
+        goto exit_remove;
+    handle->surprise_removed = MTRUE;
+
+    /* Stop data */
+    for (i = 0; i < handle->priv_num; i++) {
+        if ((priv = handle->priv[i])) {
+            if (!netif_queue_stopped(priv->netdev))
+                netif_stop_queue(priv->netdev);
+            if (netif_carrier_ok(priv->netdev))
+                netif_carrier_off(priv->netdev);
+        }
+    }
+
+    /* Shutdown firmware */
+    PRINTM(MCMND, "mlan_shutdown_fw.....\n");
+    handle->init_wait_q_woken = MFALSE;
+    status = mlan_shutdown_fw(handle->pmlan_adapter);
+    if (status == MLAN_STATUS_PENDING)
+        wait_event_interruptible(handle->init_wait_q,
+                                 handle->init_wait_q_woken);
+    PRINTM(MCMND, "mlan_shutdown_fw done!\n");
+    if (atomic_read(&handle->rx_pending) || atomic_read(&handle->tx_pending) ||
+        atomic_read(&handle->ioctl_pending)) {
+        PRINTM(MERROR, "ERR: rx_pending=%d,tx_pending=%d,ioctl_pending=%d\n",
+               atomic_read(&handle->rx_pending),
+               atomic_read(&handle->tx_pending),
+               atomic_read(&handle->ioctl_pending));
+    }
+
+    /* Remove interface */
+    for (i = 0; i < handle->priv_num; i++)
+        woal_remove_interface(handle, i);
+
+    woal_terminate_workqueue(handle);
+
+#ifdef REASSOCIATION
+    PRINTM(MINFO, "Free reassoc_timer\n");
+    if (handle->is_reassoc_timer_set) {
+        woal_cancel_timer(&handle->reassoc_timer);
+        handle->is_reassoc_timer_set = MFALSE;
+    }
+    if (handle->reassoc_thread.pid)
+        wake_up_interruptible(&handle->reassoc_thread.wait_q);
+
+    /* waiting for main thread quit */
+    while (handle->reassoc_thread.pid) {
+        woal_sched_timeout(2);
+    }
+#endif /* REASSOCIATION */
+
+#ifdef CONFIG_PROC_FS
+    woal_proc_exit(handle);
+#endif
+    /* Unregister device */
+    PRINTM(MINFO, "unregister device\n");
+    woal_unregister_dev(handle);
+    /* Free adapter structure */
+    PRINTM(MINFO, "Free Adapter\n");
+    woal_free_moal_handle(handle);
+
+    m_handle = NULL;
+  exit_remove:
+    up(&AddRemoveCardSem);
+  exit_sem_err:
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function initializes module.
+ *  
+ *  @return        MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+woal_init_module(void)
+{
+    int ret = (int) MLAN_STATUS_SUCCESS;
+    int i = 0;
+
+    ENTER();
+
+    /* Replace default fw image name for specific drv_mode */
+    if (fw_name) {
+        for (i = 0; i < (sizeof(drv_mode_tbl) / sizeof(drv_mode_tbl[0])); i++) {
+            if (drv_mode_tbl[i].drv_mode == drv_mode) {
+                drv_mode_tbl[i].fw_name = fw_name;
+                break;
+            }
+        }
+    }
+
+    /* Init mutex */
+    init_MUTEX(&AddRemoveCardSem);
+
+    /* Register with bus */
+    ret = (int) woal_bus_register();
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function cleans module
+ *  
+ *  @return        N/A
+ */
+static void
+woal_cleanup_module(void)
+{
+    moal_handle *handle = m_handle;
+    int i;
+    ENTER();
+    if (down_interruptible(&AddRemoveCardSem))
+        goto exit_sem_err;
+    if (!handle)
+        goto exit;
+
+    for (i = 0; i < handle->priv_num; i++) {
+        if ((handle->priv[i]->bss_type == MLAN_BSS_TYPE_STA) &&
+            (handle->priv[i]->media_connected == MTRUE)) {
+            woal_disconnect(handle->priv[i], MOAL_CMD_WAIT, NULL);
+        }
+    }
+
+#ifdef MFG_CMD_SUPPORT
+    if (!mfg_mode)
+#endif
+        woal_shutdown_fw(woal_get_priv(handle, MLAN_BSS_TYPE_ANY),
+                         MOAL_CMD_WAIT);
+
+  exit:
+    up(&AddRemoveCardSem);
+  exit_sem_err:
+    /* Unregister from bus */
+    woal_bus_unregister();
+    LEAVE();
+}
+
+module_init(woal_init_module);
+module_exit(woal_cleanup_module);
+
+module_param(fw_name, charp, 0);
+MODULE_PARM_DESC(fw_name, "Firmware name");
+#ifdef MFG_CMD_SUPPORT
+module_param(mfg_mode, int, 0);
+MODULE_PARM_DESC(mfg_mode,
+                 "0: Download normal firmware; 1: Download MFG firmware");
+#endif /* MFG_CMD_SUPPORT */
+#ifdef DEBUG_LEVEL1
+module_param(drvdbg, ulong, 0);
+MODULE_PARM_DESC(drvdbg, "Driver debug");
+#endif /* DEBUG_LEVEL1 */
+
+MODULE_DESCRIPTION("M-WLAN Driver");
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_VERSION(MLAN_RELEASE_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/wlan_src/mlinux/moal_main.h b/wlan_src/mlinux/moal_main.h
new file mode 100755
index 0000000..c4d0547
--- /dev/null
+++ b/wlan_src/mlinux/moal_main.h
@@ -0,0 +1,843 @@
+/** @file moal_main.h
+  *
+  * @brief This file contains wlan driver specific defines etc.
+  * 
+  * Copyright (C) 2008-2009, Marvell International Ltd.  
+  *
+  * This software file (the "File") is distributed by Marvell International 
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+  * (the "License").  You may use, redistribute and/or modify this File in 
+  * accordance with the terms and conditions of the License, a copy of which 
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+  * this warranty disclaimer.
+  *
+  */
+
+/********************************************************
+Change log:
+    10/21/2008: initial version
+********************************************************/
+
+#ifndef _MOAL_MAIN_H
+#define _MOAL_MAIN_H
+
+/* warnfix for FS redefination if any? */
+#ifdef FS
+#undef FS
+#endif
+
+/* Linux header files */
+#include        <linux/kernel.h>
+#include        <linux/module.h>
+#include        <linux/init.h>
+#include        <linux/version.h>
+#include        <linux/param.h>
+#include        <linux/delay.h>
+#include        <linux/slab.h>
+#include        <linux/mm.h>
+#include        <linux/types.h>
+#include        <linux/sched.h>
+#include        <linux/timer.h>
+#include        <linux/ioport.h>
+#include        <linux/pci.h>
+#include        <linux/ctype.h>
+#include        <linux/proc_fs.h>
+#include        <linux/vmalloc.h>
+#include	<linux/ptrace.h>
+#include	<linux/string.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
+#include       <linux/config.h>
+#endif
+
+/* ASM files */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#include        <linux/semaphore.h>
+#else
+#include        <asm/semaphore.h>
+#endif
+#include        <asm/byteorder.h>
+#include        <asm/irq.h>
+#include        <asm/uaccess.h>
+#include        <asm/io.h>
+#include        <asm/system.h>
+
+/* Net header files */
+#include        <linux/wireless.h>
+#include        <linux/netdevice.h>
+#include        <linux/net.h>
+#include        <linux/ip.h>
+#include        <linux/skbuff.h>
+#include        <linux/if_arp.h>
+#include        <linux/if_ether.h>
+#include        <linux/etherdevice.h>
+#include        <net/sock.h>
+#include        <net/arp.h>
+#include        <linux/rtnetlink.h>
+
+#include	<linux/firmware.h>
+
+/* Wireless header */
+#include        <net/iw_handler.h>
+#include        "mlan.h"
+#include 	"moal_shim.h"
+#include	"moal_wext.h"
+#include	"moal_priv.h"
+
+/** Define BOOLEAN */
+typedef t_u8 BOOLEAN;
+
+/** Driver version */
+extern const char driver_version[];
+
+/** Private structure for MOAL */
+typedef struct _moal_private moal_private;
+/** Handle data structure for MOAL  */
+typedef struct _moal_handle moal_handle;
+
+/** Hardware status codes */
+typedef enum _MOAL_HARDWARE_STATUS
+{
+    HardwareStatusReady,
+    HardwareStatusInitializing,
+    HardwareStatusFwReady,
+    HardwareStatusReset,
+    HardwareStatusClosing,
+    HardwareStatusNotReady
+} MOAL_HARDWARE_STATUS;
+
+/** moal_wait_option */
+enum
+{
+    MOAL_NO_WAIT,
+    MOAL_IOCTL_WAIT,
+    MOAL_CMD_WAIT,
+    MOAL_PROC_WAIT,
+    MOAL_WSTATS_WAIT
+};
+
+/** HostCmd_Header */
+typedef struct _HostCmd_Header
+{
+    /** Command */
+    t_u16 command;
+    /** Size */
+    t_u16 size;
+} HostCmd_Header;
+
+#ifndef MIN
+/** Find minimum */
+#define MIN(a,b)		((a) < (b) ? (a) : (b))
+#endif
+
+/*
+ * OS timer specific
+ */
+
+/** Timer structure */
+typedef struct _moal_drv_timer
+{
+        /** Timer list */
+    struct timer_list tl;
+        /** Timer function */
+    void (*timer_function) (void *context);
+        /** Timer function context */
+    void *function_context;
+        /** Time period */
+    t_u32 time_period;
+        /** Is timer periodic ? */
+    t_u32 timer_is_periodic;
+        /** Is timer cancelled ? */
+    t_u32 timer_is_canceled;
+} moal_drv_timer, *pmoal_drv_timer;
+
+/** 
+ *  @brief Timer handler
+ *  
+ *  @param fcontext	Timer context
+ *
+ *  @return		N/A
+ */
+static inline void
+woal_timer_handler(unsigned long fcontext)
+{
+    pmoal_drv_timer timer = (pmoal_drv_timer) fcontext;
+
+    timer->timer_function(timer->function_context);
+
+    if (timer->timer_is_periodic == MTRUE) {
+        mod_timer(&timer->tl, jiffies + ((timer->time_period * HZ) / 1000));
+    }
+}
+
+/** 
+ *  @brief Initialize timer
+ *  
+ *  @param timer		Timer structure
+ *  @param TimerFunction	Timer function
+ *  @param FunctionContext	Timer function context
+ *
+ *  @return			N/A
+ */
+static inline void
+woal_initialize_timer(pmoal_drv_timer timer,
+                      void (*TimerFunction) (void *context),
+                      void *FunctionContext)
+{
+    /* First, setup the timer to trigger the wlan_timer_handler proxy */
+    init_timer(&timer->tl);
+    timer->tl.function = woal_timer_handler;
+    timer->tl.data = (t_u32) timer;
+
+    /* Then tell the proxy which function to call and what to pass it */
+    timer->timer_function = TimerFunction;
+    timer->function_context = FunctionContext;
+    timer->timer_is_canceled = MTRUE;
+    timer->time_period = 0;
+    timer->timer_is_periodic = MFALSE;
+}
+
+/** 
+ *  @brief Modify timer
+ *  
+ *  @param timer		Timer structure
+ *  @param MillisecondPeriod	Time period in millisecond
+ *
+ *  @return			N/A
+ */
+static inline void
+woal_mod_timer(pmoal_drv_timer timer, t_u32 MillisecondPeriod)
+{
+    timer->time_period = MillisecondPeriod;
+    mod_timer(&timer->tl, jiffies + (MillisecondPeriod * HZ) / 1000);
+    timer->timer_is_canceled = MFALSE;
+}
+
+/** 
+ *  @brief Cancel timer
+ *  
+ *  @param timer	Timer structure
+ *
+ *  @return		N/A
+ */
+static inline void
+woal_cancel_timer(moal_drv_timer * timer)
+{
+    del_timer(&timer->tl);
+    timer->timer_is_canceled = MTRUE;
+    timer->time_period = 0;
+}
+
+#ifdef REASSOCIATION
+/*
+ * OS Thread Specific
+ */
+
+#include	<linux/kthread.h>
+
+/** Kernel thread structure */
+typedef struct _moal_thread
+{
+    /** Task control structrue */
+    struct task_struct *task;
+    /** Pointer to wait_queue_head */
+    wait_queue_head_t wait_q;
+    /** PID */
+    pid_t pid;
+    /** Pointer to moal_handle */
+    void *handle;
+} moal_thread;
+
+/** 
+ *  @brief Activate thread
+ *  
+ *  @param thr			Thread structure
+ *  @return			N/A
+ */
+static inline void
+woal_activate_thread(moal_thread * thr)
+{
+    /** Record the thread pid */
+    thr->pid = current->pid;
+
+    /** Initialize the wait queue */
+    init_waitqueue_head(&thr->wait_q);
+}
+
+/** 
+ *  @brief De-activate thread
+ *  
+ *  @param thr			Thread structure
+ *  @return			N/A
+ */
+static inline void
+woal_deactivate_thread(moal_thread * thr)
+{
+    /* Reset the pid */
+    thr->pid = 0;
+}
+
+/** 
+ *  @brief Create and run the thread
+ *
+ *  @param threadfunc		Thread function
+ *  @param thr			Thread structure
+ *  @param name			Thread name
+ *  @return			N/A
+ */
+static inline void
+woal_create_thread(int (*threadfunc) (void *), moal_thread * thr, char *name)
+{
+    /* Create and run the thread */
+    thr->task = kthread_run(threadfunc, thr, "%s", name);
+}
+#endif /* REASSOCIATION */
+
+/* The following macros are neccessary to retain compatibility
+ * around the workqueue chenges happened in kernels >= 2.6.20:
+ * - INIT_WORK changed to take 2 arguments and let the work function
+ *   get its own data through the container_of macro
+ * - delayed works have been split from normal works to save some
+ *   memory usage in struct work_struct
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+/** Work_queue work initialization */
+#define MLAN_INIT_WORK(_work, _fun)                 INIT_WORK(_work, ((void (*)(void *))_fun), _work)
+/** Work_queue delayed work initialization */
+#define MLAN_INIT_DELAYED_WORK(_work, _fun)         INIT_WORK(_work, ((void (*)(void *))_fun), _work)
+/** Work_queue container parameter */
+#define MLAN_DELAYED_CONTAINER_OF(_ptr, _type, _m)  container_of(_ptr, _type, _m)
+#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) */
+/** Work_queue work initialization */
+#define MLAN_INIT_WORK                              INIT_WORK
+/** Work_queue delayed work initialization */
+#define MLAN_INIT_DELAYED_WORK                      INIT_DELAYED_WORK
+/** Work_queue container parameter */
+#define MLAN_DELAYED_CONTAINER_OF(_ptr, _type, _m)  container_of(_ptr, _type, _m.work)
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) */
+
+/** 
+ *  @brief Schedule timeout
+ *  
+ *  @param millisec	Timeout duration in milli second
+ *
+ *  @return		N/A
+ */
+static inline void
+woal_sched_timeout(t_u32 millisec)
+{
+    set_current_state(TASK_INTERRUPTIBLE);
+
+    schedule_timeout((millisec * HZ) / 1000);
+}
+
+#ifndef __ATTRIB_ALIGN__
+#define __ATTRIB_ALIGN__ __attribute__((aligned(4)))
+#endif
+
+#ifndef __ATTRIB_PACK__
+#define __ATTRIB_PACK__ __attribute__ ((packed))
+#endif
+
+/** Get module */
+#define MODULE_GET	try_module_get(THIS_MODULE)
+/** Put module */
+#define MODULE_PUT	module_put(THIS_MODULE)
+
+/** Initialize semaphore */
+#define MOAL_INIT_SEMAPHORE(x)    	init_MUTEX(x)
+/** Initialize semaphore */
+#define MOAL_INIT_SEMAPHORE_LOCKED(x) 	init_MUTEX_LOCKED(x)
+/** Acquire semaphore and with blocking */
+#define MOAL_ACQ_SEMAPHORE_BLOCK(x)	down_interruptible(x)
+/** Acquire semaphore without blocking */
+#define MOAL_ACQ_SEMAPHORE_NOBLOCK(x)	down_trylock(x)
+/** Release semaphore */
+#define MOAL_REL_SEMAPHORE(x) 		up(x)
+
+/** Default watchdog timeout */
+#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
+
+/** 10 seconds */
+#define MOAL_TIMER_10S                10000
+/** 5 seconds */
+#define MOAL_TIMER_5S                 5000
+/** 1 second */
+#define MOAL_TIMER_1S                 1000
+
+/** BSS number bit mask */
+#define BSS_NUM_MASK		7
+
+/** Netlink protocol number */
+#define NETLINK_MARVELL     (MAX_LINKS - 1)
+/** Netlink maximum payload size */
+#define NL_MAX_PAYLOAD      1024
+/** Netlink multicast group number */
+#define NL_MULTICAST_GROUP  1
+
+/** MAX PENDING Tx data */
+#define MAX_TX_PENDING    	60
+
+/** wait_queue structure */
+typedef struct _wait_queue
+{
+        /** Pointer to wait_queue_head */
+    wait_queue_head_t *wait;
+        /** Pointer to wait condition */
+    t_u16 *condition;
+        /** Start time */
+    t_u32 start_time;
+        /** Status from MLAN */
+    mlan_status status;
+} wait_queue, *pwait_queue;
+
+/** Driver mode STA */
+#define DRV_MODE_STA       0x1
+/** Driver mode UAP */
+#define DRV_MODE_UAP       0x2
+/** Driver mode STA+UAP */
+#define DRV_MODE_UAP_STA   0x3
+
+typedef struct _moal_drv_mode
+{
+    /** driver mode */
+    t_u16 drv_mode;
+    /** total number of interfaces */
+    t_u16 intf_num;
+    /** attribute of bss */
+    mlan_bss_attr *bss_attr;
+    /** name of firmware image */
+    char *fw_name;
+} moal_drv_mode;
+
+/** Private structure for MOAL */
+struct _moal_private
+{
+        /** Handle structure */
+    moal_handle *phandle;
+        /** Tx timeout count */
+    t_u32 num_tx_timeout;
+        /** BSS number */
+    t_u8 bss_num;
+        /** BSS type */
+    t_u8 bss_type;
+        /** MAC address information */
+    t_u8 current_addr[ETH_ALEN];
+        /** Media connection status */
+    BOOLEAN media_connected;
+        /** Net device pointer */
+    struct net_device *netdev;
+        /** Net device statistics structure */
+    struct net_device_stats stats;
+
+        /** IOCTL wait queue token */
+    t_u16 ioctl_wait_q_woken;
+        /** ioctl wait queue */
+    wait_queue_head_t ioctl_wait_q __ATTRIB_ALIGN__;
+        /** Cmd wait queue token */
+    t_u16 cmd_wait_q_woken;
+        /** IOCTL wait queue */
+    wait_queue_head_t cmd_wait_q __ATTRIB_ALIGN__;
+#ifdef CONFIG_PROC_FS
+        /** Proc entry */
+    struct proc_dir_entry *proc_entry;
+        /** Proc entry name */
+    t_s8 proc_entry_name[IFNAMSIZ];
+        /** Proc wait queue token */
+    t_u16 proc_wait_q_woken;
+        /** IOCTL wait queue */
+    wait_queue_head_t proc_wait_q __ATTRIB_ALIGN__;
+#endif                          /* CONFIG_PROC_FS */
+        /** Nickname */
+    t_u8 nick_name[16];
+        /** AdHoc link sensed flag */
+    BOOLEAN is_adhoc_link_sensed;
+        /** IW statistics */
+    struct iw_statistics w_stats;
+        /** w_stats wait queue token */
+    t_u16 w_stats_wait_q_woken;
+        /** w_stats wait queue */
+    wait_queue_head_t w_stats_wait_q __ATTRIB_ALIGN__;
+        /** Current WEP key index */
+    t_u16 current_key_index;
+#ifdef REASSOCIATION
+    mlan_ssid_bssid prev_ssid_bssid;
+        /** Re-association required */
+    BOOLEAN reassoc_required;
+#endif                          /* REASSOCIATION */
+        /** Rate index */
+    t_u16 rate_index;
+        /** Async scan semaphore */
+    struct semaphore async_sem;
+        /** Scan pending on blocked flag */
+    t_u8 scan_pending_on_block;
+};
+
+/** Handle data structure for MOAL */
+struct _moal_handle
+{
+        /** MLAN adapter structure */
+    t_void *pmlan_adapter;
+        /** Private pointer */
+    moal_private *priv[MLAN_MAX_BSS_NUM];
+        /** Priv number */
+    t_u8 priv_num;
+        /** Bss attr */
+    moal_drv_mode *drv_mode;
+#ifdef CONFIG_PROC_FS
+        /** Proc top level directory entry */
+    struct proc_dir_entry *proc_mwlan;
+#endif
+        /** Firmware */
+    const struct firmware *firmware;
+        /** Hotplug device */
+    struct device *hotplug_device;
+        /** STATUS variables */
+    MOAL_HARDWARE_STATUS hardware_status;
+        /** POWER MANAGEMENT AND PnP SUPPORT */
+    BOOLEAN surprise_removed;
+        /** Firmware release number */
+    t_u32 fw_release_number;
+        /** Init wait queue token */
+    t_u16 init_wait_q_woken;
+        /** Init wait queue */
+    wait_queue_head_t init_wait_q __ATTRIB_ALIGN__;
+        /** Card pointer */
+    t_void *card;
+        /** Rx pending in MLAN */
+    atomic_t rx_pending;
+        /** Tx packet pending count in mlan */
+    atomic_t tx_pending;
+        /** IOCTL pending count in mlan */
+    atomic_t ioctl_pending;
+        /** Malloc count */
+    t_u32 malloc_count;
+        /** lock count */
+    t_u32 lock_count;
+#ifdef REASSOCIATION
+        /** Re-association thread */
+    moal_thread reassoc_thread;
+        /** Re-association timer set flag */
+    BOOLEAN is_reassoc_timer_set;
+        /** Re-association timer */
+    moal_drv_timer reassoc_timer __ATTRIB_ALIGN__;
+        /**  */
+    struct semaphore reassoc_sem;
+        /** Flag of re-association on/off */
+    BOOLEAN reassoc_on;
+#endif                          /* REASSOCIATION */
+        /** Driver workqueue */
+    struct workqueue_struct *workqueue;
+        /** main work */
+    struct work_struct main_work;
+        /** Netlink kernel socket */
+    struct sock *nl_sk;
+};
+
+/** Debug Macro definition*/
+#ifdef	DEBUG_LEVEL1
+extern t_u32 drvdbg;
+extern t_u32 ifdbg;
+
+/** Debug message control bit definition for ifdbg */
+#define MIF_D	MBIT(0)
+
+#ifdef	DEBUG_LEVEL2
+#define	PRINTM_MINFO(msg...)  do {if (drvdbg & MINFO) printk(KERN_DEBUG msg);} while(0)
+#define	PRINTM_MWARN(msg...)  do {if (drvdbg & MWARN) printk(KERN_DEBUG msg);} while(0)
+#define	PRINTM_MENTRY(msg...) do {if (drvdbg & MENTRY) printk(KERN_DEBUG msg);} while(0)
+#else
+#define	PRINTM_MINFO(msg...)  do {} while (0)
+#define	PRINTM_MWARN(msg...)  do {} while (0)
+#define	PRINTM_MENTRY(msg...) do {} while (0)
+#endif /* DEBUG_LEVEL2 */
+
+#define	PRINTM_MFW_D(msg...) do {if (drvdbg & MFW_D) printk(KERN_DEBUG msg);} while(0)
+#define	PRINTM_MCMD_D(msg...) do {if (drvdbg & MCMD_D) printk(KERN_DEBUG msg);} while(0)
+#define	PRINTM_MDAT_D(msg...) do {if (drvdbg & MDAT_D) printk(KERN_DEBUG msg);} while(0)
+
+#define	PRINTM_MINTR(msg...)  do {if (drvdbg & MINTR) printk(KERN_DEBUG msg);} while(0)
+#define	PRINTM_MEVENT(msg...) do {if (drvdbg & MEVENT) printk(msg);} while(0)
+#define	PRINTM_MCMND(msg...)  do {if (drvdbg & MCMND) printk(KERN_DEBUG msg);} while(0)
+#define	PRINTM_MDATA(msg...)  do {if (drvdbg & MDATA) printk(KERN_DEBUG msg);} while(0)
+#define	PRINTM_MERROR(msg...) do {if (drvdbg & MERROR) printk(KERN_DEBUG msg);} while(0)
+#define	PRINTM_MFATAL(msg...) do {if (drvdbg & MFATAL) printk(KERN_DEBUG msg);} while(0)
+#define	PRINTM_MMSG(msg...)   do {if (drvdbg & MMSG) printk(KERN_ALERT msg);} while(0)
+
+#define	PRINTM_MIF_D(msg...) do {if (ifdbg & MIF_D) printk(KERN_DEBUG msg);} while(0)
+
+#define	PRINTM(level,msg...) PRINTM_##level(msg)
+
+#else
+
+#define	PRINTM(level,msg...) do {} while (0)
+
+#endif /* DEBUG_LEVEL1 */
+
+/** Wait until a condition becomes true */
+#define ASSERT(cond)						\
+do {								\
+	if (!(cond))						\
+		PRINTM(MINFO, "ASSERT: %s:%i\n", __FUNCTION__);	\
+} while(0)
+
+/** Log entry point for debugging */
+#define	ENTER()			PRINTM(MENTRY, "Enter: %s\n", \
+                                    __FUNCTION__)
+/** Log exit point for debugging */
+#define	LEAVE()			PRINTM(MENTRY, "Leave: %s\n", \
+                                    __FUNCTION__)
+
+#ifdef DEBUG_LEVEL1
+#define DBG_DUMP_BUF_LEN 	64
+#define MAX_DUMP_PER_LINE	16
+
+static inline void
+hexdump(char *prompt, t_u8 * buf, int len)
+{
+    int i;
+    char dbgdumpbuf[DBG_DUMP_BUF_LEN];
+    char *ptr = dbgdumpbuf;
+
+    printk(KERN_DEBUG "%s:\n", prompt);
+    for (i = 1; i <= len; i++) {
+        ptr += sprintf(ptr, "%02x ", *buf);
+        buf++;
+        if (i % MAX_DUMP_PER_LINE == 0) {
+            *ptr = 0;
+            printk(KERN_DEBUG "%s\n", dbgdumpbuf);
+            ptr = dbgdumpbuf;
+        }
+    }
+    if (len % MAX_DUMP_PER_LINE) {
+        *ptr = 0;
+        printk(KERN_DEBUG "%s\n", dbgdumpbuf);
+    }
+}
+
+#define DBG_HEXDUMP_MCMD_D(x,y,z)    do {if (drvdbg & MCMD_D) hexdump(x,y,z);} while(0)
+#define DBG_HEXDUMP_MDAT_D(x,y,z)    do {if (drvdbg & MDAT_D) hexdump(x,y,z);} while(0)
+#define DBG_HEXDUMP_MIF_D(x,y,z)     do {if (ifdbg & MIF_D) hexdump(x,y,z);} while(0)
+#define DBG_HEXDUMP_MFW_D(x,y,z)     do {if (drvdbg & MFW_D) hexdump(x,y,z);} while(0)
+#define	DBG_HEXDUMP(level,x,y,z)    DBG_HEXDUMP_##level(x,y,z)
+
+#else
+/** Do nothing since debugging is not turned on */
+#define DBG_HEXDUMP(level,x,y,z)    do {} while (0)
+#endif
+
+#ifdef DEBUG_LEVEL2
+#define HEXDUMP(x,y,z)              do {if (drvdbg & MINFO) hexdump(x,y,z);} while(0)
+#else
+/** Do nothing since debugging is not turned on */
+#define HEXDUMP(x,y,z)              do {} while (0)
+#endif
+
+#ifdef BIG_ENDIAN
+/** Convert from 16 bit little endian format to CPU format */
+#define woal_le16_to_cpu(x) le16_to_cpu(x)
+/** Convert from 32 bit little endian format to CPU format */
+#define woal_le32_to_cpu(x) le32_to_cpu(x)
+/** Convert from 64 bit little endian format to CPU format */
+#define woal_le64_to_cpu(x) le64_to_cpu(x)
+/** Convert to 16 bit little endian format from CPU format */
+#define woal_cpu_to_le16(x) cpu_to_le16(x)
+/** Convert to 32 bit little endian format from CPU format */
+#define woal_cpu_to_le32(x) cpu_to_le32(x)
+/** Convert to 64 bit little endian format from CPU format */
+#define woal_cpu_to_le64(x) cpu_to_le64(x)
+#else
+/** Do nothing */
+#define woal_le16_to_cpu(x) x
+/** Do nothing */
+#define woal_le32_to_cpu(x) x
+/** Do nothing */
+#define woal_le64_to_cpu(x) x
+/** Do nothing */
+#define woal_cpu_to_le16(x) x
+/** Do nothing */
+#define woal_cpu_to_le32(x) x
+/** Do nothing */
+#define woal_cpu_to_le64(x) x
+#endif
+
+/** 
+ *  @brief This function returns first available priv
+ *  based on the bss_type
+ *  
+ *  @param handle    A pointer to moal_handle
+ *  @param bss_type  BSS type or MLAN_BSS_TYPE_ANY
+ *
+ *  @return          Pointer to moal_private
+ */
+static inline moal_private *
+woal_get_priv(moal_handle * handle, mlan_bss_type bss_type)
+{
+    int i;
+
+    for (i = 0; i < handle->priv_num; i++) {
+        if (handle->priv[i]) {
+            if (bss_type == MLAN_BSS_TYPE_ANY ||
+                handle->priv[i]->bss_type == bss_type)
+                break;
+        }
+    }
+    return ((i < handle->priv_num) ? handle->priv[i] : NULL);
+}
+
+/** Allocate buffer */
+pmlan_buffer woal_alloc_mlan_buffer(int size);
+/** Allocate IOCTL request buffer */
+pmlan_ioctl_req woal_alloc_mlan_ioctl_req(int size);
+/** Free buffer */
+void woal_free_mlan_buffer(pmlan_buffer pmbuf);
+/** Get private structure of a BSS by index */
+moal_private *woal_bss_num_to_priv(moal_handle * handle, t_u8 bss_num);
+/* Functions in interface module */
+/** Add card */
+moal_handle *woal_add_card(void *card);
+/** Remove card */
+mlan_status woal_remove_card(void *card);
+/** broadcast event */
+mlan_status woal_broadcast_event(moal_private * priv, t_u8 * payload,
+                                 t_u32 len);
+
+/** Interrupt handler */
+void woal_interrupt(moal_handle * handle);
+
+/** Get driver version */
+void woal_get_version(moal_handle * handle, char *version, int maxlen);
+/** Request open */
+mlan_status woal_request_open(moal_private * priv);
+/** Request close */
+mlan_status woal_request_close(moal_private * priv);
+/** Request MAC address setting */
+mlan_status woal_request_set_mac_address(moal_private * priv);
+/** Request multicast list setting */
+void woal_request_set_multicast_list(moal_private * priv,
+                                     struct net_device *dev);
+/** Request IOCTL action */
+mlan_status woal_request_ioctl(moal_private * priv, mlan_ioctl_req * req,
+                               t_u8 wait_option);
+#ifdef PROC_DEBUG
+/** Get debug information */
+mlan_status woal_get_debug_info(moal_private * priv, t_u8 wait_option,
+                                mlan_debug_info * debug_info);
+/** Set debug information */
+mlan_status woal_set_debug_info(moal_private * priv, t_u8 wait_option,
+                                mlan_debug_info * debug_info);
+#endif
+/** Disconnect */
+mlan_status woal_disconnect(moal_private * priv, t_u8 wait_option, t_u8 * mac);
+/** associate */
+mlan_status woal_bss_start(moal_private * priv, t_u8 wait_option,
+                           mlan_ssid_bssid * ssid_bssid);
+/** Get Host Sleep parameters */
+mlan_status woal_get_hs_params(moal_private * priv, t_u8 wait_option,
+                               mlan_ds_hs_cfg * hscfg);
+/** Cancel Host Sleep configuration */
+mlan_status woal_hs_cfg_cancel(moal_private * priv, t_u8 wait_option);
+
+/** set deep sleep */
+int woal_set_deep_sleep(moal_private * priv, t_u8 wait_option,
+                        BOOLEAN bdeep_sleep, t_u16 idletime);
+void woal_send_iwevcustom_event(moal_private * priv, t_s8 * str);
+void woal_send_mic_error_event(moal_private * priv, t_u32 event);
+void woal_process_ioctl_resp(moal_private * priv, mlan_ioctl_req * req);
+/** Request firmware information */
+void woal_request_get_fw_info(moal_private * priv);
+/** Get mode */
+t_u32 woal_get_mode(moal_private * priv, t_u8 wait_option);
+/** Get signal information */
+mlan_status woal_get_signal_info(moal_private * priv, t_u8 wait_option,
+                                 mlan_ds_get_signal * signal);
+/** Get statistics information */
+mlan_status woal_get_stats_info(moal_private * priv, t_u8 wait_option,
+                                mlan_ds_get_stats * stats);
+/** Get data rates */
+mlan_status woal_get_data_rates(moal_private * priv, t_u8 wait_option,
+                                moal_802_11_rates * m_rates);
+/** Get channel list */
+mlan_status woal_get_channel_list(moal_private * priv, t_u8 wait_option,
+                                  mlan_chan_list * chanlist);
+/** Get BSS information */
+mlan_status woal_get_bss_info(moal_private * priv, t_u8 wait_option,
+                              mlan_bss_info * bss_info);
+/** Get scan table */
+mlan_status woal_get_scan_table(moal_private * priv, t_u8 wait_option,
+                                mlan_scan_resp * scanresp);
+/** Set authentication mode */
+mlan_status woal_set_auth_mode(moal_private * priv, t_u8 wait_option,
+                               t_u32 auth_mode);
+/** Get authentication mode */
+mlan_status woal_get_auth_mode(moal_private * priv, t_u8 wait_option,
+                               t_u32 * auth_mode);
+/** Set encryption mode */
+mlan_status woal_set_encrypt_mode(moal_private * priv, t_u8 wait_option,
+                                  t_u32 encrypt_mode);
+/** Get encryption mode */
+mlan_status woal_get_encrypt_mode(moal_private * priv, t_u8 wait_option,
+                                  t_u32 * encrypt_mode);
+/** Enable wep key */
+mlan_status woal_enable_wep_key(moal_private * priv, t_u8 wait_option);
+/** Set WPA enable */
+mlan_status woal_set_wpa_enable(moal_private * priv, t_u8 wait_option,
+                                t_u32 enable);
+/** Get WPA state */
+mlan_status woal_get_wpa_enable(moal_private * priv, t_u8 wait_option,
+                                t_u32 * enable);
+/** Find best network to connect */
+mlan_status woal_find_best_network(moal_private * priv, t_u8 wait_option,
+                                   mlan_ssid_bssid * ssid_bssid);
+/** Request a network scan */
+mlan_status woal_request_scan(moal_private * priv, t_u8 wait_option,
+                              mlan_802_11_ssid * req_ssid);
+/** Set E-Supplicant mode */
+mlan_status woal_set_ewpa_mode(moal_private * priv, t_u8 wait_option,
+                               mlan_ssid_bssid * ssid_bssid);
+/** Set Ad-Hoc channel */
+mlan_status woal_change_adhoc_chan(moal_private * priv, int channel);
+/** Set radio on/off */
+int woal_set_radio(moal_private * priv, t_u8 option);
+
+mlan_status woal_set_wapi_enable(moal_private * priv, t_u8 wait_option,
+                                 t_u32 enable);
+
+/** Initialize priv */
+void woal_init_priv(moal_private * priv);
+mlan_status woal_get_bss_type(struct net_device *dev, struct ifreq *req);
+
+#ifdef CONFIG_PROC_FS
+/** Initialize proc fs */
+void woal_proc_init(moal_handle * handle);
+/** Clean up proc fs */
+void woal_proc_exit(moal_handle * handle);
+/** Create proc entry */
+void woal_create_proc_entry(moal_private * priv);
+/** Remove proc entry */
+void woal_proc_remove(moal_private * priv);
+/** string to number */
+int woal_string_to_number(char *s);
+#endif
+
+#ifdef PROC_DEBUG
+/** Create debug proc fs */
+void woal_debug_entry(moal_private * priv);
+/** Remove debug proc fs */
+void woal_debug_remove(moal_private * priv);
+#endif /* PROC_DEBUG */
+
+#ifdef REASSOCIATION
+int woal_reassociation_thread(void *data);
+void woal_reassoc_timer_func(void *context);
+#endif /* REASSOCIATION */
+
+t_void woal_main_work_queue(struct work_struct *work);
+
+#endif /* _MOAL_MAIN_H */
diff --git a/wlan_src/mlinux/moal_priv.c b/wlan_src/mlinux/moal_priv.c
new file mode 100755
index 0000000..5cadd81
--- /dev/null
+++ b/wlan_src/mlinux/moal_priv.c
@@ -0,0 +1,6998 @@
+/** @file  moal_priv.c
+  *
+  * @brief This file contains standard ioctl functions
+  *
+  * Copyright (C) 2008-2009, Marvell International Ltd.
+  *
+  * This software file (the "File") is distributed by Marvell International
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+  * (the "License").  You may use, redistribute and/or modify this File in
+  * accordance with the terms and conditions of the License, a copy of which
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+  * this warranty disclaimer.
+  *
+  */
+
+/************************************************************************
+Change log:
+    10/30/2008: initial version
+************************************************************************/
+
+#include	"moal_main.h"
+#include	"moal_sdio.h"
+
+/********************************************************
+                Local Variables
+********************************************************/
+/** Bands supported in Infra mode */
+static t_u8 SupportedInfraBand[] = {
+    BAND_B, BAND_B | BAND_G, BAND_G,
+    BAND_GN, BAND_B | BAND_G | BAND_GN, BAND_G | BAND_GN,
+    BAND_A, BAND_B | BAND_A, BAND_B | BAND_G | BAND_A, BAND_G | BAND_A,
+    BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN,
+        BAND_A | BAND_G | BAND_AN | BAND_GN, BAND_A | BAND_AN,
+};
+
+/** Bands supported in Ad-Hoc mode */
+static t_u8 SupportedAdhocBand[] = {
+    BAND_B, BAND_B | BAND_G, BAND_G,
+    BAND_GN, BAND_B | BAND_G | BAND_GN, BAND_G | BAND_GN,
+    BAND_A,
+    BAND_AN, BAND_A | BAND_AN,
+};
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/** Macro for maximum size of scan response buffer */
+#define MAX_SCAN_RSP_BUF (16 * 1024)
+
+/********************************************************
+		Local Functions
+********************************************************/
+/** 
+ *  @brief Handle get info resp 
+ *   
+ *  @param priv 	Pointer to moal_private structure
+ *  @param info 	Pointer to mlan_ds_get_info structure
+ *
+ *  @return    		N/A
+ */
+void
+woal_ioctl_get_info_resp(moal_private * priv, mlan_ds_get_info * info)
+{
+    ENTER();
+    switch (info->sub_command) {
+    case MLAN_OID_GET_STATS:
+        priv->w_stats.discard.fragment = info->param.stats.fcs_error;
+        priv->w_stats.discard.retries = info->param.stats.retry;
+        priv->w_stats.discard.misc = info->param.stats.ack_failure;
+        break;
+    case MLAN_OID_GET_SIGNAL:
+        if (info->param.signal.selector & BCN_RSSI_AVG_MASK)
+            priv->w_stats.qual.level = info->param.signal.bcn_rssi_avg;
+        if (info->param.signal.selector & BCN_NF_AVG_MASK)
+            priv->w_stats.qual.noise = info->param.signal.bcn_nf_avg;
+        break;
+    default:
+        break;
+    }
+    LEAVE();
+}
+
+/** 
+ *  @brief Handle get BSS resp 
+ *   
+ *  @param priv 	Pointer to moal_private structure
+ *  @param bss 		Pointer to mlan_ds_bss structure
+ *
+ *  @return    		N/A
+ */
+void
+woal_ioctl_get_bss_resp(moal_private * priv, mlan_ds_bss * bss)
+{
+    t_u32 mode = 0;
+
+    ENTER();
+
+    switch (bss->sub_command) {
+    case MLAN_OID_BSS_MODE:
+        if (bss->param.bss_mode == MLAN_BSS_MODE_INFRA)
+            mode = IW_MODE_INFRA;
+        else if (bss->param.bss_mode == MLAN_BSS_MODE_IBSS)
+            mode = IW_MODE_ADHOC;
+        else
+            mode = IW_MODE_AUTO;
+        priv->w_stats.status = mode;
+        break;
+    default:
+        break;
+    }
+
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief Copy Rates
+ *   
+ *  @param dest    A pointer to destination buffer
+ *  @param pos     The position for copy
+ *  @param src     A pointer to source buffer
+ *  @param len     Length of the source buffer
+ *
+ *  @return        Number of rates copied 
+ */
+static inline int
+woal_copy_rates(t_u8 * dest, int pos, t_u8 * src, int len)
+{
+    int i;
+
+    for (i = 0; i < len && src[i]; i++, pos++) {
+        if (pos >= MLAN_SUPPORTED_RATES)
+            break;
+        dest[pos] = src[i];
+    }
+    return pos;
+}
+
+/**
+ *  @brief Get Driver Version
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param req          A pointer to ifreq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_get_driver_version(moal_private * priv, struct ifreq *req)
+{
+    struct iwreq *wrq = (struct iwreq *) req;
+    int len;
+    char buf[MLAN_MAX_VER_STR_LEN];
+    ENTER();
+
+    woal_get_version(priv->phandle, buf, sizeof(buf) - 1);
+
+    len = strlen(buf);
+    if (wrq->u.data.pointer) {
+        if (copy_to_user(wrq->u.data.pointer, buf, len)) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            LEAVE();
+            return -EFAULT;
+        }
+        wrq->u.data.length = len;
+    }
+    PRINTM(MINFO, "MOAL VERSION: %s\n", buf);
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Get extended driver version
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param ireq         A pointer to ifreq structure
+ *
+ *  @return             0 --success, otherwise fail  
+ */
+static int
+woal_get_driver_verext(moal_private * priv, struct ifreq *ireq)
+{
+    struct iwreq *wrq = (struct iwreq *) ireq;
+    mlan_ds_get_info *info = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
+    if (req == NULL) {
+        LEAVE();
+        return -ENOMEM;
+    }
+
+    info = (mlan_ds_get_info *) req->pbuf;
+    info->sub_command = MLAN_OID_GET_VER_EXT;
+    req->req_id = MLAN_IOCTL_GET_INFO;
+    req->action = MLAN_ACT_GET;
+
+    if (!wrq->u.data.flags) {
+        info->param.ver_ext.version_str_sel =
+            *((int *) (wrq->u.name + SUBCMD_OFFSET));
+    } else {
+        if (copy_from_user
+            (&info->param.ver_ext.version_str_sel, wrq->u.data.pointer,
+             sizeof(info->param.ver_ext.version_str_sel))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            LEAVE();
+            return -EFAULT;
+        } else {
+            if (info->param.ver_ext.version_str_sel < 0) {
+                PRINTM(MERROR, "Invalid arguments!\n");
+                LEAVE();
+                return -EINVAL;
+            }
+        }
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        LEAVE();
+        return -EFAULT;
+    }
+
+    if (wrq->u.data.pointer) {
+        if (copy_to_user(wrq->u.data.pointer, info->param.ver_ext.version_str,
+                         strlen(info->param.ver_ext.version_str))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            LEAVE();
+            return -EFAULT;
+        }
+        wrq->u.data.length = strlen(info->param.ver_ext.version_str);
+    }
+
+    PRINTM(MINFO, "MOAL EXTENDED VERSION: %s\n",
+           info->param.ver_ext.version_str);
+
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Set Deep Sleep
+ *
+ *  @param priv         Pointer to the moal_private driver data struct
+ *  @param wait_option  wait option
+ *  @param bdeep_sleep  TRUE--enalbe deepsleep, FALSE--disable deepsleep
+ *  @param idletime     Idle time for optimized PS API
+ *
+ *  @return             0 --success, otherwise fail
+ */
+int
+woal_set_deep_sleep(moal_private * priv, t_u8 wait_option, BOOLEAN bdeep_sleep,
+                    t_u16 idletime)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_pm_cfg *pm = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        LEAVE();
+        return -ENOMEM;
+    }
+    pm = (mlan_ds_pm_cfg *) req->pbuf;
+    pm->sub_command = MLAN_OID_PM_CFG_DEEP_SLEEP;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+
+    req->action = MLAN_ACT_SET;
+    if (bdeep_sleep == MTRUE) {
+        PRINTM(MCMND, "Deep Sleep: sleep\n");
+        pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_ON;
+        if (idletime) {
+            pm->param.auto_deep_sleep.idletime = idletime;
+        }
+        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
+            ret = -EFAULT;
+            goto done;
+        }
+    } else {
+        PRINTM(MCMND, "%lu : Deep Sleep: wakeup\n", jiffies);
+        pm->param.auto_deep_sleep.auto_ds = DEEP_SLEEP_OFF;
+
+        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option)) {
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Performs warm reset
+ *
+ *  @param priv         A pointer to moal_private structure
+ *
+ *  @return             0 --success, otherwise fail  
+ */
+static int
+woal_warm_reset(moal_private * priv)
+{
+    int ret = 0;
+    int intf_num;
+    moal_handle *handle = priv->phandle;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_misc_cfg *misc = NULL;
+    mlan_bss_info bss_info;
+
+    ENTER();
+
+    /* Disable interfaces */
+    for (intf_num = 0; intf_num < handle->priv_num; intf_num++) {
+        netif_stop_queue(handle->priv[intf_num]->netdev);
+        netif_device_detach(handle->priv[intf_num]->netdev);
+    }
+
+    /* Exit deep sleep */
+    woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MFALSE, 0);
+
+    memset(&bss_info, 0, sizeof(bss_info));
+    woal_get_bss_info(priv, MOAL_PROC_WAIT, &bss_info);
+    if (bss_info.is_hs_configured) {
+        if (MLAN_STATUS_SUCCESS != woal_hs_cfg_cancel(priv, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+    /* Disconnect from network */
+    for (intf_num = 0; intf_num < handle->priv_num; intf_num++) {
+        if (handle->priv[intf_num]->media_connected == MTRUE) {
+            woal_disconnect(handle->priv[intf_num], MOAL_IOCTL_WAIT, NULL);
+        }
+    }
+
+    /* Initialize private structures */
+    for (intf_num = 0; intf_num < handle->priv_num; intf_num++)
+        woal_init_priv(handle->priv[intf_num]);
+
+#ifdef REASSOCIATION
+    /* Reset the reassoc timer and status */
+    handle->reassoc_on = MFALSE;
+    if (handle->is_reassoc_timer_set == MTRUE) {
+        woal_cancel_timer(&handle->reassoc_timer);
+        handle->is_reassoc_timer_set = MFALSE;
+    }
+#endif
+
+    /* Restart the firmware */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req) {
+        misc = (mlan_ds_misc_cfg *) req->pbuf;
+        misc->sub_command = MLAN_OID_MISC_WARM_RESET;
+        req->req_id = MLAN_IOCTL_MISC_CFG;
+        req->action = MLAN_ACT_SET;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            kfree(req);
+            goto done;
+        }
+        kfree(req);
+    }
+
+    /* Enable interfaces */
+    for (intf_num = 0; intf_num < handle->priv_num; intf_num++) {
+        netif_device_attach(handle->priv[intf_num]->netdev);
+        netif_start_queue(handle->priv[intf_num]->netdev);
+    }
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get signal
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq	        A pointer to iwreq structure
+ *
+ *  @return 	  	0 --success, otherwise fail
+ */
+static int
+woal_get_signal(moal_private * priv, struct iwreq *wrq)
+{
+/** Input data size */
+#define IN_DATA_SIZE	2
+/** Output data size */
+#define OUT_DATA_SIZE	12
+    int ret = 0;
+    int in_data[IN_DATA_SIZE];
+    int out_data[OUT_DATA_SIZE];
+    mlan_ds_get_signal signal;
+    int data_length = 0;
+
+    ENTER();
+
+    memset(in_data, 0, sizeof(in_data));
+    memset(out_data, 0, sizeof(out_data));
+
+    if (priv->media_connected == MFALSE) {
+        PRINTM(MERROR, "Can not get RSSI in disconnected state\n");
+        ret = -ENOTSUPP;
+        goto done;
+    }
+
+    if (wrq->u.data.length) {
+        if (copy_from_user
+            (in_data, wrq->u.data.pointer,
+             sizeof(int) * MIN(wrq->u.data.length, sizeof(in_data)))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+    switch (wrq->u.data.length) {
+    case 0:                    /* No checking, get everything */
+        break;
+    case 2:                    /* Check subtype range */
+        if (in_data[1] < 1 || in_data[1] > 4) {
+            ret = -EINVAL;
+            goto done;
+        }
+        /* Fall through */
+    case 1:                    /* Check type range */
+        if (in_data[0] < 1 || in_data[0] > 3) {
+            ret = -EINVAL;
+            goto done;
+        }
+        break;
+    default:
+        ret = -EINVAL;
+        goto done;
+    }
+
+    memset(&signal, 0, sizeof(mlan_ds_get_signal));
+    if (MLAN_STATUS_SUCCESS !=
+        woal_get_signal_info(priv, MOAL_IOCTL_WAIT, &signal)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    PRINTM(MINFO, "RSSI Beacon Last   : %d\n", (int) signal.bcn_rssi_last);
+    PRINTM(MINFO, "RSSI Beacon Average: %d\n", (int) signal.bcn_rssi_avg);
+    PRINTM(MINFO, "RSSI Data Last     : %d\n", (int) signal.data_rssi_last);
+    PRINTM(MINFO, "RSSI Data Average  : %d\n", (int) signal.data_rssi_avg);
+    PRINTM(MINFO, "SNR Beacon Last    : %d\n", (int) signal.bcn_snr_last);
+    PRINTM(MINFO, "SNR Beacon Average : %d\n", (int) signal.bcn_snr_avg);
+    PRINTM(MINFO, "SNR Data Last      : %d\n", (int) signal.data_snr_last);
+    PRINTM(MINFO, "SNR Data Average   : %d\n", (int) signal.data_snr_avg);
+    PRINTM(MINFO, "NF Beacon Last     : %d\n", (int) signal.bcn_nf_last);
+    PRINTM(MINFO, "NF Beacon Average  : %d\n", (int) signal.bcn_nf_avg);
+    PRINTM(MINFO, "NF Data Last       : %d\n", (int) signal.data_nf_last);
+    PRINTM(MINFO, "NF Data Average    : %d\n", (int) signal.data_nf_avg);
+
+    /* Check type */
+    switch (in_data[0]) {
+    case 0:                    /* Send everything */
+        out_data[data_length++] = signal.bcn_rssi_last;
+        out_data[data_length++] = signal.bcn_rssi_avg;
+        out_data[data_length++] = signal.data_rssi_last;
+        out_data[data_length++] = signal.data_rssi_avg;
+        out_data[data_length++] = signal.bcn_snr_last;
+        out_data[data_length++] = signal.bcn_snr_avg;
+        out_data[data_length++] = signal.data_snr_last;
+        out_data[data_length++] = signal.data_snr_avg;
+        out_data[data_length++] = signal.bcn_nf_last;
+        out_data[data_length++] = signal.bcn_nf_avg;
+        out_data[data_length++] = signal.data_nf_last;
+        out_data[data_length++] = signal.data_nf_avg;
+        break;
+    case 1:                    /* RSSI */
+        /* Check subtype */
+        switch (in_data[1]) {
+        case 0:                /* Everything */
+            out_data[data_length++] = signal.bcn_rssi_last;
+            out_data[data_length++] = signal.bcn_rssi_avg;
+            out_data[data_length++] = signal.data_rssi_last;
+            out_data[data_length++] = signal.data_rssi_avg;
+            break;
+        case 1:                /* bcn last */
+            out_data[data_length++] = signal.bcn_rssi_last;
+            break;
+        case 2:                /* bcn avg */
+            out_data[data_length++] = signal.bcn_rssi_avg;
+            break;
+        case 3:                /* data last */
+            out_data[data_length++] = signal.data_rssi_last;
+            break;
+        case 4:                /* data avg */
+            out_data[data_length++] = signal.data_rssi_avg;
+            break;
+        default:
+            break;
+        }
+        break;
+    case 2:                    /* SNR */
+        /* Check subtype */
+        switch (in_data[1]) {
+        case 0:                /* Everything */
+            out_data[data_length++] = signal.bcn_snr_last;
+            out_data[data_length++] = signal.bcn_snr_avg;
+            out_data[data_length++] = signal.data_snr_last;
+            out_data[data_length++] = signal.data_snr_avg;
+            break;
+        case 1:                /* bcn last */
+            out_data[data_length++] = signal.bcn_snr_last;
+            break;
+        case 2:                /* bcn avg */
+            out_data[data_length++] = signal.bcn_snr_avg;
+            break;
+        case 3:                /* data last */
+            out_data[data_length++] = signal.data_snr_last;
+            break;
+        case 4:                /* data avg */
+            out_data[data_length++] = signal.data_snr_avg;
+            break;
+        default:
+            break;
+        }
+        break;
+    case 3:                    /* NF */
+        /* Check subtype */
+        switch (in_data[1]) {
+        case 0:                /* Everything */
+            out_data[data_length++] = signal.bcn_nf_last;
+            out_data[data_length++] = signal.bcn_nf_avg;
+            out_data[data_length++] = signal.data_nf_last;
+            out_data[data_length++] = signal.data_nf_avg;
+            break;
+        case 1:                /* bcn last */
+            out_data[data_length++] = signal.bcn_nf_last;
+            break;
+        case 2:                /* bcn avg */
+            out_data[data_length++] = signal.bcn_nf_avg;
+            break;
+        case 3:                /* data last */
+            out_data[data_length++] = signal.data_nf_last;
+            break;
+        case 4:                /* data avg */
+            out_data[data_length++] = signal.data_nf_avg;
+            break;
+        default:
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+
+    wrq->u.data.length = data_length;
+    if (copy_to_user(wrq->u.data.pointer, out_data,
+                     wrq->u.data.length * sizeof(out_data[0]))) {
+        PRINTM(MERROR, "Copy to user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get Deep Sleep
+ *
+ *  @param priv         Pointer to the moal_private driver data struct
+ *  @param deep_sleep   Pointer to return deep_sleep setting
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_get_deep_sleep(moal_private * priv, t_u32 * deep_sleep)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_pm_cfg *pm = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        LEAVE();
+        return -ENOMEM;
+    }
+    pm = (mlan_ds_pm_cfg *) req->pbuf;
+    pm->sub_command = MLAN_OID_PM_CFG_DEEP_SLEEP;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+
+    req->action = MLAN_ACT_GET;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    *deep_sleep = pm->param.auto_deep_sleep.auto_ds;
+
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get/Set DeepSleep mode
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wreq	    A pointer to iwreq structure
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_deep_sleep_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    t_u32 deep_sleep = DEEP_SLEEP_OFF;
+    static t_u16 idletime = DEEP_SLEEP_ILDE_TIME;
+    t_u32 data[2];
+
+    ENTER();
+
+    if (wrq->u.data.length == 1 || wrq->u.data.length == 2) {
+        if (copy_from_user
+            (&data, wrq->u.data.pointer, wrq->u.data.length * sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            LEAVE();
+            return -EFAULT;
+        }
+        deep_sleep = data[0];
+        if (deep_sleep == DEEP_SLEEP_OFF) {
+            PRINTM(MINFO, "Exit Deep Sleep Mode\n");
+            woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MFALSE, 0);
+        } else if (deep_sleep == DEEP_SLEEP_ON) {
+            PRINTM(MINFO, "Enter Deep Sleep Mode\n");
+            if (wrq->u.data.length == 2)
+                idletime = data[1];
+            woal_set_deep_sleep(priv, MOAL_IOCTL_WAIT, MTRUE, idletime);
+        } else {
+            PRINTM(MERROR, "Unknown option = %lu\n", deep_sleep);
+            LEAVE();
+            return -EINVAL;
+        }
+    } else if (wrq->u.data.length > 2) {
+        PRINTM(MERROR, "Invalid number of arguments %d\n", wrq->u.data.length);
+        LEAVE();
+        return -EINVAL;
+    } else {                    /* Display Deep Sleep settings */
+        PRINTM(MINFO, "Get Deep Sleep Mode\n");
+        if (MLAN_STATUS_SUCCESS != woal_get_deep_sleep(priv, &deep_sleep)) {
+            LEAVE();
+            return -EFAULT;
+        }
+    }
+
+    /* Copy the Deep Sleep setting to user */
+    if (copy_to_user(wrq->u.data.pointer, &deep_sleep, sizeof(int))) {
+        PRINTM(MERROR, "Copy to user failed\n");
+        LEAVE();
+        return -EINVAL;
+    }
+    wrq->u.data.length = 1;
+
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Set/Get Usr 11n configuration request
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq	    A pointer to iwreq structure
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_11n_htcap_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int data;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_11n_cfg *cfg_11n = NULL;
+    int ret = 0;
+
+    ENTER();
+
+    if (wrq->u.data.length > 1) {
+        PRINTM(MERROR, "Invalid number of arguments\n");
+        ret = -EINVAL;
+        goto done;
+    }
+
+    if (((req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg))) == NULL)) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
+    cfg_11n->sub_command = MLAN_OID_11N_HTCAP_CFG;
+    req->req_id = MLAN_IOCTL_11N_CFG;
+
+    if (wrq->u.data.length == 0) {
+        /* Get 11n tx parameters from MLAN */
+        req->action = MLAN_ACT_GET;
+    } else if (wrq->u.data.length == 1) {
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+
+        cfg_11n->param.htcap_cfg = data;
+        PRINTM(MINFO, "SET: htusrcap:0x%x\n", data);
+        /* Update 11n tx parameters in MLAN */
+        req->action = MLAN_ACT_SET;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    data = cfg_11n->param.htcap_cfg;
+    PRINTM(MINFO, "GET: httxcap:0x%x\n", data);
+
+    if (copy_to_user(wrq->u.data.pointer, &data, sizeof(data))) {
+        PRINTM(MERROR, "Copy to user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    wrq->u.data.length = 1;
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Enable/Disable amsdu_aggr_ctrl
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq	    A pointer to iwreq structure
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_11n_amsdu_aggr_ctrl(moal_private * priv, struct iwreq *wrq)
+{
+    int data[2];
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_11n_cfg *cfg_11n = NULL;
+    int ret = 0;
+
+    ENTER();
+
+    if ((wrq->u.data.length != 0) && (wrq->u.data.length != 1)) {
+        PRINTM(MERROR, "Invalid number of arguments\n");
+        ret = -EINVAL;
+        goto done;
+    }
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
+    cfg_11n->sub_command = MLAN_OID_11N_CFG_AMSDU_AGGR_CTRL;
+    req->req_id = MLAN_IOCTL_11N_CFG;
+
+    if (wrq->u.data.length == 0) {
+        /* Get 11n tx parameters from MLAN */
+        req->action = MLAN_ACT_GET;
+    } else if (wrq->u.data.length == 1) {
+        if (copy_from_user(data, wrq->u.data.pointer,
+                           wrq->u.data.length * sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        cfg_11n->param.amsdu_aggr_ctrl.enable = data[0];
+        /* Update 11n tx parameters in MLAN */
+        req->action = MLAN_ACT_SET;
+    }
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    data[0] = cfg_11n->param.amsdu_aggr_ctrl.enable;
+    data[1] = cfg_11n->param.amsdu_aggr_ctrl.curr_buf_size;
+
+    if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
+        PRINTM(MERROR, "Copy to user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = 2;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get 11n configuration request
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq	    A pointer to iwreq structure
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_11n_tx_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int data;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_11n_cfg *cfg_11n = NULL;
+    int ret = 0;
+
+    ENTER();
+
+    if ((wrq->u.data.length != 0) && (wrq->u.data.length != 1)) {
+        PRINTM(MERROR, "Invalid number of arguments\n");
+        ret = -EINVAL;
+        goto done;
+    }
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
+    cfg_11n->sub_command = MLAN_OID_11N_CFG_TX;
+    req->req_id = MLAN_IOCTL_11N_CFG;
+
+    if (wrq->u.data.length == 0) {
+        /* Get 11n tx parameters from MLAN */
+        req->action = MLAN_ACT_GET;
+    } else if (wrq->u.data.length == 1) {
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(data))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        cfg_11n->param.tx_cfg.httxcap = data;
+        PRINTM(MINFO, "SET: httxcap:%d\n", data);
+        /* Update 11n tx parameters in MLAN */
+        req->action = MLAN_ACT_SET;
+    }
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    data = cfg_11n->param.tx_cfg.httxcap;
+    PRINTM(MINFO, "GET: httxcap:%d\n", data);
+    if (copy_to_user(wrq->u.data.pointer, &data, sizeof(data))) {
+        PRINTM(MERROR, "Copy to user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = 1;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Enable/Disable TX Aggregation
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq	    A pointer to iwreq structure
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_11n_prio_tbl(moal_private * priv, struct iwreq *wrq)
+{
+    int data[MAX_NUM_TID * 2], i, j;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_11n_cfg *cfg_11n = NULL;
+    int ret = 0;
+
+    ENTER();
+
+    if ((wrq->u.data.pointer == NULL)) {
+        LEAVE();
+        return -EINVAL;
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
+    if (req == NULL) {
+        LEAVE();
+        return -ENOMEM;
+    }
+    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
+    cfg_11n->sub_command = MLAN_OID_11N_CFG_AGGR_PRIO_TBL;
+    req->req_id = MLAN_IOCTL_11N_CFG;
+
+    if (wrq->u.data.length == 0) {
+        /* Get aggr priority table from MLAN */
+        req->action = MLAN_ACT_GET;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto error;
+        }
+        wrq->u.data.length = MAX_NUM_TID * 2;
+        for (i = 0, j = 0; i < (wrq->u.data.length); i = i + 2, ++j) {
+            data[i] = cfg_11n->param.aggr_prio_tbl.ampdu[j];
+            data[i + 1] = cfg_11n->param.aggr_prio_tbl.amsdu[j];
+        }
+
+        if (copy_to_user(wrq->u.data.pointer, data,
+                         sizeof(int) * wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto error;
+        }
+    } else if (wrq->u.data.length == 16) {
+        if (copy_from_user(data, wrq->u.data.pointer,
+                           sizeof(int) * wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto error;
+        }
+        for (i = 0, j = 0; i < (wrq->u.data.length); i = i + 2, ++j) {
+            cfg_11n->param.aggr_prio_tbl.ampdu[j] = data[i];
+            cfg_11n->param.aggr_prio_tbl.amsdu[j] = data[i + 1];
+        }
+
+        /* Update aggr priority table in MLAN */
+        req->action = MLAN_ACT_SET;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto error;
+        }
+    } else {
+        PRINTM(MERROR, "Invalid number of arguments\n");
+        ret = -EINVAL;
+        goto error;
+    }
+
+  error:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get add BA Reject paramters
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq	    A pointer to iwreq structure
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_addba_reject(moal_private * priv, struct iwreq *wrq)
+{
+    int data[MAX_NUM_TID], ret = 0, i;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_11n_cfg *cfg_11n = NULL;
+
+    ENTER();
+
+    PRINTM(MERROR, "%s\n", __FUNCTION__);
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
+    if (req == NULL) {
+        LEAVE();
+        return -ENOMEM;
+    }
+    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
+    cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_REJECT;
+    req->req_id = MLAN_IOCTL_11N_CFG;
+
+    if (wrq->u.data.length == 0) {
+        PRINTM(MERROR, "Addba reject moal\n");
+        /* Get aggr priority table from MLAN */
+        req->action = MLAN_ACT_GET;
+        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req,
+                                                      MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto error;
+        }
+
+        wrq->u.data.length = MAX_NUM_TID;
+        for (i = 0; i < (wrq->u.data.length); ++i) {
+            data[i] = cfg_11n->param.addba_reject[i];
+        }
+
+        if (copy_to_user(wrq->u.data.pointer, data,
+                         sizeof(int) * wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto error;
+        }
+    } else if (wrq->u.data.length == 8) {
+        if (copy_from_user(data, wrq->u.data.pointer,
+                           sizeof(int) * wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto error;
+        }
+        for (i = 0; i < (wrq->u.data.length); ++i) {
+            cfg_11n->param.addba_reject[i] = data[i];
+        }
+
+        /* Update aggr priority table in MLAN */
+        req->action = MLAN_ACT_SET;
+        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req,
+                                                      MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto error;
+        }
+    } else {
+        PRINTM(MERROR, "Invalid number of arguments\n");
+        ret = -EINVAL;
+        goto error;
+    }
+  error:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get add BA paramters
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq	    A pointer to iwreq structure
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_addba_para_updt(moal_private * priv, struct iwreq *wrq)
+{
+    int data[3], ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_11n_cfg *cfg_11n = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
+    if (req == NULL) {
+        LEAVE();
+        return -ENOMEM;
+    }
+    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
+    cfg_11n->sub_command = MLAN_OID_11N_CFG_ADDBA_PARAM;
+    req->req_id = MLAN_IOCTL_11N_CFG;
+
+    if (wrq->u.data.length == 0) {
+        /* Get Add BA parameters from MLAN */
+        req->action = MLAN_ACT_GET;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto error;
+        }
+        data[0] = cfg_11n->param.addba_param.timeout;
+        data[1] = cfg_11n->param.addba_param.txwinsize;
+        data[2] = cfg_11n->param.addba_param.rxwinsize;
+        PRINTM(MINFO, "GET: timeout:%d txwinsize:%d rxwinsize:%d\n", data[0],
+               data[1], data[2]);
+
+        wrq->u.data.length = 3;
+        if (copy_to_user(wrq->u.data.pointer, data,
+                         wrq->u.data.length * sizeof(int))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto error;
+        }
+    } else if (wrq->u.data.length == 3) {
+        if (copy_from_user
+            (data, wrq->u.data.pointer, wrq->u.data.length * sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto error;
+        }
+        cfg_11n->param.addba_param.timeout = data[0];
+        cfg_11n->param.addba_param.txwinsize = data[1];
+        cfg_11n->param.addba_param.rxwinsize = data[2];
+        PRINTM(MINFO, "SET: timeout:%d txwinsize:%d rxwinsize:%d\n", data[0],
+               data[1], data[2]);
+
+        /* Update Add BA parameters in MLAN */
+        req->action = MLAN_ACT_SET;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = MLAN_STATUS_FAILURE;
+            goto error;
+        }
+    } else {
+        PRINTM(MERROR, "Invalid number of arguments\n");
+        ret = -EINVAL;
+        goto error;
+    }
+
+  error:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get Transmit buffer size
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq	    A pointer to iwreq structure
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_txbuf_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int buf_size;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_11n_cfg *cfg_11n = NULL;
+    int ret = 0;
+
+    ENTER();
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11n_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    cfg_11n = (mlan_ds_11n_cfg *) req->pbuf;
+    cfg_11n->sub_command = MLAN_OID_11N_CFG_MAX_TX_BUF_SIZE;
+    req->req_id = MLAN_IOCTL_11N_CFG;
+
+    if (wrq->u.data.length == 0) {
+        /* Get Tx buffer size from MLAN */
+        req->action = MLAN_ACT_GET;
+    } else {
+        if (copy_from_user(&buf_size, wrq->u.data.pointer, sizeof(buf_size))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        PRINTM(MINFO, "SET: Tx buffer size %d\n", buf_size);
+        /* Update Tx buffer size in MLAN */
+        req->action = MLAN_ACT_SET;
+        cfg_11n->param.tx_buf_size = buf_size;
+    }
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    buf_size = cfg_11n->param.tx_buf_size;
+    if (copy_to_user(wrq->u.data.pointer, &buf_size, sizeof(buf_size))) {
+        PRINTM(MERROR, "Copy to user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = 1;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get Host Sleep configuration
+ *
+ *  @param priv             A pointer to moal_private structure
+ *  @param wrq	            A pointer to iwreq structure
+ *  @param invoke_hostcmd	MTRUE --invoke HostCmd, otherwise MFALSE
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_hs_cfg(moal_private * priv, struct iwreq *wrq, BOOLEAN invoke_hostcmd)
+{
+    int data[3];
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_pm_cfg *pmcfg = NULL;
+    mlan_ds_hs_cfg hscfg;
+    int data_length = wrq->u.data.length;
+
+    ENTER();
+
+    memset(data, 0, sizeof(data));
+    memset(&hscfg, 0, sizeof(mlan_ds_hs_cfg));
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    pmcfg = (mlan_ds_pm_cfg *) req->pbuf;
+    pmcfg->sub_command = MLAN_OID_PM_CFG_HS_CFG;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+
+    if (data_length == 0) {
+        req->action = MLAN_ACT_GET;
+    } else {
+        req->action = MLAN_ACT_SET;
+        if (data_length >= 1 && data_length <= 3) {
+            if (copy_from_user
+                (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+                PRINTM(MERROR, "Copy from user failed\n");
+                ret = -EFAULT;
+                goto done;
+            }
+        } else {
+            PRINTM(MERROR, "Invalid arguments\n");
+            ret = -EINVAL;
+            goto done;
+        }
+    }
+
+    /* Do a GET first if all arguments are not available */
+    if (data_length >= 1 && data_length < 3) {
+        woal_get_hs_params(priv, MOAL_IOCTL_WAIT, &hscfg);
+    }
+
+    switch (data_length) {
+    case 3:                    /* Conditions, GPIO, GAP provided */
+        pmcfg->param.hs_cfg.conditions = data[0];
+        pmcfg->param.hs_cfg.gpio = data[1];
+        pmcfg->param.hs_cfg.gap = data[2];
+        break;
+    case 2:                    /* Conditions, GPIO provided */
+        pmcfg->param.hs_cfg.conditions = data[0];
+        pmcfg->param.hs_cfg.gpio = data[1];
+        pmcfg->param.hs_cfg.gap = hscfg.gap;
+        break;
+    case 1:                    /* Conditions provided */
+        pmcfg->param.hs_cfg.conditions = data[0];
+        pmcfg->param.hs_cfg.gpio = hscfg.gpio;
+        pmcfg->param.hs_cfg.gap = hscfg.gap;
+        break;
+    case 0:
+        break;
+    default:
+        break;
+    }
+
+    pmcfg->param.hs_cfg.is_invoke_hostcmd = invoke_hostcmd;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (req->action == MLAN_ACT_GET) {
+        data[0] = pmcfg->param.hs_cfg.conditions;
+        data[1] = pmcfg->param.hs_cfg.gpio;
+        data[2] = pmcfg->param.hs_cfg.gap;
+        wrq->u.data.length = 3;
+        if (copy_to_user
+            (wrq->u.data.pointer, data, sizeof(int) * wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set Host Sleep parameters
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq	        A pointer to iwreq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_hs_setpara(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    int data_length = wrq->u.data.length;
+
+    ENTER();
+
+    if (data_length >= 1 && data_length <= 3) {
+        ret = woal_hs_cfg(priv, wrq, MFALSE);
+        goto done;
+    } else {
+        PRINTM(MERROR, "Invalid arguments\n");
+        ret = -EINVAL;
+        goto done;
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get/Set inactivity timeout extend
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq	        A pointer to iwreq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_inactivity_timeout_ext(moal_private * priv, struct iwreq *wrq)
+{
+    int data[4];
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_pm_cfg *pmcfg = NULL;
+    pmlan_ds_inactivity_to inac_to = NULL;
+    int data_length = wrq->u.data.length;
+
+    ENTER();
+
+    memset(data, 0, sizeof(data));
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    pmcfg = (mlan_ds_pm_cfg *) req->pbuf;
+    inac_to = &pmcfg->param.inactivity_to;
+    pmcfg->sub_command = MLAN_OID_PM_CFG_INACTIVITY_TO;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+
+    if ((data_length != 0) && (data_length != 3) && (data_length != 4)) {
+        ret = -EINVAL;
+        goto done;
+    }
+
+    req->action = MLAN_ACT_GET;
+    if (data_length) {
+        if (copy_from_user
+            (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        req->action = MLAN_ACT_SET;
+        inac_to->timeout_unit = data[0];
+        inac_to->unicast_timeout = data[1];
+        inac_to->mcast_timeout = data[2];
+        inac_to->ps_entry_timeout = data[3];
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    /* Copy back current values regardless of GET/SET */
+    data[0] = inac_to->timeout_unit;
+    data[1] = inac_to->unicast_timeout;
+    data[2] = inac_to->mcast_timeout;
+    data[3] = inac_to->ps_entry_timeout;
+
+    if (req->action == MLAN_ACT_GET) {
+        wrq->u.data.length = 4;
+        if (copy_to_user
+            (wrq->u.data.pointer, data, wrq->u.data.length * sizeof(int))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get system clock
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq	        A pointer to iwreq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_ecl_sys_clock(moal_private * priv, struct iwreq *wrq)
+{
+    int data[64];
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_misc_cfg *cfg = NULL;
+    int data_length = wrq->u.data.length;
+    int i = 0;
+
+    ENTER();
+
+    memset(data, 0, sizeof(data));
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    cfg = (mlan_ds_misc_cfg *) req->pbuf;
+    cfg->sub_command = MLAN_OID_MISC_SYS_CLOCK;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+
+    if (!data_length)
+        req->action = MLAN_ACT_GET;
+    else if (data_length <= MLAN_MAX_CLK_NUM) {
+        req->action = MLAN_ACT_SET;
+        if (copy_from_user
+            (data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    } else {
+        PRINTM(MERROR, "Invalid arguments\n");
+        ret = -EINVAL;
+        goto done;
+    }
+
+    if (req->action == MLAN_ACT_GET) {
+        /* Get configurable clocks */
+        cfg->param.sys_clock.sys_clk_type = MLAN_CLK_CONFIGURABLE;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+
+        /* Current system clock */
+        data[0] = (int) cfg->param.sys_clock.cur_sys_clk;
+        wrq->u.data.length = 1;
+
+        data_length = MIN(cfg->param.sys_clock.sys_clk_num, MLAN_MAX_CLK_NUM);
+
+        /* Configurable clocks */
+        for (i = 0; i < data_length; i++) {
+            data[i + wrq->u.data.length] =
+                (int) cfg->param.sys_clock.sys_clk[i];
+        }
+        wrq->u.data.length += data_length;
+
+        /* Get supported clocks */
+        cfg->param.sys_clock.sys_clk_type = MLAN_CLK_SUPPORTED;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+
+        data_length = MIN(cfg->param.sys_clock.sys_clk_num, MLAN_MAX_CLK_NUM);
+
+        /* Supported clocks */
+        for (i = 0; i < data_length; i++) {
+            data[i + wrq->u.data.length] =
+                (int) cfg->param.sys_clock.sys_clk[i];
+        }
+
+        wrq->u.data.length += data_length;
+
+        if (copy_to_user
+            (wrq->u.data.pointer, data, sizeof(int) * wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    } else {
+        /* Set configurable clocks */
+        cfg->param.sys_clock.sys_clk_type = MLAN_CLK_CONFIGURABLE;
+        cfg->param.sys_clock.sys_clk_num = MIN(MLAN_MAX_CLK_NUM, data_length);
+        for (i = 0; i < cfg->param.sys_clock.sys_clk_num; i++) {
+            cfg->param.sys_clock.sys_clk[i] = (t_u16) data[i];
+        }
+
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get Band and Adhoc-band setting
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq	        A pointer to iwreq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_band_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0, i;
+    int data[3];
+    int user_data_len = wrq->u.data.length;
+    t_u32 infra_band = 0;
+    t_u32 adhoc_band = 0;
+    t_u32 adhoc_channel = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_radio_cfg *radio_cfg = NULL;
+
+    ENTER();
+
+    if (user_data_len > 3) {
+        LEAVE();
+        return -EINVAL;
+    }
+
+    if (user_data_len > 0) {
+        if (priv->media_connected == MTRUE) {
+            LEAVE();
+            return -EOPNOTSUPP;
+        }
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto error;
+    }
+    radio_cfg = (mlan_ds_radio_cfg *) req->pbuf;
+    radio_cfg->sub_command = MLAN_OID_BAND_CFG;
+    req->req_id = MLAN_IOCTL_RADIO_CFG;
+
+    if (wrq->u.data.length == 0) {
+        /* Get config_bands, adhoc_start_band and adhoc_channnel values from
+           MLAN */
+        req->action = MLAN_ACT_GET;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto error;
+        }
+        data[0] = radio_cfg->param.band_cfg.config_bands;       /* Infra Band */
+        data[1] = radio_cfg->param.band_cfg.adhoc_start_band;   /* Adhoc Band */
+        data[2] = radio_cfg->param.band_cfg.adhoc_channel;      /* Adhoc
+                                                                   Channel */
+
+        wrq->u.data.length = 3;
+        if (copy_to_user
+            (wrq->u.data.pointer, data, sizeof(int) * wrq->u.data.length)) {
+            ret = -EFAULT;
+            goto error;
+        }
+    } else {
+        if (copy_from_user
+            (data, wrq->u.data.pointer, sizeof(int) * wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto error;
+        }
+
+        /* To support only <b/bg/bgn/n> */
+        infra_band = data[0];
+        for (i = 0; i < sizeof(SupportedInfraBand); i++)
+            if (infra_band == SupportedInfraBand[i])
+                break;
+        if (i == sizeof(SupportedInfraBand)) {
+            ret = -EINVAL;
+            goto error;
+        }
+
+        /* Set Adhoc band */
+        if (user_data_len >= 2) {
+            adhoc_band = data[1];
+            for (i = 0; i < sizeof(SupportedAdhocBand); i++)
+                if (adhoc_band == SupportedAdhocBand[i])
+                    break;
+            if (i == sizeof(SupportedAdhocBand)) {
+                ret = -EINVAL;
+                goto error;
+            }
+        }
+
+        /* Set Adhoc channel */
+        if (user_data_len == 3) {
+            adhoc_channel = data[2];
+            if (adhoc_channel == 0) {
+                /* Check if specified adhoc channel is non-zero */
+                ret = -EINVAL;
+                goto error;
+            }
+        }
+
+        /* Set config_bands and adhoc_start_band values to MLAN */
+        req->action = MLAN_ACT_SET;
+        radio_cfg->param.band_cfg.config_bands = infra_band;
+        radio_cfg->param.band_cfg.adhoc_start_band = adhoc_band;
+        radio_cfg->param.band_cfg.adhoc_channel = adhoc_channel;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto error;
+        }
+    }
+
+  error:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set/Get BCA timeshare
+ *  
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq          A pointer to iwreq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_bca_time_share(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    int data[3];
+    int user_data_len = wrq->u.data.length;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_bca_cfg *bca_cfg = NULL;
+
+    ENTER();
+
+    if (user_data_len != 1 && user_data_len != 3) {
+        PRINTM(MERROR, "Invalid number of parameters\n");
+        LEAVE();
+        return -EINVAL;
+    }
+
+    if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * user_data_len)) {
+        PRINTM(MERROR, "Copy from user failed\n");
+        LEAVE();
+        return -EFAULT;
+    }
+
+    if ((data[0] > TRAFFIC_TYPE_MEDIUMHIGH) && (data[0] != TRAFFIC_TYPE_RESET)) {
+        PRINTM(MERROR, "Invalid traffic_type\n");
+        LEAVE();
+        return -EINVAL;
+    }
+
+    if (user_data_len == 3) {
+        /* Valid Range for timeshare_interval: < 20 ... 60_000 > ms */
+        if (data[1] < MIN_TIMESHARE_INTERVAL ||
+            data[1] > MAX_TIMESHARE_INTERVAL) {
+            PRINTM(MERROR,
+                   "Invalid timeshare_interval Range: < 20 ... 60000 > ms\n");
+            LEAVE();
+            return -EINVAL;
+        }
+        data[1] -= (data[1] % 10);      /* If value is not multiple of 10 then
+                                           take the floor value */
+
+        /* If value is not multiple of 10 then take the floor value */
+        data[2] -= (data[2] % 10);
+        /* Valid Range for timeshare_interval: < 0 ... bt_time > */
+        if (data[2] < 0 || data[2] > data[1]) {
+            PRINTM(MERROR,
+                   "Invalid bt_time  Range: < 0 ... timeshare_interval > ms\n");
+            LEAVE();
+            return -EINVAL;
+        }
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bca_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto error;
+    }
+    bca_cfg = (mlan_ds_bca_cfg *) req->pbuf;
+    bca_cfg->sub_command = MLAN_OID_BCA_TS;
+    req->req_id = MLAN_IOCTL_BCA_CFG;
+    req->action = MLAN_ACT_GET;
+
+    if (user_data_len > 0)
+        bca_cfg->param.bca_ts.traffic_type = data[0];
+    if (user_data_len == 3) {
+        req->action = MLAN_ACT_SET;
+        bca_cfg->param.bca_ts.timeshare_interval = data[1];
+        bca_cfg->param.bca_ts.bt_time = data[2];
+    }
+
+    PRINTM(MINFO, "traffic_type=0x%x", data[0]);
+    if (user_data_len == 3)
+        PRINTM(MINFO, " timeshare_interval=0x%x bt_time=0x%x\n", data[1],
+               data[2]);
+
+    /* Set/Get BCA time share values from MLAN */
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto error;
+    }
+
+    if (user_data_len < 3) {
+        data[0] = bca_cfg->param.bca_ts.traffic_type;
+        data[1] = bca_cfg->param.bca_ts.timeshare_interval;
+        data[2] = bca_cfg->param.bca_ts.bt_time;
+
+        wrq->u.data.length = 3;
+        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto error;
+        }
+    }
+
+  error:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Read/Write adapter registers value 
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq	        A pointer to iwreq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_reg_read_write(moal_private * priv, struct iwreq *wrq)
+{
+    int data[3];
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_reg_mem *reg = NULL;
+    int data_length = wrq->u.data.length;
+
+    ENTER();
+
+    memset(data, 0, sizeof(data));
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    reg = (mlan_ds_reg_mem *) req->pbuf;
+    reg->sub_command = MLAN_OID_REG_RW;
+    req->req_id = MLAN_IOCTL_REG_MEM;
+
+    if (data_length == 2) {
+        req->action = MLAN_ACT_GET;
+    } else if (data_length == 3) {
+        req->action = MLAN_ACT_SET;
+    } else {
+        ret = -EINVAL;
+        goto done;
+    }
+    if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+        PRINTM(MERROR, "Copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    reg->param.reg_rw.type = (t_u32) data[0];
+    reg->param.reg_rw.offset = (t_u32) data[1];
+    if (data_length == 3)
+        reg->param.reg_rw.value = (t_u32) data[2];
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (req->action == MLAN_ACT_GET) {
+        if (copy_to_user
+            (wrq->u.data.pointer, &reg->param.reg_rw.value, sizeof(int))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Read the EEPROM contents of the card 
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq	        A pointer to iwreq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_read_eeprom(moal_private * priv, struct iwreq *wrq)
+{
+    int data[2];
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_reg_mem *reg = NULL;
+    int data_length = wrq->u.data.length;
+
+    ENTER();
+
+    memset(data, 0, sizeof(data));
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    reg = (mlan_ds_reg_mem *) req->pbuf;
+    reg->sub_command = MLAN_OID_EEPROM_RD;
+    req->req_id = MLAN_IOCTL_REG_MEM;
+
+    if (data_length == 2) {
+        req->action = MLAN_ACT_GET;
+    } else {
+        ret = -EINVAL;
+        goto done;
+    }
+    if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+        PRINTM(MERROR, "Copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    reg->param.rd_eeprom.offset = (t_u16) data[0];
+    reg->param.rd_eeprom.byte_count = (t_u16) data[1];
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (req->action == MLAN_ACT_GET) {
+        wrq->u.data.length = reg->param.rd_eeprom.byte_count;
+        if (copy_to_user
+            (wrq->u.data.pointer, reg->param.rd_eeprom.value,
+             wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Read/Write device memory value 
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq	        A pointer to iwreq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_mem_read_write(moal_private * priv, struct iwreq *wrq)
+{
+    t_u32 data[2];
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_reg_mem *reg_mem = NULL;
+    int data_length = wrq->u.data.length;
+
+    ENTER();
+
+    memset(data, 0, sizeof(data));
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_reg_mem));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    reg_mem = (mlan_ds_reg_mem *) req->pbuf;
+    reg_mem->sub_command = MLAN_OID_MEM_RW;
+    req->req_id = MLAN_IOCTL_REG_MEM;
+
+    if (data_length == 1) {
+        PRINTM(MINFO, "MEM_RW: GET\n");
+        req->action = MLAN_ACT_GET;
+    } else if (data_length == 2) {
+        PRINTM(MINFO, "MEM_RW: SET\n");
+        req->action = MLAN_ACT_SET;
+    } else {
+        ret = -EINVAL;
+        goto done;
+    }
+    if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) * data_length)) {
+        PRINTM(MERROR, "Copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    reg_mem->param.mem_rw.addr = (t_u32) data[0];
+    if (data_length == 2)
+        reg_mem->param.mem_rw.value = (t_u32) data[1];
+
+    PRINTM(MINFO, "MEM_RW: Addr=0x%x, Value=0x%x\n",
+           (int) reg_mem->param.mem_rw.addr, (int) reg_mem->param.mem_rw.value);
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (req->action == MLAN_ACT_GET) {
+        if (copy_to_user
+            (wrq->u.data.pointer, &reg_mem->param.mem_rw.value, sizeof(int))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get LOG
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wrq			A pointer to iwreq structure
+ *
+ *  @return 	   	 	0 --success, otherwise fail
+ */
+static int
+woal_get_log(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_get_stats stats;
+    char *buf = NULL;
+
+    ENTER();
+
+    PRINTM(MINFO, " GET STATS\n");
+    if (!(buf = kmalloc(GETLOG_BUFSIZE, GFP_ATOMIC))) {
+        PRINTM(MERROR, "kmalloc failed!\n");
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    memset(&stats, 0, sizeof(mlan_ds_get_stats));
+    if (MLAN_STATUS_SUCCESS !=
+        woal_get_stats_info(priv, MOAL_IOCTL_WAIT, &stats)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (wrq->u.data.pointer) {
+        sprintf(buf, "\n"
+                "mcasttxframe     %lu\n"
+                "failed           %lu\n"
+                "retry            %lu\n"
+                "multiretry       %lu\n"
+                "framedup         %lu\n"
+                "rtssuccess       %lu\n"
+                "rtsfailure       %lu\n"
+                "ackfailure       %lu\n"
+                "rxfrag           %lu\n"
+                "mcastrxframe     %lu\n"
+                "fcserror         %lu\n"
+                "txframe          %lu\n"
+                "wepicverrcnt-1   %lu\n"
+                "wepicverrcnt-2   %lu\n"
+                "wepicverrcnt-3   %lu\n"
+                "wepicverrcnt-4   %lu\n",
+                stats.mcast_tx_frame,
+                stats.failed,
+                stats.retry,
+                stats.multi_retry,
+                stats.frame_dup,
+                stats.rts_success,
+                stats.rts_failure,
+                stats.ack_failure,
+                stats.rx_frag,
+                stats.mcast_rx_frame,
+                stats.fcs_error,
+                stats.tx_frame,
+                stats.wep_icv_error[0],
+                stats.wep_icv_error[1],
+                stats.wep_icv_error[2], stats.wep_icv_error[3]);
+        wrq->u.data.length = strlen(buf) + 1;
+        if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+        }
+    }
+  done:
+    if (buf)
+        kfree(buf);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Deauthenticate
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wrq			A pointer to iwreq structure
+ *
+ *  @return 	   	 	0 --success, otherwise fail
+ */
+static int
+woal_deauth(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    struct sockaddr saddr;
+
+    ENTER();
+    if (wrq->u.data.length) {
+        /* Deauth mentioned BSSID */
+        if (copy_from_user(&saddr, wrq->u.data.pointer, sizeof(saddr))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if (MLAN_STATUS_SUCCESS !=
+            woal_disconnect(priv, MOAL_IOCTL_WAIT, (t_u8 *) saddr.sa_data))
+            ret = -EFAULT;
+    } else {
+        if (MLAN_STATUS_SUCCESS != woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL))
+            ret = -EFAULT;
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get TX power configurations
+ *  
+ *  @param priv     A pointer to moal_private structure
+ *  @param wrq      A pointer to iwreq structure
+ *  
+ *  @return         0 --success, otherwise fail
+ */
+static int
+woal_tx_power_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int data[5], user_data_len;
+    int ret = 0;
+    mlan_bss_info bss_info;
+    mlan_ds_power_cfg *pcfg = NULL;
+    mlan_ioctl_req *req = NULL;
+    ENTER();
+
+    memset(&bss_info, 0, sizeof(bss_info));
+    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+
+    memset(data, 0, sizeof(data));
+    user_data_len = wrq->u.data.length;
+
+    if (user_data_len) {
+        if (copy_from_user
+            (data, wrq->u.data.pointer, sizeof(int) * user_data_len)) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        switch (user_data_len) {
+        case 1:
+            if (data[0] != 0xFF)
+                ret = -EINVAL;
+            break;
+        case 2:
+        case 4:
+            if (data[0] == 0xFF) {
+                ret = -EINVAL;
+                break;
+            }
+            if (data[1] < bss_info.min_power_level) {
+                PRINTM(MERROR,
+                       "The set powercfg rate value %d dBm is out of range (%d dBm-%d dBm)!\n",
+                       data[1], (int) bss_info.min_power_level,
+                       (int) bss_info.max_power_level);
+                ret = -EINVAL;
+                break;
+            }
+            if (user_data_len == 4) {
+                if (data[1] > data[2]) {
+                    PRINTM(MERROR, "Min power should be less than maximum!\n");
+                    ret = -EINVAL;
+                    break;
+                }
+                if (data[3] < 0) {
+                    PRINTM(MERROR, "Step should not less than 0!\n");
+                    ret = -EINVAL;
+                    break;
+                }
+                if (data[2] > bss_info.max_power_level) {
+                    PRINTM(MERROR,
+                           "The set powercfg rate value %d dBm is out of range (%d dBm-%d dBm)!\n",
+                           data[2], (int) bss_info.min_power_level,
+                           (int) bss_info.max_power_level);
+                    ret = -EINVAL;
+                    break;
+                }
+                if (data[3] > data[2] - data[1]) {
+                    PRINTM(MERROR,
+                           "Step should not greater than power difference!\n");
+                    ret = -EINVAL;
+                    break;
+                }
+            }
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        if (ret)
+            goto done;
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_power_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    pcfg = (mlan_ds_power_cfg *) req->pbuf;
+    pcfg->sub_command = MLAN_OID_POWER_CFG_EXT;
+    req->req_id = MLAN_IOCTL_POWER_CFG;
+    if (!user_data_len)
+        req->action = MLAN_ACT_GET;
+    else {
+        req->action = MLAN_ACT_SET;
+        pcfg->param.power_ext.len = user_data_len;
+        memcpy((t_u8 *) & pcfg->param.power_ext.power_data, (t_u8 *) data,
+               sizeof(data));
+    }
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (!user_data_len) {
+        if (copy_to_user
+            (wrq->u.data.pointer, (t_u8 *) & pcfg->param.power_ext.power_data,
+             sizeof(int) * pcfg->param.power_ext.len)) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = pcfg->param.power_ext.len;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get Tx/Rx data rates
+ *  
+ *  @param priv     A pointer to moal_private structure
+ *  @param wrq      A pointer to iwreq structure
+ *  
+ *  @return         0 --success, otherwise fail
+ */
+static int
+woal_get_txrx_rate(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_rate *rate = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    rate = (mlan_ds_rate *) req->pbuf;
+    rate->sub_command = MLAN_OID_GET_DATA_RATE;
+    req->req_id = MLAN_IOCTL_RATE;
+    req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (copy_to_user
+        (wrq->u.data.pointer, (t_u8 *) & rate->param.data_rate,
+         sizeof(int) * 2)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = 2;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Turn on/off the sdio clock
+ *  
+ *  @param priv     A pointer to moal_private structure
+ *  @param wrq      A pointer to iwreq structure
+ *  
+ *  @return         0 --success, otherwise fail
+ */
+static int
+woal_sdio_clock_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    int data = 2;
+    /* Initialize the clock state as on */
+    static int clock_state = 1;
+
+    ENTER();
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    } else {
+        wrq->u.data.length = sizeof(clock_state) / sizeof(int);
+        if (copy_to_user(wrq->u.data.pointer, &clock_state, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+
+        goto done;
+    }
+    switch (data) {
+    case CMD_DISABLED:
+        PRINTM(MINFO, "SDIO clock is turned off\n");
+        ret = woal_sdio_set_bus_clock(priv->phandle, MFALSE);
+        clock_state = data;
+        break;
+    case CMD_ENABLED:
+        PRINTM(MINFO, "SDIO clock is turned on\n");
+        ret = woal_sdio_set_bus_clock(priv->phandle, MTRUE);
+        clock_state = data;
+        break;
+    default:
+        ret = -EINVAL;
+        PRINTM(MINFO, "sdioclock: wrong parameter\n");
+        break;
+    }
+  done:
+    return ret;
+}
+
+/**
+ *  @brief Set/Get beacon interval
+ *  
+ *  @param priv     A pointer to moal_private structure
+ *  @param wrq      A pointer to iwreq structure
+ *  
+ *  @return         0 --success, otherwise fail
+ */
+static int
+woal_beacon_interval(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_bss *bss = NULL;
+    mlan_ioctl_req *req = NULL;
+    int bcn = 0;
+
+    ENTER();
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(&bcn, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if ((bcn < MLAN_MIN_BEACON_INTERVAL) ||
+            (bcn > MLAN_MAX_BEACON_INTERVAL)) {
+            ret = -EINVAL;
+            goto done;
+        }
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_IBSS_BCN_INTERVAL;
+    req->req_id = MLAN_IOCTL_BSS;
+    if (!wrq->u.data.length)
+        req->action = MLAN_ACT_GET;
+    else {
+        req->action = MLAN_ACT_SET;
+        bss->param.bcn_interval = bcn;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (copy_to_user
+        (wrq->u.data.pointer, (t_u8 *) & bss->param.bcn_interval,
+         sizeof(int))) {
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = 1;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get ATIM window
+ *  
+ *  @param priv     A pointer to moal_private structure
+ *  @param wrq      A pointer to iwreq structure
+ *  
+ *  @return         0 --success, otherwise fail
+ */
+static int
+woal_atim_window(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_bss *bss = NULL;
+    mlan_ioctl_req *req = NULL;
+    int atim = 0;
+
+    ENTER();
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(&atim, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if ((atim < 0) || (atim > MLAN_MAX_ATIM_WINDOW)) {
+            ret = -EINVAL;
+            goto done;
+        }
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_IBSS_ATIM_WINDOW;
+    req->req_id = MLAN_IOCTL_BSS;
+    if (!wrq->u.data.length)
+        req->action = MLAN_ACT_GET;
+    else {
+        req->action = MLAN_ACT_SET;
+        bss->param.atim_window = atim;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (copy_to_user
+        (wrq->u.data.pointer, (t_u8 *) & bss->param.atim_window, sizeof(int))) {
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = 1;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * @brief Set/Get TX data rate
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return           0 --success, otherwise fail
+ */
+static int
+woal_set_get_txrate(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_rate *rate = NULL;
+    mlan_ioctl_req *req = NULL;
+    int rateindex = 0;
+
+    ENTER();
+    if (wrq->u.data.length) {
+        if (copy_from_user(&rateindex, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    rate = (mlan_ds_rate *) req->pbuf;
+    rate->param.rate_cfg.rate_type = MLAN_RATE_INDEX;
+    rate->sub_command = MLAN_OID_RATE_CFG;
+    req->req_id = MLAN_IOCTL_RATE;
+    if (!wrq->u.data.length)
+        req->action = MLAN_ACT_GET;
+    else {
+        req->action = MLAN_ACT_SET;
+        if (rateindex == AUTO_RATE)
+            rate->param.rate_cfg.is_rate_auto = 1;
+        else {
+            if ((rateindex != MLAN_RATE_INDEX_MCS32) &&
+                ((rateindex < 0) || (rateindex > MLAN_RATE_INDEX_MCS7))) {
+                ret = -EINVAL;
+                goto done;
+            }
+        }
+        rate->param.rate_cfg.rate = rateindex;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    } else {
+        if (wrq->u.data.length)
+            priv->rate_index = rateindex;
+    }
+    if (!wrq->u.data.length) {
+        if (rate->param.rate_cfg.is_rate_auto)
+            rateindex = AUTO_RATE;
+        else
+            rateindex = rate->param.rate_cfg.rate;
+        wrq->u.data.length = 1;
+        if (copy_to_user(wrq->u.data.pointer, &rateindex, sizeof(int))) {
+            ret = -EFAULT;
+        }
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * @brief Set/Get region code
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return           0 --success, otherwise fail
+ */
+static int
+woal_set_get_regioncode(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_misc_cfg *cfg = NULL;
+    mlan_ioctl_req *req = NULL;
+    int region = 0;
+
+    ENTER();
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(&region, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    cfg = (mlan_ds_misc_cfg *) req->pbuf;
+    cfg->sub_command = MLAN_OID_MISC_REGION;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+    if (!wrq->u.data.length)
+        req->action = MLAN_ACT_GET;
+    else {
+        req->action = MLAN_ACT_SET;
+        cfg->param.region_code = region;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (!wrq->u.data.length) {
+        wrq->u.data.length = 1;
+        if (copy_to_user
+            (wrq->u.data.pointer, &cfg->param.region_code, sizeof(int)))
+            ret = -EFAULT;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * @brief Set/Get radio
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return           0 --success, otherwise fail
+ */
+static int
+woal_set_get_radio(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_bss_info bss_info;
+    int option = 0;
+
+    ENTER();
+
+    memset(&bss_info, 0, sizeof(bss_info));
+
+    if (wrq->u.data.length) {
+        /* Set radio */
+        if (copy_from_user(&option, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if (MLAN_STATUS_SUCCESS != woal_set_radio(priv, (t_u8) option))
+            ret = -EFAULT;
+    } else {
+        /* Get radio status */
+        woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+        wrq->u.data.length = 1;
+        if (copy_to_user
+            (wrq->u.data.pointer, &bss_info.radio_on,
+             sizeof(bss_info.radio_on))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+        }
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+#ifdef DEBUG_LEVEL1
+/** 
+ *  @brief Get/Set the bit mask of driver debug message control
+ *
+ *  @param priv			A pointer to moal_private structure
+ *  @param wrq			A pointer to wrq structure
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_drv_dbg(moal_private * priv, struct iwreq *wrq)
+{
+    int data[4];
+    int ret = 0;
+
+    ENTER();
+
+    if (!wrq->u.data.length) {
+        data[0] = drvdbg;
+        data[1] = ifdbg;
+        /* Return the current driver debug bit masks */
+        if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto drvdbgexit;
+        }
+        wrq->u.data.length = 2;
+    } else if (wrq->u.data.length < 3) {
+        /* Get the driver debug bit masks */
+        if (copy_from_user
+            (data, wrq->u.data.pointer, sizeof(int) * wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto drvdbgexit;
+        }
+        drvdbg = data[0];
+        if (wrq->u.data.length == 2)
+            ifdbg = data[1];
+    } else {
+        PRINTM(MERROR, "Invalid parameter number\n");
+        goto drvdbgexit;
+    }
+
+    printk(KERN_ALERT "drvdbg = 0x%08lx\n", drvdbg);
+#ifdef DEBUG_LEVEL2
+    printk(KERN_ALERT "MINFO  (%08lx) %s\n", MINFO,
+           (drvdbg & MINFO) ? "X" : "");
+    printk(KERN_ALERT "MWARN  (%08lx) %s\n", MWARN,
+           (drvdbg & MWARN) ? "X" : "");
+    printk(KERN_ALERT "MENTRY (%08lx) %s\n", MENTRY,
+           (drvdbg & MENTRY) ? "X" : "");
+#endif
+    printk(KERN_ALERT "MFW_D  (%08lx) %s\n", MFW_D,
+           (drvdbg & MFW_D) ? "X" : "");
+    printk(KERN_ALERT "MCMD_D (%08lx) %s\n", MCMD_D,
+           (drvdbg & MCMD_D) ? "X" : "");
+    printk(KERN_ALERT "MDAT_D (%08lx) %s\n", MDAT_D,
+           (drvdbg & MDAT_D) ? "X" : "");
+    printk(KERN_ALERT "MINTR  (%08lx) %s\n", MINTR,
+           (drvdbg & MINTR) ? "X" : "");
+    printk(KERN_ALERT "MEVENT (%08lx) %s\n", MEVENT,
+           (drvdbg & MEVENT) ? "X" : "");
+    printk(KERN_ALERT "MCMND  (%08lx) %s\n", MCMND,
+           (drvdbg & MCMND) ? "X" : "");
+    printk(KERN_ALERT "MDATA  (%08lx) %s\n", MDATA,
+           (drvdbg & MDATA) ? "X" : "");
+    printk(KERN_ALERT "MERROR (%08lx) %s\n", MERROR,
+           (drvdbg & MERROR) ? "X" : "");
+    printk(KERN_ALERT "MFATAL (%08lx) %s\n", MFATAL,
+           (drvdbg & MFATAL) ? "X" : "");
+    printk(KERN_ALERT "MMSG   (%08lx) %s\n", MMSG, (drvdbg & MMSG) ? "X" : "");
+    printk(KERN_ALERT "ifdbg = 0x%08lx\n", ifdbg);
+    printk(KERN_ALERT "MIF_D  (%08lx) %s\n", MIF_D, (ifdbg & MIF_D) ? "X" : "");
+
+  drvdbgexit:
+    LEAVE();
+    return ret;
+}
+#endif /* DEBUG_LEVEL1 */
+
+/**
+ * @brief Set/Get Tx/Rx antenna
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_set_get_tx_rx_ant(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_radio_cfg *radio = NULL;
+    mlan_ioctl_req *req = NULL;
+    int data = 0;
+
+    ENTER();
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    radio = (mlan_ds_radio_cfg *) req->pbuf;
+    radio->sub_command = MLAN_OID_ANT_CFG;
+    req->req_id = MLAN_IOCTL_RADIO_CFG;
+    if (wrq->u.data.length) {
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        req->action = MLAN_ACT_SET;
+        radio->param.antenna = data;
+    } else
+        req->action = MLAN_ACT_GET;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (!wrq->u.data.length) {
+        data = radio->param.antenna;
+        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * @brief Set/Get QoS configuration
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_set_get_qos_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_wmm_cfg *cfg = NULL;
+    mlan_ioctl_req *req = NULL;
+    int data = 0;
+
+    ENTER();
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    cfg = (mlan_ds_wmm_cfg *) req->pbuf;
+    cfg->sub_command = MLAN_OID_WMM_CFG_QOS;
+    req->req_id = MLAN_IOCTL_WMM_CFG;
+    if (wrq->u.data.length) {
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        req->action = MLAN_ACT_SET;
+        cfg->param.qos_cfg = (t_u8) data;
+    } else
+        req->action = MLAN_ACT_GET;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (!wrq->u.data.length) {
+        data = (int) cfg->param.qos_cfg;
+        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * @brief Set/Get LDO configuration
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_set_get_ldo_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_misc_cfg *cfg = NULL;
+    mlan_ioctl_req *req = NULL;
+    int data = 0;
+
+    ENTER();
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    cfg = (mlan_ds_misc_cfg *) req->pbuf;
+    cfg->sub_command = MLAN_OID_MISC_LDO;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+    if (wrq->u.data.length) {
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if (data != LDO_INTERNAL && data != LDO_EXTERNAL) {
+            PRINTM(MERROR, "Invalid parameter, LDO config not changed\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        req->action = MLAN_ACT_SET;
+        cfg->param.ldo_cfg = (t_u16) data;
+    } else
+        req->action = MLAN_ACT_GET;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (!wrq->u.data.length) {
+        data = (int) cfg->param.ldo_cfg;
+        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * @brief Set/Get WWS mode
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_wws_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_misc_cfg *wws = NULL;
+    mlan_ioctl_req *req = NULL;
+    int data = 0;
+
+    ENTER();
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    wws = (mlan_ds_misc_cfg *) req->pbuf;
+    wws->sub_command = MLAN_OID_MISC_WWS;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+    if (wrq->u.data.length) {
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if (data != CMD_DISABLED && data != CMD_ENABLED) {
+            ret = -EINVAL;
+            goto done;
+        }
+        req->action = MLAN_ACT_SET;
+        wws->param.wws_cfg = data;
+    } else
+        req->action = MLAN_ACT_GET;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (!wrq->u.data.length) {
+        data = wws->param.wws_cfg;
+        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * @brief Set/Get sleep period
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_sleep_pd(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_pm_cfg *pm_cfg = NULL;
+    mlan_ioctl_req *req = NULL;
+    int data = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    pm_cfg = (mlan_ds_pm_cfg *) req->pbuf;
+    pm_cfg->sub_command = MLAN_OID_PM_CFG_SLEEP_PD;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+    if (wrq->u.data.length) {
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if ((data <= MAX_SLEEP_PERIOD && data >= MIN_SLEEP_PERIOD) ||
+            (data == 0)
+            || (data == SLEEP_PERIOD_RESERVED_FF)
+            ) {
+            req->action = MLAN_ACT_SET;
+            pm_cfg->param.sleep_period = data;
+        } else {
+            ret = -EINVAL;
+            goto done;
+        }
+    } else
+        req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (!wrq->u.data.length) {
+        data = pm_cfg->param.sleep_period;
+        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * @brief Configuer sleep parameters
+ *
+ * @param priv         A pointer to moal_private structure
+ * @param req          A pointer to ifreq structure
+ *
+ * @return             0 --success, otherwise fail  
+ */
+static int
+woal_sleep_params_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_pm_cfg *pm = NULL;
+    mlan_ds_sleep_params *psleep_params = NULL;
+    int data[6] = { 0 }, i;
+#ifdef DEBUG_LEVEL1
+    char err_str[][35] = { {"sleep clock error in ppm"},
+    {"wakeup offset in usec"},
+    {"clock stabilization time in usec"},
+    {"value of reserved for debug"}
+    };
+#endif
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        LEAVE();
+        return -ENOMEM;
+    }
+
+    pm = (mlan_ds_pm_cfg *) req->pbuf;
+    pm->sub_command = MLAN_OID_PM_CFG_SLEEP_PARAMS;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+    psleep_params = (pmlan_ds_sleep_params) & pm->param.sleep_params;
+
+    if (wrq->u.data.length == 0) {
+        req->action = MLAN_ACT_GET;
+    } else if (wrq->u.data.length == 6) {
+        if (copy_from_user(data, wrq->u.data.pointer, sizeof(int) *
+                           wrq->u.data.length)) {
+            /* copy_from_user failed */
+            PRINTM(MERROR, "S_PARAMS: copy from user failed\n");
+            return -EINVAL;
+        }
+#define MIN_VAL 0x0000
+#define MAX_VAL 0xFFFF
+        for (i = 0; i < 6; i++) {
+            if ((i == 3) || (i == 4)) {
+                /* These two cases are handled below the loop */
+                continue;
+            }
+            if (data[i] < MIN_VAL || data[i] > MAX_VAL) {
+                PRINTM(MERROR, "Invalid %s (0-65535)!\n", err_str[i]);
+                ret = -EINVAL;
+                goto done;
+            }
+        }
+        if (data[3] < 0 || data[3] > 2) {
+            PRINTM(MERROR, "Invalid control periodic calibration (0-2)!\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        if (data[4] < 0 || data[4] > 2) {
+            PRINTM(MERROR, "Invalid control of external sleep clock (0-2)!\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        req->action = MLAN_ACT_SET;
+        psleep_params->error = data[0];
+        psleep_params->offset = data[1];
+        psleep_params->stable_time = data[2];
+        psleep_params->cal_control = data[3];
+        psleep_params->ext_sleep_clk = data[4];
+        psleep_params->reserved = data[5];
+    } else {
+        ret = -EINVAL;
+        goto done;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    data[0] = psleep_params->error;
+    data[1] = psleep_params->offset;
+    data[2] = psleep_params->stable_time;
+    data[3] = psleep_params->cal_control;
+    data[4] = psleep_params->ext_sleep_clk;
+    data[5] = psleep_params->reserved;
+    wrq->u.data.length = 6;
+
+    if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) *
+                     wrq->u.data.length)) {
+        PRINTM(MERROR, "QCONFIG: copy to user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+#ifdef REASSOCIATION
+/**
+ * @brief Set/Get reassociation settings
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_set_get_reassoc(moal_private * priv, struct iwreq *wrq)
+{
+    moal_handle *handle = priv->phandle;
+    int ret = 0;
+    int data = 0;
+
+    ENTER();
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if (data == 0) {
+            handle->reassoc_on = MFALSE;
+            if (handle->is_reassoc_timer_set == MTRUE) {
+                woal_cancel_timer(&handle->reassoc_timer);
+                handle->is_reassoc_timer_set = MFALSE;
+            }
+        } else
+            handle->reassoc_on = MTRUE;
+    } else {
+        data = (int) handle->reassoc_on;
+        if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+
+  done:
+    LEAVE();
+    return ret;
+}
+#endif /* REASSOCIATION */
+
+/**
+ *  @brief implement WMM enable command
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq      Pointer to user data
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_wmm_enable_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_wmm_cfg *wmm = NULL;
+    mlan_ioctl_req *req = NULL;
+    int data = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    wmm = (mlan_ds_wmm_cfg *) req->pbuf;
+    req->req_id = MLAN_IOCTL_WMM_CFG;
+    wmm->sub_command = MLAN_OID_WMM_CFG_ENABLE;
+
+    if (wrq->u.data.length) {
+        /* Set WMM configuration */
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if ((data < CMD_DISABLED) || (data > CMD_ENABLED)) {
+            ret = -EINVAL;
+            goto done;
+        }
+        req->action = MLAN_ACT_SET;
+        if (data == CMD_DISABLED)
+            wmm->param.wmm_enable = MFALSE;
+        else
+            wmm->param.wmm_enable = MTRUE;
+    } else {
+        /* Get WMM status */
+        req->action = MLAN_ACT_GET;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (wrq->u.data.pointer) {
+        if (copy_to_user
+            (wrq->u.data.pointer, &wmm->param.wmm_enable,
+             sizeof(wmm->param.wmm_enable))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Implement 802.11D enable command
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq      Pointer to user data
+ *
+ *  @return         0 --success, otherwise fail
+ */
+static int
+woal_11d_enable_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_11d_cfg *pcfg_11d = NULL;
+    mlan_ioctl_req *req = NULL;
+    int data = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_11d_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    pcfg_11d = (mlan_ds_11d_cfg *) req->pbuf;
+    req->req_id = MLAN_IOCTL_11D_CFG;
+    pcfg_11d->sub_command = MLAN_OID_11D_CFG_ENABLE;
+    if (wrq->u.data.length) {
+        /* Set 11D configuration */
+        if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if ((data < CMD_DISABLED) || (data > CMD_ENABLED)) {
+            ret = -EINVAL;
+            goto done;
+        }
+        if (data == CMD_DISABLED)
+            pcfg_11d->param.enable_11d = MFALSE;
+        else
+            pcfg_11d->param.enable_11d = MTRUE;
+        req->action = MLAN_ACT_SET;
+    } else {
+        req->action = MLAN_ACT_GET;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (wrq->u.data.pointer) {
+        if (copy_to_user
+            (wrq->u.data.pointer, &pcfg_11d->param.enable_11d,
+             sizeof(pcfg_11d->param.enable_11d))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    }
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Control WPS Session Enable/Disable
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq      Pointer to user data
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_wps_cfg_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_wps_cfg *pwps = NULL;
+    mlan_ioctl_req *req = NULL;
+    char buf[8];
+    struct iwreq *wreq = (struct iwreq *) wrq;
+
+    ENTER();
+
+    PRINTM(MINFO, "WOAL_WPS_SESSION\n");
+
+    memset(buf, 0, sizeof(buf));
+    if (copy_from_user(buf, wreq->u.data.pointer,
+                       MIN(sizeof(buf) - 1, wreq->u.data.length))) {
+        PRINTM(MERROR, "Copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wps_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    pwps = (mlan_ds_wps_cfg *) req->pbuf;
+    req->req_id = MLAN_IOCTL_WPS_CFG;
+    req->action = MLAN_ACT_SET;
+    pwps->sub_command = MLAN_OID_WPS_CFG_SESSION;
+    if (buf[0] == 1)
+        pwps->param.wps_session = MLAN_WPS_CFG_SESSION_START;
+    else
+        pwps->param.wps_session = MLAN_WPS_CFG_SESSION_END;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Convert ascii string to Hex integer
+ *     
+ *  @param d                    A pointer to integer buf
+ *  @param s			A pointer to ascii string 
+ *  @param dlen			The length o fascii string
+ *
+ *  @return 	   	        Number of integer  
+ */
+static int
+woal_ascii2hex(t_u8 * d, char *s, t_u32 dlen)
+{
+    int i;
+    t_u8 n;
+
+    ENTER();
+
+    memset(d, 0x00, dlen);
+
+    for (i = 0; i < dlen * 2; i++) {
+        if ((s[i] >= 48) && (s[i] <= 57))
+            n = s[i] - 48;
+        else if ((s[i] >= 65) && (s[i] <= 70))
+            n = s[i] - 55;
+        else if ((s[i] >= 97) && (s[i] <= 102))
+            n = s[i] - 87;
+        else
+            break;
+        if (!(i % 2))
+            n = n * 16;
+        d[i / 2] += n;
+    }
+
+    LEAVE();
+    return i;
+}
+
+/** 
+ *  @brief Return hex value of a give character
+ *
+ *  @param chr	    Character to be converted
+ *
+ *  @return 	    The converted chanrater if chr is a valid hex, else 0
+ */
+static int
+woal_hexval(char chr)
+{
+    ENTER();
+
+    if (chr >= '0' && chr <= '9')
+        return chr - '0';
+    if (chr >= 'A' && chr <= 'F')
+        return chr - 'A' + 10;
+    if (chr >= 'a' && chr <= 'f')
+        return chr - 'a' + 10;
+
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Return hex value of a given ascii string
+ *
+ *  @param a	    String to be converted to ascii
+ *
+ *  @return 	    The converted chanrater if a is a valid hex, else 0
+ */
+static int
+woal_atox(char *a)
+{
+    int i = 0;
+
+    ENTER();
+
+    while (isxdigit(*a))
+        i = i * 16 + woal_hexval(*a++);
+
+    LEAVE();
+    return i;
+}
+
+/** 
+ *  @brief Extension of strsep lib command. This function will also take care
+ *	   escape character
+ *
+ *  @param s         A pointer to array of chars to process
+ *  @param delim     The delimiter character to end the string
+ *  @param esc       The escape character to ignore for delimiter
+ *
+ *  @return          Pointer to the seperated string if delim found, else NULL
+ */
+static char *
+woal_strsep(char **s, char delim, char esc)
+{
+    char *se = *s, *sb;
+
+    ENTER();
+
+    if (!(*s) || (*se == '\0')) {
+        LEAVE();
+        return NULL;
+    }
+
+    for (sb = *s; *sb != '\0'; ++sb) {
+        if (*sb == esc && *(sb + 1) == esc) {
+            /* 
+             * We get a esc + esc seq then keep the one esc
+             * and chop off the other esc character
+             */
+            memmove(sb, sb + 1, strlen(sb));
+            continue;
+        }
+        if (*sb == esc && *(sb + 1) == delim) {
+            /* 
+             * We get a delim + esc seq then keep the delim
+             * and chop off the esc character
+             */
+            memmove(sb, sb + 1, strlen(sb));
+            continue;
+        }
+        if (*sb == delim)
+            break;
+    }
+
+    if (*sb == '\0')
+        sb = NULL;
+    else
+        *sb++ = '\0';
+
+    *s = sb;
+
+    LEAVE();
+    return se;
+}
+
+/**
+ *  @brief Convert mac address from string to t_u8 buffer.
+ *
+ *  @param mac_addr The buffer to store the mac address in.	    
+ *  @param buf      The source of mac address which is a string.	    
+ *
+ *  @return 	    N/A
+ */
+static void
+woal_mac2u8(t_u8 * mac_addr, char *buf)
+{
+    char *begin = buf, *end;
+    int i;
+
+    ENTER();
+
+    for (i = 0; i < ETH_ALEN; ++i) {
+        end = woal_strsep(&begin, ':', '/');
+        if (end)
+            mac_addr[i] = woal_atox(end);
+    }
+
+    LEAVE();
+}
+
+/**
+ *  @brief Set WPA passphrase and SSID
+ *
+ *  @param priv	    A pointer to moal_private structure
+ *  @param wrq	    A pointer to user data
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_passphrase(moal_private * priv, struct iwreq *wrq)
+{
+    t_u16 len = 0;
+    static char buf[256];
+    char *begin, *end, *opt;
+    int ret = 0, action = -1, i;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_ioctl_req *req = NULL;
+    t_u8 zero_mac[] = { 0, 0, 0, 0, 0, 0 };
+    t_u8 *mac = NULL;
+
+    ENTER();
+
+    if (!wrq->u.data.length) {
+        PRINTM(MERROR, "Argument missing for setpassphrase\n");
+        ret = -EINVAL;
+        goto done;
+    }
+
+    if (copy_from_user(buf, wrq->u.data.pointer, wrq->u.data.length)) {
+        PRINTM(MERROR, "Copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    buf[wrq->u.data.length] = '\0';
+
+    if (wrq->u.data.length <= 1) {
+        PRINTM(MERROR, "No valid arguments\n");
+        ret = -EINVAL;
+        goto done;
+    }
+    /* Parse the buf to get the cmd_action */
+    begin = buf;
+    end = woal_strsep(&begin, ';', '/');
+    if (end)
+        action = woal_atox(end);
+    if (action < 0 || action > 2 || end[1] != '\0') {
+        PRINTM(MERROR, "Invalid action argument %s\n", end);
+        ret = -EINVAL;
+        goto done;
+    }
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_PASSPHRASE;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    if (action == 0)
+        req->action = MLAN_ACT_GET;
+    else
+        req->action = MLAN_ACT_SET;
+    while (begin) {
+        end = woal_strsep(&begin, ';', '/');
+        opt = woal_strsep(&end, '=', '/');
+        if (!opt || !end || !end[0]) {
+            PRINTM(MERROR, "Invalid option\n");
+            ret = -EINVAL;
+            break;
+        } else if (!strnicmp(opt, "ssid", strlen(opt))) {
+            if (strlen(end) > MLAN_MAX_SSID_LENGTH) {
+                PRINTM(MERROR, "SSID length exceeds max length\n");
+                ret = -EFAULT;
+                break;
+            }
+            sec->param.passphrase.ssid.ssid_len = strlen(end);
+            strcpy((char *) sec->param.passphrase.ssid.ssid, end);
+            PRINTM(MINFO, "ssid=%s, len=%d\n", sec->param.passphrase.ssid.ssid,
+                   (int) sec->param.passphrase.ssid.ssid_len);
+        } else if (!strnicmp(opt, "bssid", strlen(opt))) {
+            woal_mac2u8((t_u8 *) & sec->param.passphrase.bssid, end);
+        } else if (!strnicmp(opt, "psk", strlen(opt)) &&
+                   req->action == MLAN_ACT_SET) {
+            if (strlen(end) != (MLAN_MAX_PMK_LENGTH * 2)) {
+                PRINTM(MERROR, "Invalid PMK length\n");
+                ret = -EINVAL;
+                break;
+            }
+            woal_ascii2hex(sec->param.passphrase.psk.pmk.pmk, end,
+                           MLAN_MAX_PMK_LENGTH * 2);
+            sec->param.passphrase.psk_type = MLAN_PSK_PMK;
+        } else if (!strnicmp(opt, "passphrase", strlen(opt)) &&
+                   req->action == MLAN_ACT_SET) {
+            if (strlen(end) < MLAN_MIN_PASSPHRASE_LENGTH ||
+                strlen(end) > MLAN_MAX_PASSPHRASE_LENGTH) {
+                PRINTM(MERROR, "Invalid length for passphrase\n");
+                ret = -EINVAL;
+                break;
+            }
+            sec->param.passphrase.psk_type = MLAN_PSK_PASSPHRASE;
+            strcpy(sec->param.passphrase.psk.passphrase.passphrase, end);
+            sec->param.passphrase.psk.passphrase.passphrase_len = strlen(end);
+            PRINTM(MINFO, "passphrase=%s, len=%d\n",
+                   sec->param.passphrase.psk.passphrase.passphrase,
+                   (int) sec->param.passphrase.psk.passphrase.passphrase_len);
+        } else {
+            PRINTM(MERROR, "Invalid option %s\n", opt);
+            ret = -EINVAL;
+            break;
+        }
+    }
+    if (ret)
+        goto done;
+
+    if (action == 2)
+        sec->param.passphrase.psk_type = MLAN_PSK_CLEAR;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (action == 0) {
+        memset(buf, 0, sizeof(buf));
+        if (sec->param.passphrase.ssid.ssid_len) {
+            len += sprintf(buf + len, "ssid:");
+            memcpy(buf + len, sec->param.passphrase.ssid.ssid,
+                   sec->param.passphrase.ssid.ssid_len);
+            len += sec->param.passphrase.ssid.ssid_len;
+            len += sprintf(buf + len, " ");
+        }
+        if (memcmp(&sec->param.passphrase.bssid, zero_mac, sizeof(zero_mac))) {
+            mac = (t_u8 *) & sec->param.passphrase.bssid;
+            len += sprintf(buf + len, "bssid:");
+            for (i = 0; i < ETH_ALEN - 1; ++i)
+                len += sprintf(buf + len, "%02x:", mac[i]);
+            len += sprintf(buf + len, "%02x ", mac[i]);
+        }
+        if (sec->param.passphrase.psk_type == MLAN_PSK_PMK) {
+            len += sprintf(buf + len, "psk:");
+            for (i = 0; i < MLAN_MAX_PMK_LENGTH; ++i)
+                len +=
+                    sprintf(buf + len, "%02x",
+                            sec->param.passphrase.psk.pmk.pmk[i]);
+            len += sprintf(buf + len, "\n");
+        }
+        if (sec->param.passphrase.psk_type == MLAN_PSK_PASSPHRASE) {
+            len +=
+                sprintf(buf + len, "passphrase:%s \n",
+                        sec->param.passphrase.psk.passphrase.passphrase);
+        }
+        if (wrq->u.data.pointer) {
+            if (copy_to_user(wrq->u.data.pointer, buf, len)) {
+                PRINTM(MERROR, "Copy to user failed, len %d\n", len);
+                ret = -EFAULT;
+                goto done;
+            }
+            wrq->u.data.length = len;
+        }
+
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get esupp mode
+ *  
+ *  @param priv     A pointer to moal_private structure
+ *  @param wrq      A pointer to iwreq structure
+ *  
+ *  @return         0 --success, otherwise fail
+ */
+static int
+woal_get_esupp_mode(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_ESUPP_MODE;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (copy_to_user
+        (wrq->u.data.pointer, (t_u8 *) & sec->param.esupp_mode,
+         sizeof(int) * 3)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = 3;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/** AES key length */
+#define AES_KEY_LEN 16
+/**
+ *  @brief Adhoc AES control 
+ *
+ *  @param priv	    A pointer to moal_private structure
+ *  @param wrq	    A pointer to user data
+ *
+ *  @return 	    0 --success, otherwise fail
+ */
+static int
+woal_adhoc_aes_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    static char buf[256];
+    int ret = 0, action = -1, i;
+    t_u8 key_ascii[32];
+    t_u8 key_hex[16];
+    t_u8 *tmp;
+    mlan_bss_info bss_info;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    memset(key_ascii, 0x00, sizeof(key_ascii));
+    memset(key_hex, 0x00, sizeof(key_hex));
+
+    /* Get current BSS information */
+    memset(&bss_info, 0, sizeof(bss_info));
+    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+    if (bss_info.bss_mode != MLAN_BSS_MODE_IBSS ||
+        bss_info.media_connected == MTRUE) {
+        PRINTM(MERROR, "STA is connected or not in IBSS mode.\n");
+        ret = -EOPNOTSUPP;
+        goto done;
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(buf, wrq->u.data.pointer, wrq->u.data.length)) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        buf[wrq->u.data.length] = '\0';
+
+        if (wrq->u.data.length == 1) {
+            /* Get Adhoc AES Key */
+            req->req_id = MLAN_IOCTL_SEC_CFG;
+            req->action = MLAN_ACT_GET;
+            sec = (mlan_ds_sec_cfg *) req->pbuf;
+            sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
+            sec->param.encrypt_key.key_len = AES_KEY_LEN;
+            sec->param.encrypt_key.key_index = 0x40000000;
+            if (MLAN_STATUS_SUCCESS !=
+                woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+                ret = -EFAULT;
+                goto done;
+            }
+
+            memcpy(key_hex, sec->param.encrypt_key.key_material,
+                   sizeof(key_hex));
+            HEXDUMP("Adhoc AES Key (HEX)", key_hex, sizeof(key_hex));
+
+            wrq->u.data.length = sizeof(key_ascii) + 1;
+
+            tmp = key_ascii;
+            for (i = 0; i < sizeof(key_hex); i++)
+                tmp += sprintf((char *) tmp, "%02x", key_hex[i]);
+        } else if (wrq->u.data.length >= 2) {
+            /* Parse the buf to get the cmd_action */
+            action = woal_atox(&buf[0]);
+            if (action < 1 || action > 2) {
+                PRINTM(MERROR, "Invalid action argument %d\n", action);
+                ret = -EINVAL;
+                goto done;
+            }
+
+            req->req_id = MLAN_IOCTL_SEC_CFG;
+            req->action = MLAN_ACT_SET;
+            sec = (mlan_ds_sec_cfg *) req->pbuf;
+            sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
+
+            if (action == 1) {
+                /* Set Adhoc AES Key */
+                memcpy(key_ascii, &buf[2], sizeof(key_ascii));
+                woal_ascii2hex(key_hex, (char *) key_ascii, sizeof(key_hex));
+                HEXDUMP("Adhoc AES Key (HEX)", key_hex, sizeof(key_hex));
+
+                sec->param.encrypt_key.key_len = AES_KEY_LEN;
+                sec->param.encrypt_key.key_index = 0x40000000;
+                memcpy(sec->param.encrypt_key.key_material,
+                       key_hex, sec->param.encrypt_key.key_len);
+
+                if (MLAN_STATUS_SUCCESS !=
+                    woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+                    ret = -EFAULT;
+                    goto done;
+                }
+            } else if (action == 2) {
+                /* Clear Adhoc AES Key */
+                sec->param.encrypt_key.key_len = AES_KEY_LEN;
+                sec->param.encrypt_key.key_index = 0x40000000;
+                memset(sec->param.encrypt_key.key_material, 0,
+                       sizeof(sec->param.encrypt_key.key_material));
+
+                if (MLAN_STATUS_SUCCESS !=
+                    woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+                    ret = -EFAULT;
+                    goto done;
+                }
+            } else {
+                PRINTM(MERROR, "Invalid argument\n");
+                ret = -EINVAL;
+                goto done;
+            }
+        }
+
+        HEXDUMP("Adhoc AES Key (ASCII)", key_ascii, sizeof(key_ascii));
+        wrq->u.data.length = sizeof(key_ascii);
+        if (wrq->u.data.pointer) {
+            if (copy_to_user(wrq->u.data.pointer, &key_ascii,
+                             sizeof(key_ascii))) {
+                PRINTM(MERROR, "copy_to_user failed\n");
+                ret = -EFAULT;
+                goto done;
+            }
+        }
+    }
+
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+#ifdef MFG_CMD_SUPPORT
+/** 
+ *  @brief Manufacturing command ioctl function
+ *   
+ *  @param priv		A pointer to moal_private structure
+ *  @param wrq 		A pointer to iwreq structure
+ *  @return    		0 --success, otherwise fail
+ */
+static int
+woal_mfg_command(moal_private * priv, struct iwreq *wrq)
+{
+    HostCmd_Header cmd_header;
+    int ret = 0;
+    mlan_ds_misc_cfg *misc = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    misc = (mlan_ds_misc_cfg *) req->pbuf;
+    memset(&cmd_header, 0, sizeof(cmd_header));
+
+    /* get MFG command header */
+    if (copy_from_user
+        (&cmd_header, wrq->u.data.pointer, sizeof(HostCmd_Header))) {
+        PRINTM(MERROR, "copy from user failed: MFG command header\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    misc->param.mfgcmd.len = cmd_header.size;
+
+    PRINTM(MINFO, "MFG command len = %lu\n", misc->param.mfgcmd.len);
+
+    if (cmd_header.size > MLAN_SIZE_OF_CMD_BUFFER) {
+        ret = -EINVAL;
+        goto done;
+    }
+
+    /* get the whole command from user */
+    if (copy_from_user
+        (misc->param.mfgcmd.cmd, wrq->u.data.pointer, cmd_header.size)) {
+        PRINTM(MERROR, "copy from user failed: MFG command\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    misc->sub_command = MLAN_OID_MISC_MFG_CMD;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+    req->action = MLAN_ACT_SET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (copy_to_user
+        (wrq->u.data.pointer, (t_u8 *) misc->param.mfgcmd.cmd,
+         MIN(cmd_header.size, misc->param.mfgcmd.len))) {
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = MIN(cmd_header.size, misc->param.mfgcmd.len);
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+#endif /* MFG_CMD_SUPPORT */
+
+/** 
+ *  @brief host command ioctl function
+ *   
+ *  @param priv		A pointer to moal_private structure
+ *  @param wrq 		A pointer to iwreq structure
+ *  @return    		0 --success, otherwise fail
+ */
+static int
+woal_host_command(moal_private * priv, struct iwreq *wrq)
+{
+    HostCmd_Header cmd_header;
+    int ret = 0;
+    mlan_ds_misc_cfg *misc = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    misc = (mlan_ds_misc_cfg *) req->pbuf;
+    memset(&cmd_header, 0, sizeof(cmd_header));
+
+    /* get command header */
+    if (copy_from_user
+        (&cmd_header, wrq->u.data.pointer, sizeof(HostCmd_Header))) {
+        PRINTM(MERROR, "copy from user failed: Host command header\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    misc->param.hostcmd.len = woal_le16_to_cpu(cmd_header.size);
+
+    PRINTM(MINFO, "Host command len = %lu\n", misc->param.hostcmd.len);
+
+    if (woal_le16_to_cpu(cmd_header.size) > MLAN_SIZE_OF_CMD_BUFFER) {
+        ret = -EINVAL;
+        goto done;
+    }
+
+    /* get the whole command from user */
+    if (copy_from_user
+        (misc->param.hostcmd.cmd, wrq->u.data.pointer,
+         woal_le16_to_cpu(cmd_header.size))) {
+        PRINTM(MERROR, "copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    misc->sub_command = MLAN_OID_MISC_HOST_CMD;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (copy_to_user
+        (wrq->u.data.pointer, (t_u8 *) misc->param.hostcmd.cmd,
+         misc->param.hostcmd.len)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = misc->param.hostcmd.len;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief arpfilter ioctl function
+ *   
+ *  @param priv		A pointer to moal_private structure
+ *  @param wrq 		A pointer to iwreq structure
+ *  @return    		0 --success, otherwise fail
+ */
+static int
+woal_arp_filter(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ds_misc_cfg *misc = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    misc = (mlan_ds_misc_cfg *) req->pbuf;
+    misc->sub_command = MLAN_OID_MISC_GEN_IE;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+    req->action = MLAN_ACT_SET;
+    misc->param.gen_ie.type = MLAN_IE_TYPE_ARP_FILTER;
+    misc->param.gen_ie.len = wrq->u.data.length;
+
+    /* get the whole command from user */
+    if (copy_from_user
+        (misc->param.gen_ie.ie_data, wrq->u.data.pointer, wrq->u.data.length)) {
+        PRINTM(MERROR, "copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Create a brief scan resp to relay basic BSS info to the app layer
+ *
+ *  When the beacon/probe response has not been buffered, use the saved BSS
+ *    information available to provide a minimum response for the application
+ *    ioctl retrieval routines.  Include:
+ *        - Timestamp
+ *        - Beacon Period
+ *        - Capabilities (including WMM Element if available)
+ *        - SSID
+ *
+ *  @param ppbuffer  Output parameter: Buffer used to create basic scan rsp
+ *  @param pbss_desc Pointer to a BSS entry in the scan table to create
+ *                   scan response from for delivery to the application layer
+ *
+ *  @return          void
+ */
+static void
+wlan_scan_create_brief_table_entry(t_u8 ** ppbuffer,
+                                   BSSDescriptor_t * pbss_desc)
+{
+    t_u8 *ptmp_buf = *ppbuffer;
+    t_u8 tmp_ssid_hdr[2];
+    t_u8 ie_len = 0;
+
+    if (copy_to_user(ptmp_buf, pbss_desc->time_stamp,
+                     sizeof(pbss_desc->time_stamp))) {
+        PRINTM(MINFO, "Copy to user failed\n");
+        return;
+    }
+    ptmp_buf += sizeof(pbss_desc->time_stamp);
+
+    if (copy_to_user(ptmp_buf, &pbss_desc->beacon_period,
+                     sizeof(pbss_desc->beacon_period))) {
+        PRINTM(MINFO, "Copy to user failed\n");
+        return;
+    }
+    ptmp_buf += sizeof(pbss_desc->beacon_period);
+
+    if (copy_to_user
+        (ptmp_buf, &pbss_desc->cap_info, sizeof(pbss_desc->cap_info))) {
+        PRINTM(MINFO, "Copy to user failed\n");
+        return;
+    }
+    ptmp_buf += sizeof(pbss_desc->cap_info);
+
+    tmp_ssid_hdr[0] = 0;        /* Element ID for SSID is zero */
+    tmp_ssid_hdr[1] = pbss_desc->ssid.ssid_len;
+    if (copy_to_user(ptmp_buf, tmp_ssid_hdr, sizeof(tmp_ssid_hdr))) {
+        PRINTM(MINFO, "Copy to user failed\n");
+        return;
+    }
+    ptmp_buf += sizeof(tmp_ssid_hdr);
+
+    if (copy_to_user(ptmp_buf, pbss_desc->ssid.ssid, pbss_desc->ssid.ssid_len)) {
+        PRINTM(MINFO, "Copy to user failed\n");
+        return;
+    }
+    ptmp_buf += pbss_desc->ssid.ssid_len;
+
+    if (pbss_desc->wmm_ie.vend_hdr.element_id == WMM_IE) {
+        ie_len = sizeof(IEEEtypes_Header_t) + pbss_desc->wmm_ie.vend_hdr.len;
+        if (copy_to_user(ptmp_buf, &pbss_desc->wmm_ie, ie_len)) {
+            PRINTM(MINFO, "Copy to user failed\n");
+            return;
+        }
+
+        ptmp_buf += ie_len;
+    }
+
+    if (pbss_desc->pwpa_ie) {
+        if ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE) {
+            ie_len =
+                sizeof(IEEEtypes_Header_t) +
+                (*(pbss_desc->pwpa_ie)).vend_hdr.len;
+            if (copy_to_user(ptmp_buf, pbss_desc->pwpa_ie, ie_len)) {
+                PRINTM(MINFO, "Copy to user failed\n");
+                return;
+            }
+        }
+
+        ptmp_buf += ie_len;
+    }
+
+    if (pbss_desc->prsn_ie) {
+        if ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id == RSN_IE) {
+            ie_len =
+                sizeof(IEEEtypes_Header_t) +
+                (*(pbss_desc->prsn_ie)).ieee_hdr.len;
+            if (copy_to_user(ptmp_buf, pbss_desc->prsn_ie, ie_len)) {
+                PRINTM(MINFO, "Copy to user failed\n");
+                return;
+            }
+        }
+
+        ptmp_buf += ie_len;
+    }
+
+    *ppbuffer = ptmp_buf;
+}
+
+/** 
+ *  @brief Create a wlan_ioctl_get_scan_table_entry for a given BSS 
+ *         Descriptor for inclusion in the ioctl response to the user space
+ *         application.
+ *
+ *
+ *  @param pbss_desc   Pointer to a BSS entry in the scan table to form
+ *                     scan response from for delivery to the application layer
+ *  @param ppbuffer    Output parameter: Buffer used to output scan return struct
+ *  @param pspace_left Output parameter: Number of bytes available in the 
+ *                     response buffer.
+ *
+ *  @return MLAN_STATUS_SUCCESS, or < 0 with IOCTL error code
+ */
+static int
+wlan_get_scan_table_ret_entry(BSSDescriptor_t * pbss_desc,
+                              t_u8 ** ppbuffer, int *pspace_left)
+{
+    wlan_ioctl_get_scan_table_entry *prsp_entry;
+    wlan_ioctl_get_scan_table_entry tmp_rsp_entry;
+    int space_needed;
+    t_u8 *pcurrent;
+    int variable_size;
+
+    const int fixed_size = (sizeof(tmp_rsp_entry.fixed_field_length)
+                            + sizeof(tmp_rsp_entry.fixed_fields)
+                            + sizeof(tmp_rsp_entry.bss_info_length));
+
+    ENTER();
+
+    pcurrent = *ppbuffer;
+
+    /* The variable size returned is the stored beacon size */
+    variable_size = pbss_desc->beacon_buf_size;
+
+    /* If we stored a beacon and its size was zero, set the variable size
+       return value to the size of the brief scan response
+       wlan_scan_create_brief_table_entry creates.  Also used if we are not
+       configured to store beacons in the first place */
+    if (!variable_size) {
+        variable_size = pbss_desc->ssid.ssid_len + 2;
+        variable_size += (sizeof(pbss_desc->beacon_period)
+                          + sizeof(pbss_desc->time_stamp)
+                          + sizeof(pbss_desc->cap_info));
+        if (pbss_desc->wmm_ie.vend_hdr.element_id == WMM_IE) {
+            variable_size += (sizeof(IEEEtypes_Header_t)
+                              + pbss_desc->wmm_ie.vend_hdr.len);
+        }
+
+        if (pbss_desc->pwpa_ie) {
+            if ((*(pbss_desc->pwpa_ie)).vend_hdr.element_id == WPA_IE) {
+                variable_size += (sizeof(IEEEtypes_Header_t)
+                                  + (*(pbss_desc->pwpa_ie)).vend_hdr.len);
+            }
+        }
+
+        if (pbss_desc->prsn_ie) {
+            if ((*(pbss_desc->prsn_ie)).ieee_hdr.element_id == RSN_IE) {
+                variable_size += (sizeof(IEEEtypes_Header_t)
+                                  + (*(pbss_desc->prsn_ie)).ieee_hdr.len);
+            }
+        }
+    }
+
+    space_needed = fixed_size + variable_size;
+
+    PRINTM(MINFO, "GetScanTable: need(%d), left(%d)\n",
+           space_needed, *pspace_left);
+
+    if (space_needed >= *pspace_left) {
+        *pspace_left = 0;
+        LEAVE();
+        return -E2BIG;
+    }
+
+    *pspace_left -= space_needed;
+
+    tmp_rsp_entry.fixed_field_length = sizeof(prsp_entry->fixed_fields);
+
+    memcpy(tmp_rsp_entry.fixed_fields.bssid,
+           pbss_desc->mac_address, sizeof(prsp_entry->fixed_fields.bssid));
+
+    tmp_rsp_entry.fixed_fields.rssi = pbss_desc->rssi;
+    tmp_rsp_entry.fixed_fields.channel = pbss_desc->channel;
+    tmp_rsp_entry.fixed_fields.network_tsf = pbss_desc->network_tsf;
+    tmp_rsp_entry.bss_info_length = variable_size;
+
+    /* 
+     *  Copy fixed fields to user space
+     */
+    if (copy_to_user(pcurrent, &tmp_rsp_entry, fixed_size)) {
+        PRINTM(MINFO, "Copy to user failed\n");
+        LEAVE();
+        return -EFAULT;
+    }
+
+    pcurrent += fixed_size;
+
+    if (pbss_desc->pbeacon_buf) {
+        /* 
+         *  Copy variable length elements to user space
+         */
+        if (copy_to_user(pcurrent, pbss_desc->pbeacon_buf,
+                         pbss_desc->beacon_buf_size)) {
+            PRINTM(MINFO, "Copy to user failed\n");
+            LEAVE();
+            return -EFAULT;
+        }
+
+        pcurrent += pbss_desc->beacon_buf_size;
+    } else {
+        wlan_scan_create_brief_table_entry(&pcurrent, pbss_desc);
+    }
+
+    *ppbuffer = pcurrent;
+
+    LEAVE();
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/**
+ *  @brief Retrieve the scan response/beacon table
+ *
+ *  @param wrq          A pointer to iwreq structure
+ *  @param scan_resp    A pointer to mlan_scan_resp structure
+ *  @param scan_start   argument
+ *
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static int
+moal_ret_get_scan_table_ioctl(struct iwreq *wrq, mlan_scan_resp * scan_resp,
+                              t_u32 scan_start)
+{
+    pBSSDescriptor_t pbss_desc, scan_table;
+    mlan_scan_resp *prsp_info;
+    int ret_code;
+    int ret_len;
+    int space_left;
+    t_u8 *pcurrent;
+    t_u8 *pbuffer_end;
+    t_u32 num_scans_done;
+
+    ENTER();
+
+    num_scans_done = 0;
+    ret_code = MLAN_STATUS_SUCCESS;
+
+    prsp_info = (mlan_scan_resp *) wrq->u.data.pointer;
+    prsp_info->pscan_table =
+        (t_u8 *) prsp_info + sizeof(prsp_info->num_in_scan_table);
+    pcurrent = prsp_info->pscan_table;
+
+    pbuffer_end = wrq->u.data.pointer + wrq->u.data.length - 1;
+    space_left = pbuffer_end - pcurrent;
+    scan_table = (BSSDescriptor_t *) (scan_resp->pscan_table);
+
+    PRINTM(MINFO, "GetScanTable: scan_start req = %ld\n", scan_start);
+    PRINTM(MINFO, "GetScanTable: length avail = %d\n", wrq->u.data.length);
+
+    if (!scan_start) {
+        PRINTM(MINFO, "GetScanTable: get current BSS Descriptor\n");
+
+        /* Use to get current association saved descriptor */
+        pbss_desc = scan_table;
+
+        ret_code = wlan_get_scan_table_ret_entry(pbss_desc,
+                                                 &pcurrent, &space_left);
+
+        if (ret_code == MLAN_STATUS_SUCCESS) {
+            num_scans_done = 1;
+        }
+    } else {
+        scan_start--;
+
+        while (space_left
+               && (scan_start + num_scans_done < scan_resp->num_in_scan_table)
+               && (ret_code == MLAN_STATUS_SUCCESS)) {
+
+            pbss_desc = (scan_table + (scan_start + num_scans_done));
+
+            PRINTM(MINFO, "GetScanTable: get current BSS Descriptor [%ld]\n",
+                   scan_start + num_scans_done);
+
+            ret_code = wlan_get_scan_table_ret_entry(pbss_desc,
+                                                     &pcurrent, &space_left);
+
+            if (ret_code == MLAN_STATUS_SUCCESS) {
+                num_scans_done++;
+            }
+        }
+    }
+
+    prsp_info->num_in_scan_table = num_scans_done;
+    ret_len = pcurrent - (t_u8 *) wrq->u.data.pointer;
+
+    wrq->u.data.length = ret_len;
+
+    /* Return ret_code (EFAULT or E2BIG) in the case where no scan results were 
+       successfully encoded. */
+    LEAVE();
+    return (num_scans_done ? MLAN_STATUS_SUCCESS : ret_code);
+}
+
+/** 
+ *  @brief Get scan table ioctl
+ *
+ *  @param priv     A pointer to moal_private structure
+ *  @param wrq 		A pointer to iwreq structure
+ *
+ *  @return         MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+static mlan_status
+woal_get_scan_table_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_scan *scan = NULL;
+    t_u32 scan_start;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    scan = (mlan_ds_scan *) req->pbuf;
+    req->req_id = MLAN_IOCTL_SCAN;
+    req->action = MLAN_ACT_GET;
+
+    /* get the whole command from user */
+    if (copy_from_user(&scan_start, wrq->u.data.pointer, sizeof(scan_start))) {
+        PRINTM(MERROR, "copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    if (scan_start) {
+        scan->sub_command = MLAN_OID_SCAN_NORMAL;
+    } else {
+        scan->sub_command = MLAN_OID_SCAN_SPECIFIC_SSID;
+    }
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+    if (status == MLAN_STATUS_SUCCESS) {
+        status = moal_ret_get_scan_table_ioctl(wrq,
+                                               &scan->param.scan_resp,
+                                               scan_start);
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set user scan
+ *
+ *  @param priv     A pointer to moal_private structure
+ *  @param wrq 		A pointer to iwreq structure
+ *
+ *  @return         MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+static mlan_status
+woal_set_user_scan_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_scan *scan = NULL;
+    union iwreq_data wrqu;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan) + wrq->u.data.length);
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    scan = (mlan_ds_scan *) req->pbuf;
+    scan->sub_command = MLAN_OID_SCAN_USER_CONFIG;
+    req->req_id = MLAN_IOCTL_SCAN;
+    req->action = MLAN_ACT_SET;
+
+    if (copy_from_user(scan->param.user_scan.scan_cfg_buf,
+                       wrq->u.data.pointer, wrq->u.data.length)) {
+        PRINTM(MINFO, "Copy from user failed\n");
+        LEAVE();
+        return -EFAULT;
+    }
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
+    if (status == MLAN_STATUS_SUCCESS) {
+        memset(&wrqu, 0, sizeof(union iwreq_data));
+        wireless_send_event(priv->netdev, SIOCGIWSCAN, &wrqu, NULL);
+    } else {
+    }
+
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Cmd52 read/write register
+ *   
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq          A pointer to iwreq structure
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static int
+woal_cmd52rdwr_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    t_u8 buf[7];
+    t_u8 rw, func, data = 0;
+    int reg, ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    if (copy_from_user(buf, wrq->u.data.pointer,
+                       MIN(wrq->u.data.length, sizeof(buf)))) {
+        PRINTM(MINFO, "Copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    rw = buf[0];
+    func = buf[1];
+    reg = buf[5];
+    reg = (reg << 8) + buf[4];
+    reg = (reg << 8) + buf[3];
+    reg = (reg << 8) + buf[2];
+    if (rw)
+        data = buf[6];
+
+    PRINTM(MINFO, "rw=%d, func=%d, reg=0x%08X, data=0x%02X\n", rw, func, reg,
+           data);
+
+    if (!rw) {
+        sdio_claim_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
+        data =
+            sdio_readb(((struct sdio_mmc_card *) priv->phandle->card)->func,
+                       reg, &ret);
+        sdio_release_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
+        if (ret) {
+            PRINTM(MERROR, "sdio_readb: reading register 0x%X failed\n", reg);
+            goto done;
+        }
+    } else {
+        sdio_claim_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
+        sdio_writeb(((struct sdio_mmc_card *) priv->phandle->card)->func, data,
+                    reg, &ret);
+        sdio_release_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
+        if (ret) {
+            PRINTM(MERROR, "sdio_writeb: writing register 0x%X failed\n", reg);
+            goto done;
+        }
+    }
+
+    if (copy_to_user(wrq->u.data.pointer, &data, sizeof(data))) {
+        PRINTM(MINFO, "Copy to user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Cmd53 read/write register
+ *     
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq          A pointer to iwreq structure
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static int
+woal_cmd53rdwr_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    t_u8 *buf = NULL;
+    t_u8 rw, func, mode;
+    t_u16 blklen = 0, blknum = 0;
+    int reg = 0, pattern_len = 0, total_len = 0, pos = 0, ret =
+        MLAN_STATUS_SUCCESS;
+    t_u8 *data = NULL;
+
+    ENTER();
+
+    if (!(buf = (t_u8 *) kmalloc(WOAL_2K_BYTES, GFP_ATOMIC))) {
+        PRINTM(MERROR, "Cannot allocate buffer for command!\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    if (!(data = (t_u8 *) kmalloc(WOAL_2K_BYTES, GFP_ATOMIC))) {
+        PRINTM(MERROR, "Cannot allocate buffer for command!\n");
+        ret = -EFAULT;
+        goto done;
+    }
+    if (wrq->u.data.length > WOAL_2K_BYTES) {
+        PRINTM(MERROR, "Data lengh is too large!\n");
+        ret = -EINVAL;
+        goto done;
+    }
+    if (copy_from_user(buf, wrq->u.data.pointer, wrq->u.data.length)) {
+        PRINTM(MINFO, "Copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    rw = buf[0];                /* read/write (0/1) */
+    func = buf[1];              /* func (0/1/2) */
+    reg = buf[5];               /* address */
+    reg = (reg << 8) + buf[4];
+    reg = (reg << 8) + buf[3];
+    reg = (reg << 8) + buf[2];
+    mode = buf[6];              /* byte mode/block mode (0/1) */
+    blklen = buf[8];            /* block size */
+    blklen = (blklen << 8) + buf[7];
+    blknum = buf[10];           /* block number or byte number */
+    blknum = (blknum << 8) + buf[9];
+
+    if (mode != BYTE_MODE)
+        mode = BLOCK_MODE;
+    total_len = (mode == BLOCK_MODE) ? blknum * blklen : blknum;
+    if (total_len > WOAL_2K_BYTES) {
+        PRINTM(MERROR, "Total data length is too large!\n");
+        ret = -EINVAL;
+        goto done;
+    }
+    PRINTM(MINFO, "CMD53 read/write, func = %d, addr = %#x, mode = %d, "
+           "block size = %d, block(byte) number = %d\n",
+           func, reg, mode, blklen, blknum);
+
+    if (!rw) {
+        sdio_claim_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
+        if (!sdio_readsb
+            (((struct sdio_mmc_card *) priv->phandle->card)->func, data, reg,
+             total_len))
+            PRINTM(MERROR, "sdio_readsb: reading memory 0x%x failed\n", reg);
+        sdio_release_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
+
+        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
+            PRINTM(MINFO, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    } else {
+        pattern_len = wrq->u.data.length - 11;
+        if (pattern_len > total_len)
+            pattern_len = total_len;
+        memset(data, 0, sizeof(data));
+
+        /* Copy/duplicate the pattern to data buffer */
+        for (pos = 0; pos < total_len; pos++)
+            data[pos] = buf[11 + (pos % pattern_len)];
+
+        sdio_claim_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
+        if (!sdio_writesb
+            (((struct sdio_mmc_card *) priv->phandle->card)->func, reg, data,
+             total_len))
+            PRINTM(MERROR, "sdio_writesb: writing memory 0x%x failed\n", reg);
+        sdio_release_host(((struct sdio_mmc_card *) priv->phandle->card)->func);
+    }
+
+  done:
+    if (buf)
+        kfree(buf);
+    if (data)
+        kfree(data);
+    LEAVE();
+    return ret;
+}
+
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+/**
+ * @brief Set SDIO Multi-point aggregation control parameters
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_do_sdio_mpa_ctrl(moal_private * priv, struct iwreq *wrq)
+{
+    int data[6];
+    int ret = 0;
+    mlan_ds_misc_cfg *misc = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+    PRINTM(MERROR, "mpa_ctrl: %d\n", wrq->u.data.length);
+
+    if (wrq->u.data.length > 6) {
+        PRINTM(MERROR, "Invalid number of arguments\n");
+        ret = -EINVAL;
+        goto done;
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    misc = (mlan_ds_misc_cfg *) req->pbuf;
+    memset(misc, 0, sizeof(mlan_ds_misc_cfg));
+
+    misc->sub_command = MLAN_OID_MISC_SDIO_MPA_CTRL;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+
+    /* Get the values first, then modify these values if user had modified them 
+     */
+
+    req->action = MLAN_ACT_GET;
+    if ((ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) !=
+        MLAN_STATUS_SUCCESS) {
+        PRINTM(MERROR, "woal_request_ioctl returned %d\n", ret);
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (wrq->u.data.length == 0) {
+        data[0] = misc->param.mpa_ctrl.tx_enable;
+        data[1] = misc->param.mpa_ctrl.rx_enable;
+        data[2] = misc->param.mpa_ctrl.tx_buf_size;
+        data[3] = misc->param.mpa_ctrl.rx_buf_size;
+        data[4] = misc->param.mpa_ctrl.tx_max_ports;
+        data[5] = misc->param.mpa_ctrl.rx_max_ports;
+
+        PRINTM(MINFO, "Get Param: %d %d %d %d %d %d\n", data[0], data[1],
+               data[2], data[3], data[4], data[5]);
+
+        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = sizeof(data) / sizeof(int);
+        goto done;
+    }
+
+    if (copy_from_user(data, wrq->u.data.pointer,
+                       sizeof(int) * wrq->u.data.length)) {
+        PRINTM(MINFO, "Copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    switch (wrq->u.data.length) {
+    case 6:
+        misc->param.mpa_ctrl.rx_max_ports = data[5];
+    case 5:
+        misc->param.mpa_ctrl.tx_max_ports = data[4];
+    case 4:
+        misc->param.mpa_ctrl.rx_buf_size = data[3];
+    case 3:
+        misc->param.mpa_ctrl.tx_buf_size = data[2];
+    case 2:
+        misc->param.mpa_ctrl.rx_enable = data[1];
+    case 1:
+        /* Set cmd */
+        req->action = MLAN_ACT_SET;
+
+        PRINTM(MINFO, "Set Param: %d %d %d %d %d %d\n", data[0], data[1],
+               data[2], data[3], data[4], data[5]);
+
+        misc->param.mpa_ctrl.tx_enable = data[0];
+        break;
+    default:
+        PRINTM(MERROR, "Default case error\n");
+        ret = -EINVAL;
+        goto done;
+    }
+
+    if ((ret = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT) !=
+         MLAN_STATUS_SUCCESS)) {
+        PRINTM(MERROR, "woal_request_ioctl returned %d\n", ret);
+        ret = -EFAULT;
+        goto done;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+#endif /* SDIO_MULTI_PORT_TX_AGGR || SDIO_MULTI_PORT_RX_AGGR */
+
+/**
+ * @brief Set/get TID multi-port eligibility table
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_set_get_tid_elig_tbl(moal_private * priv, struct iwreq *wrq)
+{
+    int data[8] = { 0 }, ret = 0;
+    mlan_ds_wmm_cfg *cfg = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    if (wrq->u.data.length > 8) {
+        ret = -EINVAL;
+        goto done;
+    }
+    cfg = (mlan_ds_wmm_cfg *) req->pbuf;
+    cfg->sub_command = MLAN_OID_TID_ELIG_TBL;
+    req->req_id = MLAN_IOCTL_WMM_CFG;
+    if (wrq->u.data.length) {
+        if (copy_from_user
+            (data, wrq->u.data.pointer, (wrq->u.data.length * sizeof(int)))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        req->action = MLAN_ACT_SET;
+        memcpy(cfg->param.tid_tbl, (t_u32 *) data, sizeof(data));
+    } else
+        req->action = MLAN_ACT_GET;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (!wrq->u.data.length) {
+        memcpy(data, (int *) cfg->param.tid_tbl, sizeof(data));
+        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = sizeof(data) / sizeof(int);
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/** Maximum number of probes to send on each channel */
+#define MAX_PROBES  10
+/**
+ * @brief Set/Get scan configuration parameters
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_set_get_scan_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int data[6], ret = 0;
+    mlan_ds_scan *scan = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    if (wrq->u.data.length > 6) {
+        ret = -EINVAL;
+        goto done;
+    }
+    scan = (mlan_ds_scan *) req->pbuf;
+    scan->sub_command = MLAN_OID_SCAN_CONFIG;
+    req->req_id = MLAN_IOCTL_SCAN;
+    memset(data, 0, sizeof(data));
+    if (wrq->u.data.length) {
+        if (copy_from_user
+            (data, wrq->u.data.pointer, (wrq->u.data.length * sizeof(int)))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if ((data[0] < 0) || (data[0] > MLAN_SCAN_TYPE_PASSIVE)) {
+            PRINTM(MERROR, "Invalid argument for scan type\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        if ((data[1] < 0) || (data[1] > MLAN_SCAN_MODE_ANY)) {
+            PRINTM(MERROR, "Invalid argument for scan mode\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        if ((data[2] < 0) || (data[2] > MAX_PROBES)) {
+            PRINTM(MERROR, "Invalid argument for scan probes\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        if (((data[3] < 0) || (data[3] > MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME)) ||
+            ((data[4] < 0) || (data[4] > MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME)) ||
+            ((data[5] < 0) || (data[5] > MRVDRV_MAX_PASSIVE_SCAN_CHAN_TIME))) {
+            PRINTM(MERROR, "Invalid argument for scan time\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        req->action = MLAN_ACT_SET;
+        memcpy(&scan->param.scan_cfg, (t_u32 *) data, sizeof(data));
+    } else
+        req->action = MLAN_ACT_GET;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (!wrq->u.data.length) {
+        memcpy(data, (int *) &scan->param.scan_cfg, sizeof(data));
+        if (copy_to_user(wrq->u.data.pointer, data, sizeof(data))) {
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = sizeof(data) / sizeof(int);
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/** VSIE configuration buffer length */
+#define VSIE_MAX_CFG_LEN    (MLAN_MAX_VSIE_LEN - 2 + 3)
+/** VSIE mask to remove the IE */
+#define VSIE_MASK_DISABLE   0x00
+/** VSIE Action : Get */
+#define VSIE_ACTION_GET     0
+/** VSIE Action : Add */
+#define VSIE_ACTION_ADD     1
+/** VSIE Action : Delete */
+#define VSIE_ACTION_DELETE  2
+/** 
+ *  @brief Get/Add/Remove vendor specific IE
+ *   
+ *  @param priv         A pointer to moal_private structure
+ *  @param wrq          A pointer to iwreq structure
+ *  @return             MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static int
+woal_vsie_cfg_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    int ret = 0, user_data_len = 0, ie_len = 0;
+    mlan_ds_misc_cfg *misc = NULL;
+    mlan_ioctl_req *req = NULL;
+    t_u8 *buf = NULL;
+
+    ENTER();
+
+    user_data_len = wrq->u.data.length;
+    if (user_data_len < 2 || user_data_len == 3 ||
+        user_data_len > VSIE_MAX_CFG_LEN) {
+        PRINTM(MERROR, "Invalid argument number!\n");
+        LEAVE();
+        return -EINVAL;
+    }
+    if (!(buf = (t_u8 *) kmalloc(VSIE_MAX_CFG_LEN, GFP_ATOMIC))) {
+        PRINTM(MERROR, "Cannot allocate buffer for command!\n");
+        LEAVE();
+        return -ENOMEM;
+    }
+    memset(buf, 0, VSIE_MAX_CFG_LEN);
+    if (copy_from_user(buf, wrq->u.data.pointer, user_data_len)) {
+        PRINTM(MINFO, "Copy from user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if ((buf[0] > VSIE_ACTION_DELETE) ||
+        (buf[1] > MLAN_MAX_VSIE_NUM - 1) ||
+        ((buf[0] == VSIE_ACTION_ADD) &&
+         !(buf[2] &&
+           buf[2] <=
+           (MLAN_VSIE_MASK_SCAN | MLAN_VSIE_MASK_ASSOC |
+            MLAN_VSIE_MASK_ADHOC)))) {
+        PRINTM(MERROR, "Invalid argument!\n");
+        ret = -EINVAL;
+        goto done;
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+    misc = (mlan_ds_misc_cfg *) req->pbuf;
+    misc->sub_command = MLAN_OID_MISC_VS_IE;
+
+    misc->param.vsie.id = buf[1];
+    misc->param.vsie.mask = VSIE_MASK_DISABLE;
+    switch (buf[0]) {
+    case VSIE_ACTION_GET:
+        req->action = MLAN_ACT_GET;
+        break;
+    case VSIE_ACTION_ADD:
+        ie_len = user_data_len - 3;
+        misc->param.vsie.mask = buf[2];
+        misc->param.vsie.ie[1] = ie_len;
+        memcpy(&misc->param.vsie.ie[2], &buf[3], ie_len);
+    case VSIE_ACTION_DELETE:
+        /* Set with mask 0 is remove */
+        req->action = MLAN_ACT_SET;
+        break;
+    default:
+        break;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    wrq->u.data.length = misc->param.vsie.ie[1];
+    if (wrq->u.data.length) {
+        if (copy_to_user
+            (wrq->u.data.pointer, &misc->param.vsie.ie[2],
+             wrq->u.data.length)) {
+            PRINTM(MINFO, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+  done:
+    if (buf)
+        kfree(buf);
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * @brief Set/Get PS configuration parameters
+ * 
+ * @param priv     A pointer to moal_private structure
+ * @param wrq      A pointer to iwreq structure
+ * 
+ * @return         0 --success, otherwise fail
+ */
+static int
+woal_set_get_ps_cfg(moal_private * priv, struct iwreq *wrq)
+{
+    int data[7], ret = 0;
+    mlan_ds_pm_cfg *pm_cfg = NULL;
+    mlan_ioctl_req *req = NULL;
+    int allowed = 3;
+    int i = 3;
+
+    ENTER();
+
+    allowed++;                  /* For ad-hoc awake period parameter */
+    allowed++;                  /* For beacon missing timeout parameter */
+    allowed += 2;               /* For delay to PS and PS mode parameters */
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    if (wrq->u.data.length > allowed) {
+        ret = -EINVAL;
+        goto done;
+    }
+    pm_cfg = (mlan_ds_pm_cfg *) req->pbuf;
+    pm_cfg->sub_command = MLAN_OID_PM_CFG_PS_CFG;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+    memset(data, 0, sizeof(data));
+    if (wrq->u.data.length) {
+        if (copy_from_user
+            (data, wrq->u.data.pointer, (wrq->u.data.length * sizeof(int)))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        if ((data[0] < PS_NULL_DISABLE)) {
+            PRINTM(MERROR, "Invalid argument for PS null interval\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        if ((data[1] != IGNORE_MULTIPLE_DTIM) &&
+            ((data[1] < MIN_MULTIPLE_DTIM) || (data[1] > MAX_MULTIPLE_DTIM))) {
+            PRINTM(MERROR, "Invalid argument for multiple DTIM\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        if (data[2] < MIN_LISTEN_INTERVAL) {
+            PRINTM(MERROR, "Invalid argument for listen interval\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        if ((data[i] != SPECIAL_ADHOC_AWAKE_PD) &&
+            ((data[i] < MIN_ADHOC_AWAKE_PD) ||
+             (data[i] > MAX_ADHOC_AWAKE_PD))) {
+            PRINTM(MERROR, "Invalid argument for adhoc awake period\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        i++;
+        if ((data[i] != DISABLE_BCN_MISS_TO) &&
+            ((data[i] < MIN_BCN_MISS_TO) || (data[i] > MAX_BCN_MISS_TO))) {
+            PRINTM(MERROR, "Invalid argument for beacon miss timeout\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        i++;
+        if (wrq->u.data.length < allowed - 1)
+            data[i] = DELAY_TO_PS_UNCHANGED;
+        else if ((data[i] < MIN_DELAY_TO_PS) || (data[i] > MAX_DELAY_TO_PS)) {
+            PRINTM(MERROR, "Invalid argument for delay to PS\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        i++;
+        if ((data[i] != PS_MODE_UNCHANGED) && (data[i] != PS_MODE_AUTO) &&
+            (data[i] != PS_MODE_POLL) && (data[i] != PS_MODE_NULL)) {
+            PRINTM(MERROR, "Invalid argument for PS mode\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        i++;
+        req->action = MLAN_ACT_SET;
+        memcpy(&pm_cfg->param.ps_cfg, (t_u32 *) data,
+               sizeof(pm_cfg->param.ps_cfg));
+    } else
+        req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    memcpy(data, (int *) &pm_cfg->param.ps_cfg, sizeof(pm_cfg->param.ps_cfg));
+    if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * allowed)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    wrq->u.data.length = allowed;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Private IOCTL entry to send an ADDTS TSPEC
+ *
+ *  Receive a ADDTS command from the application.  The command structure
+ *    contains a TSPEC and timeout in milliseconds.  The timeout is performed
+ *    in the firmware after the ADDTS command frame is sent.
+ *
+ *  The TSPEC is received in the API as an opaque block whose length is
+ *    calculated from the IOCTL data length.  The firmware will send the
+ *    entire data block, including the bytes after the TSPEC.  This is done
+ *    to allow extra IEs to be packaged with the TSPEC in the ADDTS action
+ *    frame.
+ *
+ *  The IOCTL structure contains two return fields:
+ *    - The firmware command result, which indicates failure and timeouts
+ *    - The IEEE Status code which contains the corresponding value from
+ *      any ADDTS response frame received.
+ *
+ *  In addition, the opaque TSPEC data block passed in is replaced with the
+ *    TSPEC received in the ADDTS response frame.  In case of failure, the
+ *    AP may modify the TSPEC on return and in the case of success, the
+ *    medium time is returned as calculated by the AP.  Along with the TSPEC,
+ *    any IEs that are sent in the ADDTS response are also returned and can be
+ *    parsed using the IOCTL length as an indicator of extra elements.
+ *
+ *  The return value to the application layer indicates a driver execution
+ *    success or failure.  A successful return could still indicate a firmware
+ *    failure or AP negotiation failure via the commandResult field copied
+ *    back to the application.
+ *
+ *  @param priv    Pointer to the mlan_private driver data struct
+ *  @param wrq     A pointer to iwreq structure containing the
+ *                 wlan_ioctl_wmm_addts_req_t struct for this ADDTS request
+ *
+ *  @return        0 if successful; IOCTL error code otherwise
+ */
+static int
+woal_wmm_addts_req_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    static t_u8 dialog_tok = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_wmm_cfg *cfg = NULL;
+    wlan_ioctl_wmm_addts_req_t addts_ioctl;
+    int ret = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    req->req_id = MLAN_IOCTL_WMM_CFG;
+    cfg = (mlan_ds_wmm_cfg *) req->pbuf;
+    cfg->sub_command = MLAN_OID_WMM_CFG_ADDTS;
+
+    memset(&addts_ioctl, 0, sizeof(addts_ioctl));
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(&addts_ioctl, wrq->u.data.pointer,
+                           MIN(wrq->u.data.length, sizeof(addts_ioctl)))) {
+            PRINTM(MERROR, "TSPEC: ADDTS copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+
+        if ((++dialog_tok) == 0)
+            dialog_tok = 1;
+        cfg->param.addts.dialog_tok = dialog_tok;
+        cfg->param.addts.timeout = addts_ioctl.timeout_ms;
+        cfg->param.addts.tspec_data_len = (wrq->u.data.length
+                                           - sizeof(addts_ioctl.timeout_ms)
+                                           - sizeof(addts_ioctl.cmd_result)
+                                           -
+                                           sizeof(addts_ioctl.
+                                                  ieee_status_code));
+
+        memcpy(cfg->param.addts.tspec_data,
+               addts_ioctl.tspec_data, cfg->param.addts.tspec_data_len);
+
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+        addts_ioctl.cmd_result = cfg->param.addts.result;
+        addts_ioctl.ieee_status_code = (t_u8) cfg->param.addts.status_code;
+        memcpy(addts_ioctl.tspec_data,
+               cfg->param.addts.tspec_data, cfg->param.addts.tspec_data_len);
+
+        wrq->u.data.length = (sizeof(addts_ioctl.timeout_ms)
+                              + sizeof(addts_ioctl.cmd_result)
+                              + sizeof(addts_ioctl.ieee_status_code)
+                              + cfg->param.addts.tspec_data_len);
+
+        if (copy_to_user(wrq->u.data.pointer, &addts_ioctl, wrq->u.data.length)) {
+            PRINTM(MERROR, "TSPEC: ADDTS copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Private IOCTL entry to send a DELTS TSPEC
+ *
+ *  Receive a DELTS command from the application.  The command structure
+ *    contains a TSPEC and reason code along with space for a command result
+ *    to be returned.  The information is packaged is sent to the wlan_cmd.c
+ *    firmware command prep and send routines for execution in the firmware.
+ *
+ *  The reason code is not used for WMM implementations but is indicated in
+ *    the 802.11e specification.
+ *
+ *  The return value to the application layer indicates a driver execution
+ *    success or failure.  A successful return could still indicate a firmware
+ *    failure via the cmd_result field copied back to the application.
+ *
+ *  @param priv    Pointer to the mlan_private driver data struct
+ *  @param wrq     A pointer to iwreq structure containing the
+ *                 wlan_ioctl_wmm_delts_req_t struct for this DELTS request
+ *
+ *  @return        0 if successful; IOCTL error code otherwise
+ */
+static int
+woal_wmm_delts_req_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_wmm_cfg *cfg = NULL;
+    wlan_ioctl_wmm_delts_req_t delts_ioctl;
+    int ret = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    req->req_id = MLAN_IOCTL_WMM_CFG;
+    cfg = (mlan_ds_wmm_cfg *) req->pbuf;
+    cfg->sub_command = MLAN_OID_WMM_CFG_DELTS;
+
+    memset(&delts_ioctl, 0, sizeof(delts_ioctl));
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(&delts_ioctl, wrq->u.data.pointer,
+                           MIN(wrq->u.data.length, sizeof(delts_ioctl)))) {
+            PRINTM(MERROR, "TSPEC: DELTS copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+
+        cfg->param.delts.status_code = (t_u32) delts_ioctl.ieee_reason_code;
+
+        /* Calculate the length of the TSPEC */
+        cfg->param.delts.tspec_data_len = (wrq->u.data.length
+                                           - sizeof(delts_ioctl.cmd_result)
+                                           -
+                                           sizeof(delts_ioctl.
+                                                  ieee_reason_code));
+
+        memcpy(cfg->param.delts.tspec_data,
+               delts_ioctl.tspec_data, cfg->param.delts.tspec_data_len);
+
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+
+        /* Return the firmware command result back to the application layer */
+        delts_ioctl.cmd_result = cfg->param.delts.result;
+        wrq->u.data.length = sizeof(delts_ioctl);
+
+        if (copy_to_user(wrq->u.data.pointer, &delts_ioctl, wrq->u.data.length)) {
+            PRINTM(MERROR, "TSPEC: DELTS copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Private IOCTL entry to get/set a specified AC Queue's parameters
+ *
+ *  Receive a AC Queue configuration command which is used to get, set, or
+ *    default the parameters associated with a specific WMM AC Queue.
+ *
+ *  @param priv    Pointer to the mlan_private driver data struct
+ *  @param wrq     A pointer to iwreq structure containing the
+ *                 wlan_ioctl_wmm_queue_config_t struct
+ *
+ *  @return        0 if successful; IOCTL error code otherwise
+ */
+static int
+woal_wmm_queue_config_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_wmm_cfg *pwmm = NULL;
+    mlan_ds_wmm_queue_config *pqcfg = NULL;
+    wlan_ioctl_wmm_queue_config_t qcfg_ioctl;
+    int ret = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    req->req_id = MLAN_IOCTL_WMM_CFG;
+    pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
+    pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_CONFIG;
+
+    memset(&qcfg_ioctl, 0, sizeof(qcfg_ioctl));
+    pqcfg = (mlan_ds_wmm_queue_config *) & pwmm->param.q_cfg;
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(&qcfg_ioctl, wrq->u.data.pointer,
+                           MIN(wrq->u.data.length, sizeof(qcfg_ioctl)))) {
+            PRINTM(MERROR, "QCONFIG: copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+
+        pqcfg->action = qcfg_ioctl.action;
+        pqcfg->access_category = qcfg_ioctl.access_category;
+        pqcfg->msdu_lifetime_expiry = qcfg_ioctl.msdu_lifetime_expiry;
+
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+        memset(&qcfg_ioctl, 0, sizeof(qcfg_ioctl));
+        qcfg_ioctl.action = pqcfg->action;
+        qcfg_ioctl.access_category = pqcfg->access_category;
+        qcfg_ioctl.msdu_lifetime_expiry = pqcfg->msdu_lifetime_expiry;
+        wrq->u.data.length = sizeof(qcfg_ioctl);
+
+        if (copy_to_user(wrq->u.data.pointer, &qcfg_ioctl, wrq->u.data.length)) {
+            PRINTM(MERROR, "QCONFIG: copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Private IOCTL entry to get and start/stop queue stats on a WMM AC
+ *
+ *  Receive a AC Queue statistics command from the application for a specific
+ *    WMM AC.  The command can:
+ *         - Turn stats on
+ *         - Turn stats off
+ *         - Collect and clear the stats
+ *
+ *  @param priv    Pointer to the moal_private driver data struct
+ *  @param wrq     A pointer to iwreq structure containing the
+ *                 wlan_ioctl_wmm_queue_stats_t struct
+ *
+ *  @return        0 if successful; IOCTL error code otherwise
+ */
+static int
+woal_wmm_queue_stats_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_wmm_cfg *pwmm = NULL;
+    mlan_ds_wmm_queue_stats *pqstats = NULL;
+    wlan_ioctl_wmm_queue_stats_t qstats_ioctl;
+    int ret = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    req->req_id = MLAN_IOCTL_WMM_CFG;
+    pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
+    pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_STATS;
+
+    memset(&qstats_ioctl, 0, sizeof(qstats_ioctl));
+    pqstats = (mlan_ds_wmm_queue_stats *) & pwmm->param.q_stats;
+
+    if (wrq->u.data.length) {
+        if (copy_from_user(&qstats_ioctl, wrq->u.data.pointer,
+                           MIN(wrq->u.data.length, sizeof(qstats_ioctl)))) {
+            PRINTM(MERROR, "QSTATS: copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+
+        memcpy((void *) pqstats, (void *) &qstats_ioctl, sizeof(qstats_ioctl));
+        PRINTM(MINFO, "QSTATS: IOCTL [%d,%d]\n", qstats_ioctl.action,
+               qstats_ioctl.access_category);
+
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+
+        memset(&qstats_ioctl, 0, sizeof(qstats_ioctl));
+        memcpy((void *) &qstats_ioctl, (void *) pqstats, sizeof(qstats_ioctl));
+        wrq->u.data.length = sizeof(qstats_ioctl);
+
+        if (copy_to_user
+            (wrq->u.data.pointer, &qstats_ioctl, wrq->u.data.length)) {
+            PRINTM(MERROR, "QSTATS: copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Private IOCTL entry to get the status of the WMM queues
+ *
+ *  Return the following information for each WMM AC:
+ *        - WMM IE Acm Required
+ *        - Firmware Flow Required
+ *        - Firmware Flow Established
+ *        - Firmware Queue Enabled
+ *        - Firmware Delivery Enabled
+ *        - Firmware Trigger Enabled
+ *
+ *  @param priv    Pointer to the moal_private driver data struct
+ *  @param wrq     A pointer to iwreq structure containing the
+ *                 wlan_ioctl_wmm_queue_status_t struct for request
+ *
+ *  @return        0 if successful; IOCTL error code otherwise
+ */
+static int
+woal_wmm_queue_status_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_wmm_cfg *pwmm = NULL;
+    wlan_ioctl_wmm_queue_status_t qstatus_ioctl;
+    int ret = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    req->req_id = MLAN_IOCTL_WMM_CFG;
+    pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
+    pwmm->sub_command = MLAN_OID_WMM_CFG_QUEUE_STATUS;
+
+    if (wrq->u.data.length == sizeof(qstatus_ioctl)) {
+        if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_NO_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+
+        memset(&qstatus_ioctl, 0, sizeof(qstatus_ioctl));
+        memcpy((void *) &qstatus_ioctl, (void *) &pwmm->param.q_status,
+               sizeof(qstatus_ioctl));
+        wrq->u.data.length = sizeof(qstatus_ioctl);
+    } else {
+        wrq->u.data.length = 0;
+    }
+
+    if (copy_to_user(wrq->u.data.pointer, &qstatus_ioctl, wrq->u.data.length)) {
+        PRINTM(MERROR, "QSTATUS: copy to user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Private IOCTL entry to get the status of the WMM Traffic Streams
+ *
+ *  @param priv    Pointer to the moal_private driver data struct
+ *  @param wrq     A pointer to iwreq structure containing the
+ *                 wlan_ioctl_wmm_ts_status_t struct for request
+ *
+ *  @return        0 if successful; IOCTL error code otherwise
+ */
+static int
+woal_wmm_ts_status_ioctl(moal_private * priv, struct iwreq *wrq)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_wmm_cfg *pwmm = NULL;
+    wlan_ioctl_wmm_ts_status_t ts_status_ioctl;
+    int ret = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_wmm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    req->req_id = MLAN_IOCTL_WMM_CFG;
+    pwmm = (mlan_ds_wmm_cfg *) req->pbuf;
+    pwmm->sub_command = MLAN_OID_WMM_CFG_TS_STATUS;
+
+    memset(&ts_status_ioctl, 0, sizeof(ts_status_ioctl));
+
+    if (wrq->u.data.length == sizeof(ts_status_ioctl)) {
+        if (copy_from_user(&ts_status_ioctl, wrq->u.data.pointer,
+                           MIN(wrq->u.data.length, sizeof(ts_status_ioctl)))) {
+            PRINTM(MERROR, "TSTATUS: copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+
+        memset(&pwmm->param.ts_status, 0, sizeof(ts_status_ioctl));
+        pwmm->param.ts_status.tid = ts_status_ioctl.tid;
+
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+
+        memset(&ts_status_ioctl, 0, sizeof(ts_status_ioctl));
+        memcpy((void *) &ts_status_ioctl, (void *) &pwmm->param.ts_status,
+               sizeof(ts_status_ioctl));
+        wrq->u.data.length = sizeof(ts_status_ioctl);
+    } else {
+        wrq->u.data.length = 0;
+    }
+
+    if (copy_to_user(wrq->u.data.pointer, &ts_status_ioctl, wrq->u.data.length)) {
+        PRINTM(MERROR, "TSTATUS: copy to user failed\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set/Get auth type
+ *
+ *  @param priv     Pointer to the moal_private driver data struct
+ *  @param wrq	    A pointer to iwreq structure
+ *
+ *  @return          0 --success, otherwise fail
+ */
+static int
+woal_auth_type(moal_private * priv, struct iwreq *wrq)
+{
+    int auth_type;
+    t_u32 auth_mode;
+    int ret = 0;
+
+    ENTER();
+    if (wrq->u.data.length == 0) {
+        if (MLAN_STATUS_SUCCESS !=
+            woal_get_auth_mode(priv, MOAL_IOCTL_WAIT, &auth_mode)) {
+            ret = -EFAULT;
+            goto done;
+        }
+        auth_type = auth_mode;
+        if (copy_to_user(wrq->u.data.pointer, &auth_type, sizeof(auth_type))) {
+            PRINTM(MERROR, "Copy to user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        wrq->u.data.length = 1;
+    } else {
+        if (copy_from_user(&auth_type, wrq->u.data.pointer, sizeof(auth_type))) {
+            PRINTM(MERROR, "Copy from user failed\n");
+            ret = -EFAULT;
+            goto done;
+        }
+        PRINTM(MINFO, "SET: auth_type %d\n", auth_type);
+        if (((auth_type < MLAN_AUTH_MODE_OPEN) ||
+             (auth_type > MLAN_AUTH_MODE_SHARED))
+            && (auth_type != MLAN_AUTH_MODE_AUTO)) {
+            ret = -EINVAL;
+            goto done;
+        }
+        auth_mode = auth_type;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_set_auth_mode(priv, MOAL_IOCTL_WAIT, auth_mode)) {
+            ret = -EFAULT;
+            goto done;
+        }
+    }
+  done:
+    LEAVE();
+    return ret;
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+
+/** 
+ *  @brief Get version 
+ *   
+ *  @param handle 		A pointer to moal_handle structure
+ *  @param version		A pointer to version buffer
+ *  @param max_len		max length of version buffer
+ *
+ *  @return 	   		N/A
+ */
+void
+woal_get_version(moal_handle * handle, char *version, int max_len)
+{
+    union
+    {
+        t_u32 l;
+        t_u8 c[4];
+    } ver;
+    char fw_ver[32];
+
+    ENTER();
+
+    ver.l = handle->fw_release_number;
+    sprintf(fw_ver, "%u.%u.%u.p%u", ver.c[2], ver.c[1], ver.c[0], ver.c[3]);
+
+    snprintf(version, max_len, driver_version, fw_ver);
+
+    LEAVE();
+}
+
+/**
+ *  @brief ioctl function - entry point
+ *
+ *  @param dev		A pointer to net_device structure
+ *  @param req	   	A pointer to ifreq structure
+ *  @param cmd 		Command
+ *
+ *  @return          0 --success, otherwise fail
+ */
+int
+woal_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    struct iwreq *wrq = (struct iwreq *) req;
+    int ret = 0;
+
+    ENTER();
+
+    PRINTM(MINFO, "woal_do_ioctl: ioctl cmd = 0x%x\n", cmd);
+    switch (cmd) {
+    case WOAL_SETONEINT_GETWORDCHAR:
+        switch (wrq->u.data.flags) {
+        case WOAL_VERSION:     /* Get driver version */
+            ret = woal_get_driver_version(priv, req);
+            break;
+        case WOAL_VEREXT:      /* Get extended driver version */
+            ret = woal_get_driver_verext(priv, req);
+            break;
+        default:
+            ret = -EOPNOTSUPP;
+            break;
+        }
+        break;
+    case WOAL_SETNONE_GETNONE:
+        switch (wrq->u.data.flags) {
+        case WOAL_WARMRESET:
+            ret = woal_warm_reset(priv);
+            break;
+        default:
+            ret = -EOPNOTSUPP;
+            break;
+        }
+        break;
+    case WOAL_SETONEINT_GETONEINT:
+        switch (wrq->u.data.flags) {
+        case WOAL_SET_GET_TXRATE:
+            ret = woal_set_get_txrate(priv, wrq);
+            break;
+        case WOAL_SET_GET_REGIONCODE:
+            ret = woal_set_get_regioncode(priv, wrq);
+            break;
+        case WOAL_SET_RADIO:
+            ret = woal_set_get_radio(priv, wrq);
+            break;
+        case WOAL_WMM_ENABLE:
+            ret = woal_wmm_enable_ioctl(priv, wrq);
+            break;
+        case WOAL_11D_ENABLE:
+            ret = woal_11d_enable_ioctl(priv, wrq);
+            break;
+        case WOAL_SET_GET_TX_RX_ANT:
+            ret = woal_set_get_tx_rx_ant(priv, wrq);
+            break;
+        case WOAL_SET_GET_QOS_CFG:
+            ret = woal_set_get_qos_cfg(priv, wrq);
+            break;
+        case WOAL_SET_GET_LDO_CFG:
+            ret = woal_set_get_ldo_cfg(priv, wrq);
+            break;
+#ifdef REASSOCIATION
+        case WOAL_SET_GET_REASSOC:
+            ret = woal_set_get_reassoc(priv, wrq);
+            break;
+#endif /* REASSOCIATION */
+        case WOAL_TXBUF_CFG:
+            ret = woal_txbuf_cfg(priv, wrq);
+            break;
+        case WOAL_SET_GET_WWS_CFG:
+            ret = woal_wws_cfg(priv, wrq);
+            break;
+        case WOAL_SLEEP_PD:
+            ret = woal_sleep_pd(priv, wrq);
+            break;
+        case WOAL_AUTH_TYPE:
+            ret = woal_auth_type(priv, wrq);
+            break;
+
+        default:
+            ret = -EOPNOTSUPP;
+            break;
+        }
+        break;
+
+    case WOAL_SET_GET_SIXTEEN_INT:
+        switch ((int) wrq->u.data.flags) {
+        case WOAL_TX_POWERCFG:
+            ret = woal_tx_power_cfg(priv, wrq);
+            break;
+#ifdef DEBUG_LEVEL1
+        case WOAL_DRV_DBG:
+            ret = woal_drv_dbg(priv, wrq);
+            break;
+#endif
+        case WOAL_BEACON_INTERVAL:
+            ret = woal_beacon_interval(priv, wrq);
+            break;
+        case WOAL_ATIM_WINDOW:
+            ret = woal_atim_window(priv, wrq);
+            break;
+        case WOAL_SIGNAL:
+            ret = woal_get_signal(priv, wrq);
+            break;
+        case WOAL_DEEP_SLEEP:
+            ret = woal_deep_sleep_ioctl(priv, wrq);
+            break;
+        case WOAL_11N_TX_CFG:
+            ret = woal_11n_tx_cfg(priv, wrq);
+            break;
+        case WOAL_11N_AMSDU_AGGR_CTRL:
+            ret = woal_11n_amsdu_aggr_ctrl(priv, wrq);
+            break;
+        case WOAL_11N_HTCAP_CFG:
+            ret = woal_11n_htcap_cfg(priv, wrq);
+            break;
+        case WOAL_PRIO_TBL:
+            ret = woal_11n_prio_tbl(priv, wrq);
+            break;
+        case WOAL_ADDBA_UPDT:
+            ret = woal_addba_para_updt(priv, wrq);
+            break;
+        case WOAL_ADDBA_REJECT:
+            ret = woal_addba_reject(priv, wrq);
+            break;
+        case WOAL_HS_CFG:
+            ret = woal_hs_cfg(priv, wrq, MTRUE);
+            break;
+        case WOAL_HS_SETPARA:
+            ret = woal_hs_setpara(priv, wrq);
+            break;
+        case WOAL_REG_READ_WRITE:
+            ret = woal_reg_read_write(priv, wrq);
+            break;
+        case WOAL_INACTIVITY_TIMEOUT_EXT:
+            ret = woal_inactivity_timeout_ext(priv, wrq);
+            break;
+        case WOAL_SDIO_CLOCK:
+            ret = woal_sdio_clock_ioctl(priv, wrq);
+            break;
+        case WOAL_BAND_CFG:
+            ret = woal_band_cfg(priv, wrq);
+            break;
+        case WOAL_BCA_TIME_SHARE:
+            ret = woal_bca_time_share(priv, wrq);
+            break;
+        case WOAL_TID_ELIG_TBL:
+            ret = woal_set_get_tid_elig_tbl(priv, wrq);
+            break;
+        case WOAL_SCAN_CFG:
+            ret = woal_set_get_scan_cfg(priv, wrq);
+            break;
+        case WOAL_PS_CFG:
+            ret = woal_set_get_ps_cfg(priv, wrq);
+            break;
+        case WOAL_MEM_READ_WRITE:
+            ret = woal_mem_read_write(priv, wrq);
+            break;
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+        case WOAL_SDIO_MPA_CTRL:
+            ret = woal_do_sdio_mpa_ctrl(priv, wrq);
+            break;
+#endif
+        case WOAL_SLEEP_PARAMS:
+            ret = woal_sleep_params_ioctl(priv, wrq);
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        break;
+
+    case WOALGETLOG:
+        ret = woal_get_log(priv, wrq);
+        break;
+    case WOAL_SET_GET_256_CHAR:
+        switch (wrq->u.data.flags) {
+        case WOAL_PASSPHRASE:
+            ret = woal_passphrase(priv, wrq);
+            break;
+        case WOAL_ADHOC_AES:
+            ret = woal_adhoc_aes_ioctl(priv, wrq);
+            break;
+        case WOAL_WMM_QUEUE_STATUS:
+            ret = woal_wmm_queue_status_ioctl(priv, wrq);
+            break;
+        case WOAL_WMM_TS_STATUS:
+            ret = woal_wmm_ts_status_ioctl(priv, wrq);
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        break;
+
+    case WOAL_SETADDR_GETNONE:
+        switch ((int) wrq->u.data.flags) {
+        case WOAL_DEAUTH:
+            ret = woal_deauth(priv, wrq);
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        break;
+
+    case WOAL_SETNONE_GETTWELVE_CHAR:
+        /* 
+         * We've not used IW_PRIV_TYPE_FIXED so sub-ioctl number is
+         * in flags of iwreq structure, otherwise it will be in
+         * mode member of iwreq structure.
+         */
+        switch ((int) wrq->u.data.flags) {
+        case WOAL_WPS_SESSION:
+            ret = woal_wps_cfg_ioctl(priv, wrq);
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        break;
+    case WOAL_SETNONE_GET_FOUR_INT:
+        switch ((int) wrq->u.data.flags) {
+        case WOAL_DATA_RATE:
+            ret = woal_get_txrx_rate(priv, wrq);
+            break;
+        case WOAL_ESUPP_MODE:
+            ret = woal_get_esupp_mode(priv, wrq);
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        break;
+
+#ifdef MFG_CMD_SUPPORT
+    case WOAL_MFG_CMD:
+        PRINTM(MINFO, "Entering the Manufacturing ioctl SIOCCFMFG\n");
+        ret = woal_mfg_command(priv, wrq);
+        PRINTM(MINFO, "Manufacturing Ioctl %s\n", (ret) ? "failed" : "success");
+        break;
+#endif
+    case WOAL_SET_GET_64_INT:
+        switch ((int) wrq->u.data.flags) {
+        case WOAL_ECL_SYS_CLOCK:
+            ret = woal_ecl_sys_clock(priv, wrq);
+            break;
+        }
+        break;
+
+    case WOAL_HOST_CMD:
+        ret = woal_host_command(priv, wrq);
+        break;
+    case WOAL_ARP_FILTER:
+        ret = woal_arp_filter(priv, wrq);
+        break;
+    case WOAL_SET_INTS_GET_CHARS:
+        switch ((int) wrq->u.data.flags) {
+        case WOAL_READ_EEPROM:
+            ret = woal_read_eeprom(priv, wrq);
+            break;
+        }
+        break;
+    case WOAL_SET_GET_2K_BYTES:
+        switch ((int) wrq->u.data.flags) {
+        case WOAL_CMD_52RDWR:
+            ret = woal_cmd52rdwr_ioctl(priv, wrq);
+            break;
+        case WOAL_CMD_53RDWR:
+            ret = woal_cmd53rdwr_ioctl(priv, wrq);
+            break;
+        case WOAL_SET_USER_SCAN:
+            ret = woal_set_user_scan_ioctl(priv, wrq);
+            break;
+        case WOAL_GET_SCAN_TABLE:
+            ret = woal_get_scan_table_ioctl(priv, wrq);
+            break;
+        case WOAL_VSIE_CFG:
+            ret = woal_vsie_cfg_ioctl(priv, wrq);
+            break;
+        case WOAL_WMM_ADDTS:
+            ret = woal_wmm_addts_req_ioctl(priv, wrq);
+            break;
+        case WOAL_WMM_DELTS:
+            ret = woal_wmm_delts_req_ioctl(priv, wrq);
+            break;
+        case WOAL_WMM_QUEUE_CONFIG:
+            ret = woal_wmm_queue_config_ioctl(priv, wrq);
+            break;
+        case WOAL_WMM_QUEUE_STATS:
+            ret = woal_wmm_queue_stats_ioctl(priv, wrq);
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        break;
+
+    case WOAL_GET_BSS_TYPE:
+        ret = woal_get_bss_type(dev, req);
+        break;
+    default:
+        ret = -EINVAL;
+        break;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Send get FW info request to MLAN
+ *   
+ *  @param priv  A pointer to moal_private structure
+ *
+ *  @return      None
+ */
+void
+woal_request_get_fw_info(moal_private * priv)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_get_info *info;
+    mlan_status status;
+    ENTER();
+    memset(priv->current_addr, 0xff, ETH_ALEN);
+
+    /* Allocate an IOCTL request buffer */
+    req = (mlan_ioctl_req *) woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        status = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    info = (mlan_ds_get_info *) req->pbuf;
+    req->req_id = MLAN_IOCTL_GET_INFO;
+    req->action = MLAN_ACT_GET;
+    info->sub_command = MLAN_OID_GET_FW_INFO;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, MOAL_CMD_WAIT);
+    if (status == MLAN_STATUS_SUCCESS) {
+        priv->phandle->fw_release_number = info->param.fw_info.fw_ver;
+        if (priv->current_addr[0] == 0xff)
+            memcpy(priv->current_addr, &info->param.fw_info.mac_addr,
+                   sizeof(mlan_802_11_mac_addr));
+        memcpy(priv->netdev->dev_addr, priv->current_addr, ETH_ALEN);
+        DBG_HEXDUMP(MIF_D, "mac", priv->current_addr, 6);
+    } else
+        PRINTM(MERROR, "get fw info failed! status=%d, error_code=0x%lx\n",
+               status, req->status_code);
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return;
+}
+
+/** 
+ *  @brief Get mode
+ *
+ *  @param priv          A pointer to moal_private structure
+ *  @param wait_option   Wait option (MOAL_WAIT or MOAL_NO_WAIT)   
+ *
+ *  @return              Wireless mode
+ */
+t_u32
+woal_get_mode(moal_private * priv, t_u8 wait_option)
+{
+    int ret = 0;
+    mlan_ds_bss *bss = NULL;
+    mlan_ioctl_req *req = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    t_u32 mode = priv->w_stats.status;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_BSS_MODE;
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS) {
+        switch (bss->param.bss_mode) {
+        case MLAN_BSS_MODE_INFRA:
+            mode = IW_MODE_INFRA;
+            break;
+        case MLAN_BSS_MODE_IBSS:
+            mode = IW_MODE_ADHOC;
+            break;
+        default:
+            mode = IW_MODE_AUTO;
+            break;
+        }
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return mode;
+}
+
+/** 
+ *  @brief Get RSSI info
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wait_option  Wait option
+ *  @param signal       A pointer tp mlan_ds_get_signal structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_signal_info(moal_private * priv, t_u8 wait_option,
+                     mlan_ds_get_signal * signal)
+{
+    int ret = 0;
+    mlan_ds_get_info *info = NULL;
+    mlan_ioctl_req *req = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    info = (mlan_ds_get_info *) req->pbuf;
+    info->sub_command = MLAN_OID_GET_SIGNAL;
+    info->param.signal.selector = ALL_RSSI_INFO_MASK;
+    req->req_id = MLAN_IOCTL_GET_INFO;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS) {
+        if (signal)
+            memcpy(signal, &info->param.signal, sizeof(mlan_ds_get_signal));
+        if (info->param.signal.selector & BCN_RSSI_AVG_MASK)
+            priv->w_stats.qual.level = info->param.signal.bcn_rssi_avg;
+        if (info->param.signal.selector & BCN_NF_AVG_MASK)
+            priv->w_stats.qual.noise = info->param.signal.bcn_nf_avg;
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get statistics information
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wait_option  Wait option
+ *  @param stats        A pointer to mlan_ds_get_stats structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_stats_info(moal_private * priv, t_u8 wait_option,
+                    mlan_ds_get_stats * stats)
+{
+    int ret = 0;
+    mlan_ds_get_info *info = NULL;
+    mlan_ioctl_req *req = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_get_info));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    info = (mlan_ds_get_info *) req->pbuf;
+    info->sub_command = MLAN_OID_GET_STATS;
+    req->req_id = MLAN_IOCTL_GET_INFO;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS) {
+        if (stats)
+            memcpy(stats, &info->param.stats, sizeof(mlan_ds_get_stats));
+        priv->w_stats.discard.fragment = info->param.stats.fcs_error;
+        priv->w_stats.discard.retries = info->param.stats.retry;
+        priv->w_stats.discard.misc = info->param.stats.ack_failure;
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get data rates
+ *
+ *  @param priv          A pointer to moal_private structure
+ *  @param wait_option   Wait option
+ *  @param m_rates       A pointer to moal_802_11_rates structure
+ *
+ *  @return              MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_data_rates(moal_private * priv, t_u8 wait_option,
+                    moal_802_11_rates * m_rates)
+{
+    int ret = 0;
+    mlan_ds_rate *rate = NULL;
+    mlan_ioctl_req *req = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    rate = (mlan_ds_rate *) req->pbuf;
+    rate->sub_command = MLAN_OID_SUPPORTED_RATES;
+    req->req_id = MLAN_IOCTL_RATE;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS) {
+        if (m_rates)
+            m_rates->num_of_rates =
+                woal_copy_rates(m_rates->rates, m_rates->num_of_rates,
+                                rate->param.rates, MLAN_SUPPORTED_RATES);
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get channel list
+ *
+ *  @param priv            A pointer to moal_private structure
+ *  @param wait_option     Wait option
+ *  @param chan_list       A pointer to mlan_chan_list structure
+ *
+ *  @return                MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_channel_list(moal_private * priv, t_u8 wait_option,
+                      mlan_chan_list * chan_list)
+{
+    int ret = 0;
+    mlan_ds_bss *bss = NULL;
+    mlan_ioctl_req *req = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_BSS_CHANNEL_LIST;
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS) {
+        if (chan_list) {
+            memcpy(chan_list, &bss->param.chanlist, sizeof(mlan_chan_list));
+        }
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get scan table
+ *
+ *  @param priv         A pointer to moal_private structure
+ *  @param wait_option  Wait option
+ *  @param scan_resp    A pointer to mlan_scan_resp structure
+ *
+ *  @return             MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_scan_table(moal_private * priv, t_u8 wait_option,
+                    mlan_scan_resp * scan_resp)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_scan *scan = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    scan = (mlan_ds_scan *) req->pbuf;
+    scan->sub_command = MLAN_OID_SCAN_NORMAL;
+    req->req_id = MLAN_IOCTL_SCAN;
+    req->action = MLAN_ACT_GET;
+    memcpy((void *) &scan->param.scan_resp, (void *) scan_resp,
+           sizeof(mlan_scan_resp));
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS) {
+        if (scan_resp) {
+            memcpy(scan_resp, &scan->param.scan_resp, sizeof(mlan_scan_resp));
+        }
+    }
+
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set authentication mode
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param auth_mode            Authentication mode
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_set_auth_mode(moal_private * priv, t_u8 wait_option, t_u32 auth_mode)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_AUTH_MODE;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_SET;
+    sec->param.auth_mode = auth_mode;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get authentication mode
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param auth_mode            A pointer to authentication mode
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_auth_mode(moal_private * priv, t_u8 wait_option, t_u32 * auth_mode)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_AUTH_MODE;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS && auth_mode) {
+        *auth_mode = sec->param.auth_mode;
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set encrypt mode
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param encrypt_mode         Encryption mode
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_set_encrypt_mode(moal_private * priv, t_u8 wait_option, t_u32 encrypt_mode)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_MODE;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_SET;
+    sec->param.encrypt_mode = encrypt_mode;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get encrypt mode
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param encrypt_mode         A pointer to encrypt mode
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_encrypt_mode(moal_private * priv, t_u8 wait_option,
+                      t_u32 * encrypt_mode)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_MODE;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS && encrypt_mode) {
+        *encrypt_mode = sec->param.encrypt_mode;
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Set wpa enable
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param enable               MTRUE or MFALSE
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_set_wpa_enable(moal_private * priv, t_u8 wait_option, t_u32 enable)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_WPA_ENABLED;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_SET;
+    sec->param.wpa_enabled = enable;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Get WPA enable
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param enable               A pointer to wpa enable status
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_get_wpa_enable(moal_private * priv, t_u8 wait_option, t_u32 * enable)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_WPA_ENABLED;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+    if (status == MLAN_STATUS_SUCCESS && enable) {
+        *enable = sec->param.wpa_enabled;
+    }
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Find the best network to associate
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option  
+ *  @param ssid_bssid           A pointer to mlan_ssid_bssid structure
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_find_best_network(moal_private * priv, t_u8 wait_option,
+                       mlan_ssid_bssid * ssid_bssid)
+{
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_bss *bss = NULL;
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    t_u8 *mac = 0;
+
+    ENTER();
+
+    if (!ssid_bssid) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    bss = (mlan_ds_bss *) req->pbuf;
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_GET;
+    bss->sub_command = MLAN_OID_BSS_FIND_BSS;
+
+    memcpy(&bss->param.ssid_bssid, ssid_bssid, sizeof(mlan_ssid_bssid));
+
+    /* Send IOCTL request to MLAN */
+    ret = woal_request_ioctl(priv, req, wait_option);
+    if (ret == MLAN_STATUS_SUCCESS) {
+        memcpy(ssid_bssid, &bss->param.ssid_bssid, sizeof(mlan_ssid_bssid));
+        mac = (t_u8 *) & ssid_bssid->bssid;
+        PRINTM(MCMND, "Find network: ssid=%s, %02x:%02x:%02x:%02x:%02x:%02x\n",
+               ssid_bssid->ssid.ssid, mac[0], mac[1], mac[2], mac[3], mac[4],
+               mac[5]);
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Request a scan
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option  
+ *  @param req_ssid             A pointer to mlan_802_11_ssid structure
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_request_scan(moal_private * priv,
+                  t_u8 wait_option, mlan_802_11_ssid * req_ssid)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_ioctl_req *ioctl_req = NULL;
+    mlan_ds_scan *scan = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    if (MOAL_ACQ_SEMAPHORE_BLOCK(&priv->async_sem)) {
+        PRINTM(MERROR, "Acquire semaphore error, request_scan\n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    priv->scan_pending_on_block = MTRUE;
+
+    /* Allocate an IOCTL request buffer */
+    ioctl_req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_scan));
+    if (ioctl_req == NULL) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    scan = (mlan_ds_scan *) ioctl_req->pbuf;
+
+    if (req_ssid && req_ssid->ssid_len != 0) {
+        /* Specific SSID scan */
+        ioctl_req->req_id = MLAN_IOCTL_SCAN;
+        ioctl_req->action = MLAN_ACT_SET;
+
+        scan->sub_command = MLAN_OID_SCAN_SPECIFIC_SSID;
+
+        memcpy(scan->param.scan_req.scan_ssid.ssid,
+               req_ssid->ssid, req_ssid->ssid_len);
+        scan->param.scan_req.scan_ssid.ssid_len = req_ssid->ssid_len;
+    } else {
+        /* Normal scan */
+        ioctl_req->req_id = MLAN_IOCTL_SCAN;
+        ioctl_req->action = MLAN_ACT_SET;
+
+        scan->sub_command = MLAN_OID_SCAN_NORMAL;
+    }
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, ioctl_req, wait_option);
+    if (status == MLAN_STATUS_FAILURE) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+  done:
+    if ((ioctl_req) && (status != MLAN_STATUS_PENDING))
+        kfree(ioctl_req);
+    if (ret == MLAN_STATUS_FAILURE) {
+        priv->scan_pending_on_block = MFALSE;
+        MOAL_REL_SEMAPHORE(&priv->async_sem);
+    }
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Set ewpa mode
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *  @param ssid_bssid           A pointer to mlan_ssid_bssid structure
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_set_ewpa_mode(moal_private * priv, t_u8 wait_option,
+                   mlan_ssid_bssid * ssid_bssid)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto error;
+    }
+    /* Fill request buffer */
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_PASSPHRASE;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_GET;
+
+    /* Try Get All */
+    memset(&sec->param.passphrase, 0, sizeof(mlan_ds_passphrase));
+    memcpy(&sec->param.passphrase.ssid, &ssid_bssid->ssid,
+           sizeof(sec->param.passphrase.ssid));
+    memcpy(&sec->param.passphrase.bssid, &ssid_bssid->bssid,
+           MLAN_MAC_ADDR_LENGTH);
+    sec->param.passphrase.psk_type = MLAN_PSK_QUERY;
+
+    /* Send IOCTL request to MLAN */
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, wait_option))
+        goto error;
+    sec->param.ewpa_enabled = MFALSE;
+    if (sec->param.passphrase.psk_type == MLAN_PSK_PASSPHRASE) {
+        if (sec->param.passphrase.psk.passphrase.passphrase_len > 0) {
+            sec->param.ewpa_enabled = MTRUE;
+        }
+    } else if (sec->param.passphrase.psk_type == MLAN_PSK_PMK)
+        sec->param.ewpa_enabled = MTRUE;
+
+    sec->sub_command = MLAN_OID_SEC_CFG_EWPA_ENABLED;
+    req->action = MLAN_ACT_SET;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+
+  error:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief Change Adhoc Channel
+ *   
+ *  @param priv 		A pointer to moal_private structure
+ *  @param channel		The channel to be set. 
+ *
+ *  @return 	   		MLAN_STATUS_SUCCESS--success, MLAN_STATUS_FAILURE--fail
+ */
+mlan_status
+woal_change_adhoc_chan(moal_private * priv, int channel)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+    mlan_bss_info bss_info;
+    mlan_ds_bss *bss = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    memset(&bss_info, 0, sizeof(bss_info));
+
+    /* Get BSS information */
+    if (MLAN_STATUS_SUCCESS !=
+        woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    if (bss_info.bss_mode == MLAN_BSS_MODE_INFRA) {
+        ret = MLAN_STATUS_SUCCESS;
+        goto done;
+    }
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Get current channel */
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_IBSS_CHANNEL;
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_GET;
+
+    /* Send IOCTL request to MLAN */
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    if (bss->param.bss_chan.channel == channel) {
+        ret = MLAN_STATUS_SUCCESS;
+        goto done;
+    }
+    PRINTM(MCMND, "Updating Channel from %d to %d\n",
+           (int) bss->param.bss_chan.channel, channel);
+
+    if (bss_info.media_connected != MTRUE) {
+        ret = MLAN_STATUS_SUCCESS;
+        goto done;
+    }
+
+    /* Do disonnect */
+    bss->sub_command = MLAN_OID_BSS_STOP;
+    memset((t_u8 *) & bss->param.bssid, 0, ETH_ALEN);
+
+    /* Send IOCTL request to MLAN */
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+
+    /* Do specific SSID scanning */
+    if (MLAN_STATUS_SUCCESS !=
+        woal_request_scan(priv, MOAL_IOCTL_WAIT, &bss_info.ssid)) {
+        ret = MLAN_STATUS_FAILURE;
+        goto done;
+    }
+    /* Start/Join Adhoc network */
+    bss->sub_command = MLAN_OID_BSS_START;
+    memset(&bss->param.ssid_bssid, 0, sizeof(mlan_ssid_bssid));
+    memcpy(&bss->param.ssid_bssid.ssid, &bss_info.ssid,
+           sizeof(mlan_802_11_ssid));
+
+    /* Send IOCTL request to MLAN */
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = MLAN_STATUS_FAILURE;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief enable wep key 
+ *  
+ *  @param priv                 A pointer to moal_private structure
+ *  @param wait_option          Wait option
+ *
+ *  @return                     MLAN_STATUS_SUCCESS -- success, otherwise fail          
+ */
+mlan_status
+woal_enable_wep_key(moal_private * priv, t_u8 wait_option)
+{
+    int ret = 0;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    ENTER();
+
+    /* Allocate an IOCTL request buffer */
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    /* Fill request buffer */
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_SET;
+    sec->param.encrypt_key.key_disable = MFALSE;
+    sec->param.encrypt_key.key_len = 0;
+    sec->param.encrypt_key.is_current_wep_key = MTRUE;
+
+    /* Send IOCTL request to MLAN */
+    status = woal_request_ioctl(priv, req, wait_option);
+  done:
+    if (req && (status != MLAN_STATUS_PENDING))
+        kfree(req);
+    LEAVE();
+    return status;
+}
+
+#if WIRELESS_EXT > 14
+
+/** 
+ *  @brief This function sends customized event to application.
+ *  
+ *  @param priv    A pointer to moal_private structure
+ *  @param str	   A pointer to event string
+ *
+ *  @return 	   N/A
+ */
+void
+woal_send_iwevcustom_event(moal_private * priv, t_s8 * str)
+{
+    union iwreq_data iwrq;
+    char buf[50];
+
+    ENTER();
+
+    memset(&iwrq, 0, sizeof(union iwreq_data));
+    memset(buf, 0, sizeof(buf));
+
+    snprintf(buf, sizeof(buf) - 1, "%s", str);
+
+    iwrq.data.pointer = buf;
+    iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;
+
+    /* Send Event to upper layer */
+    wireless_send_event(priv->netdev, IWEVCUSTOM, &iwrq, buf);
+    PRINTM(MINFO, "Wireless event %s is sent to application\n", str);
+
+    LEAVE();
+    return;
+}
+#endif
+
+#if WIRELESS_EXT >= 18
+/** 
+ *  @brief This function sends mic error event to application.
+ *  
+ *  @param priv    A pointer to moal_private structure
+ *  @param event   MIC MERROR EVENT. 
+ *
+ *  @return 	   N/A
+ */
+void
+woal_send_mic_error_event(moal_private * priv, t_u32 event)
+{
+    union iwreq_data iwrq;
+    struct iw_michaelmicfailure mic;
+
+    ENTER();
+
+    memset(&iwrq, 0, sizeof(iwrq));
+    memset(&mic, 0, sizeof(mic));
+    if (event == MLAN_EVENT_ID_FW_MIC_ERR_UNI)
+        mic.flags = IW_MICFAILURE_PAIRWISE;
+    else
+        mic.flags = IW_MICFAILURE_GROUP;
+    iwrq.data.pointer = &mic;
+    iwrq.data.length = sizeof(mic);
+
+    wireless_send_event(priv->netdev, IWEVMICHAELMICFAILURE, &iwrq,
+                        (char *) &mic);
+
+    LEAVE();
+    return;
+}
+#endif
+
+/** 
+ *  @brief Handle ioctl resp 
+ *   
+ *  @param priv 	Pointer to moal_private structure
+ *  @param req		Pointer to mlan_ioctl_req structure
+ *
+ *  @return    		N/A
+ */
+void
+woal_process_ioctl_resp(moal_private * priv, mlan_ioctl_req * req)
+{
+    ENTER();
+
+    if (priv == NULL)
+        return;
+    switch (req->req_id) {
+    case MLAN_IOCTL_GET_INFO:
+        woal_ioctl_get_info_resp(priv, (mlan_ds_get_info *) req->pbuf);
+        break;
+    case MLAN_IOCTL_BSS:
+        woal_ioctl_get_bss_resp(priv, (mlan_ds_bss *) req->pbuf);
+    default:
+        break;
+    }
+
+    LEAVE();
+    return;
+}
diff --git a/wlan_src/mlinux/moal_priv.h b/wlan_src/mlinux/moal_priv.h
new file mode 100755
index 0000000..e408f95
--- /dev/null
+++ b/wlan_src/mlinux/moal_priv.h
@@ -0,0 +1,625 @@
+/** @file moal_priv.h
+ *
+ * @brief This file contains definition for extended private IOCTL call.
+ *  
+ * Copyright (C) 2008-2009, Marvell International Ltd.  
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/********************************************************
+Change log:
+    10/31/2008: initial version
+********************************************************/
+
+#ifndef _WOAL_PRIV_H_
+#define _WOAL_PRIV_H_
+
+/** Offset for subcommand */
+#define SUBCMD_OFFSET               4
+
+/** Command disabled */
+#define	CMD_DISABLED				0
+/** Command enabled */
+#define	CMD_ENABLED				1
+/** Command get */
+#define	CMD_GET					2
+
+/** 2K bytes */
+#define WOAL_2K_BYTES       2000
+
+/** PRIVATE CMD ID */
+#define WOAL_IOCTL                  0x8BE0
+
+/** Private command ID to set one int/get word char */
+#define WOAL_SETONEINT_GETWORDCHAR  (WOAL_IOCTL + 1)
+/** Private command ID to get version */
+#define WOAL_VERSION                1
+/** Private command ID to get extended version */
+#define WOAL_VEREXT                 2
+
+/** Private command ID to set/get none */
+#define WOAL_SETNONE_GETNONE        (WOAL_IOCTL + 2)
+/** Private command ID for warm reset */
+#define WOAL_WARMRESET              1
+
+/** Private command ID to set/get sixteen int */
+#define WOAL_SET_GET_SIXTEEN_INT    (WOAL_IOCTL + 3)
+/** Private command ID to set/get TX power configurations */
+#define WOAL_TX_POWERCFG            1
+#ifdef DEBUG_LEVEL1
+/** Private command ID to set/get driver debug */
+#define WOAL_DRV_DBG                2
+#endif
+/** Private command ID to set/get beacon interval */
+#define WOAL_BEACON_INTERVAL        3
+/** Private command ID to set/get ATIM window */
+#define WOAL_ATIM_WINDOW            4
+/** Private command ID to get RSSI */
+#define WOAL_SIGNAL                 5
+/** Private command ID to set/get Deep Sleep mode */
+#define WOAL_DEEP_SLEEP             7
+/** Private command ID for 11n ht configration */
+#define WOAL_11N_TX_CFG             8
+/** Private command ID for 11n usr ht configration */
+#define WOAL_11N_HTCAP_CFG          9
+/** Private command ID for TX Aggregation */
+#define WOAL_PRIO_TBL               10
+/** Private command ID for Updating ADDBA variables */
+#define WOAL_ADDBA_UPDT             11
+/** Private command ID to set/get Host Sleep configuration */
+#define WOAL_HS_CFG                 12
+/** Private command ID to set Host Sleep parameters */
+#define WOAL_HS_SETPARA             13
+/** Private command ID to read/write registers */
+#define WOAL_REG_READ_WRITE         14
+/** Private command ID to set/get band/adhocband */
+#define WOAL_BAND_CFG               15
+/** Private command ID to set/get BCA timeshare */
+#define	WOAL_BCA_TIME_SHARE         16
+/** Private command ID for TX Aggregation */
+#define WOAL_11N_AMSDU_AGGR_CTRL    17
+/** Private command ID to set/get Inactivity timeout */
+#define WOAL_INACTIVITY_TIMEOUT_EXT 18
+/** Private command ID to turn on/off sdio clock */
+#define WOAL_SDIO_CLOCK             19
+/** Private command ID to set/get tid multi-port eligibility table */
+#define WOAL_TID_ELIG_TBL           20
+/** Private command ID to set/get scan configuration parameter */
+#define WOAL_SCAN_CFG               21
+/** Private command ID to set/get PS configuration parameter */
+#define WOAL_PS_CFG                 22
+/** Private command ID to read/write memory */
+#define WOAL_MEM_READ_WRITE         23
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+/** Private command ID to control SDIO MP-A */
+#define WOAL_SDIO_MPA_CTRL          25
+#endif
+/** Private command ID for Updating ADDBA variables */
+#define WOAL_ADDBA_REJECT           27
+/** Private command ID to set/get sleep parameters */
+#define WOAL_SLEEP_PARAMS           28
+
+#ifdef MFG_CMD_SUPPORT
+/** Private command ID for MFG command support */
+#define	WOAL_MFG_CMD                (WOAL_IOCTL + 4)
+#endif
+
+/** Private command ID to set one int/get one int */
+#define WOAL_SETONEINT_GETONEINT    (WOAL_IOCTL + 5)
+/** Private command ID to set/get Tx rate */
+#define WOAL_SET_GET_TXRATE         1
+/** Private command ID to set/get region code */
+#define WOAL_SET_GET_REGIONCODE     2
+/** Private command ID to turn on/off radio */
+#define WOAL_SET_RADIO              3
+/** Private command ID to enable WMM */
+#define WOAL_WMM_ENABLE	    	    4
+/** Private command ID to enable 802.11D */
+#define WOAL_11D_ENABLE	    	    5
+/** Private command ID to set/get tx/rx antenna */
+#define WOAL_SET_GET_TX_RX_ANT      6
+/** Private command ID to set/get QoS configuration */
+#define WOAL_SET_GET_QOS_CFG        7
+/** Private command ID to set/get LDO configuration */
+#define WOAL_SET_GET_LDO_CFG        8
+#ifdef REASSOCIATION
+/** Private command ID to set/get reassociation setting */
+#define WOAL_SET_GET_REASSOC        9
+#endif /* REASSOCIATION */
+/** Private command ID for Updating Transmit buffer configration */
+#define WOAL_TXBUF_CFG              10
+/** Private command ID to set/get WWS mode */
+#define	WOAL_SET_GET_WWS_CFG        12
+/** Private command ID to set/get sleep period */
+#define WOAL_SLEEP_PD               13
+/** Private command ID to set/get auth type */
+#define WOAL_AUTH_TYPE              18
+
+/** Private command ID to get log */
+#define WOALGETLOG                  (WOAL_IOCTL + 7)
+
+/** Private command ID to set a wext address variable */
+#define WOAL_SETADDR_GETNONE        (WOAL_IOCTL + 8)
+/** Private command ID to send deauthentication */
+#define WOAL_DEAUTH                 1
+
+/** Private command to get/set 256 chars */
+#define WOAL_SET_GET_256_CHAR       (WOAL_IOCTL + 9)
+/** Private command to read/write passphrase */
+#define WOAL_PASSPHRASE             1
+/** Private command to get/set Ad-Hoc AES */
+#define WOAL_ADHOC_AES              2
+/** Private command ID to get WMM queue status */
+#define WOAL_WMM_QUEUE_STATUS       4
+/** Private command ID to get Traffic stream status */
+#define WOAL_WMM_TS_STATUS          5
+
+/** Get log buffer size */
+#define GETLOG_BUFSIZE              512
+
+/** Private command ID to set none/get twelve chars*/
+#define WOAL_SETNONE_GETTWELVE_CHAR (WOAL_IOCTL + 11)
+/** Private command ID for WPS session */
+#define WOAL_WPS_SESSION            1
+
+/** Private command ID to set none/get four int */
+#define WOAL_SETNONE_GET_FOUR_INT   (WOAL_IOCTL + 13)
+/** Private command ID to get data rates */
+#define WOAL_DATA_RATE              1
+/** Private command ID to get E-Supplicant mode */
+#define WOAL_ESUPP_MODE             2
+
+/** Private command to get/set 64 ints */
+#define WOAL_SET_GET_64_INT         (WOAL_IOCTL + 15)
+/** Private command ID to set/get ECL system clock */
+#define WOAL_ECL_SYS_CLOCK          1
+
+/** Private command ID for hostcmd */
+#define WOAL_HOST_CMD               (WOAL_IOCTL + 17)
+
+/** Private command ID for arpfilter */
+#define WOAL_ARP_FILTER             (WOAL_IOCTL + 19)
+
+/** Private command ID to set ints and get chars */
+#define WOAL_SET_INTS_GET_CHARS     (WOAL_IOCTL + 21)
+/** Private command ID to read EEPROM data */
+#define WOAL_READ_EEPROM            1
+
+/** Private command ID to set/get 2K bytes */
+#define WOAL_SET_GET_2K_BYTES       (WOAL_IOCTL + 23)
+
+/** Private command ID to read/write Command 52 */
+#define WOAL_CMD_52RDWR             1
+/** Private command ID to read/write Command 53 */
+#define WOAL_CMD_53RDWR             2
+
+/** Private command ID for setuserscan */
+#define WOAL_SET_USER_SCAN          3
+/** Private command ID for getscantable */
+#define WOAL_GET_SCAN_TABLE         4
+
+/** Private command ID for vsiecfg */
+#define WOAL_VSIE_CFG               5
+
+/** Private command ID to request ADDTS */
+#define WOAL_WMM_ADDTS              7
+/** Private command ID to request DELTS */
+#define WOAL_WMM_DELTS              8
+/** Private command ID to queue configuration */
+#define WOAL_WMM_QUEUE_CONFIG       9
+/** Private command ID to queue stats */
+#define WOAL_WMM_QUEUE_STATS        10
+
+/** Private command ID to get BSS type */
+#define WOAL_GET_BSS_TYPE           (SIOCDEVPRIVATE + 15)
+
+/**
+ * iwpriv ioctl handlers
+ */
+static const struct iw_priv_args woal_private_args[] = {
+    {
+     WOAL_SETONEINT_GETWORDCHAR,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_CHAR | 128,
+     ""},
+    {
+     WOAL_VERSION,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_CHAR | 128,
+     "version"},
+    {
+     WOAL_VEREXT,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_CHAR | 128,
+     "verext"},
+    {
+     WOAL_SETNONE_GETNONE,
+     IW_PRIV_TYPE_NONE,
+     IW_PRIV_TYPE_NONE,
+     ""},
+    {
+     WOAL_WARMRESET,
+     IW_PRIV_TYPE_NONE,
+     IW_PRIV_TYPE_NONE,
+     "warmreset"},
+    {
+     WOAL_SETONEINT_GETONEINT,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     ""},
+    {
+     WOAL_SET_GET_TXRATE,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "txratecfg"},
+    {
+     WOAL_SET_GET_REGIONCODE,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "regioncode"},
+    {
+     WOAL_SET_RADIO,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "radioctrl"},
+    {
+     WOAL_WMM_ENABLE,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "wmmcfg"},
+    {
+     WOAL_11D_ENABLE,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "11dcfg"},
+    {
+     WOAL_SET_GET_TX_RX_ANT,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "antcfg"},
+    {
+     WOAL_SET_GET_QOS_CFG,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "qoscfg"},
+    {
+     WOAL_SET_GET_LDO_CFG,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "ldocfg"},
+    {
+     WOAL_SET_GET_WWS_CFG,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "wwscfg"},
+#ifdef REASSOCIATION
+    {
+     WOAL_SET_GET_REASSOC,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "reassoctrl"},
+#endif
+    {
+     WOAL_TXBUF_CFG,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "txbufcfg"},
+    {
+     WOAL_SLEEP_PD,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "sleeppd"},
+    {
+     WOAL_AUTH_TYPE,
+     IW_PRIV_TYPE_INT | 1,
+     IW_PRIV_TYPE_INT | 1,
+     "authtype"},
+    {
+     WOAL_SET_GET_SIXTEEN_INT,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     ""},
+    {
+     WOAL_TX_POWERCFG,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "txpowercfg"},
+#ifdef DEBUG_LEVEL1
+    {
+     WOAL_DRV_DBG,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "drvdbg"},
+#endif
+    {
+     WOAL_BEACON_INTERVAL,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "bcninterval"},
+    {
+     WOAL_ATIM_WINDOW,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "atimwindow"},
+    {
+     WOAL_SIGNAL,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "getsignal"},
+    {
+     WOAL_DEEP_SLEEP,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "deepsleep",
+     },
+    {
+     WOAL_11N_TX_CFG,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "httxcfg"},
+    {
+     WOAL_11N_HTCAP_CFG,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "htcapinfo"},
+    {
+     WOAL_PRIO_TBL,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "aggrpriotbl"},
+    {
+     WOAL_11N_AMSDU_AGGR_CTRL,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "amsduaggrctrl"},
+    {
+     WOAL_ADDBA_UPDT,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "addbapara"},
+    {
+     WOAL_ADDBA_REJECT,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "addbareject"},
+    {
+     WOAL_HS_CFG,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "hscfg"},
+    {
+     WOAL_HS_SETPARA,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "hssetpara"},
+    {
+     WOAL_REG_READ_WRITE,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "regrdwr"},
+    {
+     WOAL_BAND_CFG,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "bandcfg"},
+    {
+     WOAL_INACTIVITY_TIMEOUT_EXT,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "inactivityto"},
+    {
+     WOAL_SDIO_CLOCK,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "sdioclock"},
+    {
+     WOAL_BCA_TIME_SHARE,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "bcats"},
+    {
+     WOAL_TID_ELIG_TBL,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "tideligtbl"},
+    {
+     WOAL_SCAN_CFG,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "scancfg"},
+    {
+     WOAL_PS_CFG,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "pscfg"},
+    {
+     WOAL_MEM_READ_WRITE,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "memrdwr"},
+#if defined(SDIO_MULTI_PORT_TX_AGGR) || defined(SDIO_MULTI_PORT_RX_AGGR)
+    {
+     WOAL_SDIO_MPA_CTRL,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "mpactrl"},
+#endif
+    {
+     WOAL_SLEEP_PARAMS,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_INT | 16,
+     "sleepparams"},
+    {
+     WOALGETLOG,
+     IW_PRIV_TYPE_NONE,
+     IW_PRIV_TYPE_CHAR | GETLOG_BUFSIZE,
+     "getlog"},
+    {
+     WOAL_SETADDR_GETNONE,
+     IW_PRIV_TYPE_ADDR | 1,
+     IW_PRIV_TYPE_NONE,
+     ""},
+    {
+     WOAL_DEAUTH,
+     IW_PRIV_TYPE_ADDR | 1,
+     IW_PRIV_TYPE_NONE,
+     "deauth"},
+    {
+     WOAL_SET_GET_256_CHAR,
+     IW_PRIV_TYPE_CHAR | 256,
+     IW_PRIV_TYPE_CHAR | 256,
+     ""},
+    {
+     WOAL_PASSPHRASE,
+     IW_PRIV_TYPE_CHAR | 256,
+     IW_PRIV_TYPE_CHAR | 256,
+     "passphrase"},
+    {
+     WOAL_ADHOC_AES,
+     IW_PRIV_TYPE_CHAR | 256,
+     IW_PRIV_TYPE_CHAR | 256,
+     "adhocaes"},
+    {
+     WOAL_WMM_QUEUE_STATUS,
+     IW_PRIV_TYPE_CHAR | 256,
+     IW_PRIV_TYPE_CHAR | 256,
+     "qstatus"},
+    {
+     WOAL_WMM_TS_STATUS,
+     IW_PRIV_TYPE_CHAR | 256,
+     IW_PRIV_TYPE_CHAR | 256,
+     "ts_status"},
+    {
+     WOAL_SETNONE_GETTWELVE_CHAR,
+     IW_PRIV_TYPE_NONE,
+     IW_PRIV_TYPE_CHAR | 12,
+     ""},
+    {
+     WOAL_WPS_SESSION,
+     IW_PRIV_TYPE_NONE,
+     IW_PRIV_TYPE_CHAR | 12,
+     "wpssession"},
+    {
+     WOAL_SETNONE_GET_FOUR_INT,
+     IW_PRIV_TYPE_NONE,
+     IW_PRIV_TYPE_INT | 4,
+     ""},
+    {
+     WOAL_DATA_RATE,
+     IW_PRIV_TYPE_NONE,
+     IW_PRIV_TYPE_INT | 4,
+     "getdatarate"},
+    {
+     WOAL_ESUPP_MODE,
+     IW_PRIV_TYPE_NONE,
+     IW_PRIV_TYPE_INT | 4,
+     "esuppmode"},
+    {
+     WOAL_SET_GET_64_INT,
+     IW_PRIV_TYPE_INT | 64,
+     IW_PRIV_TYPE_INT | 64,
+     ""},
+    {
+     WOAL_ECL_SYS_CLOCK,
+     IW_PRIV_TYPE_INT | 64,
+     IW_PRIV_TYPE_INT | 64,
+     "sysclock"},
+    {
+     WOAL_HOST_CMD,
+     IW_PRIV_TYPE_BYTE | 2047,
+     IW_PRIV_TYPE_BYTE | 2047,
+     "hostcmd"},
+    {
+     WOAL_ARP_FILTER,
+     IW_PRIV_TYPE_BYTE | 2047,
+     IW_PRIV_TYPE_BYTE | 2047,
+     "arpfilter"},
+    {
+     WOAL_SET_INTS_GET_CHARS,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_BYTE | 256,
+     ""},
+    {
+     WOAL_READ_EEPROM,
+     IW_PRIV_TYPE_INT | 16,
+     IW_PRIV_TYPE_BYTE | 256,
+     "rdeeprom"},
+    {
+     WOAL_SET_GET_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     ""},
+    {
+     WOAL_CMD_52RDWR,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     "sdcmd52rw"},
+    {
+     WOAL_CMD_53RDWR,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     "sdcmd53rw"},
+    {
+     WOAL_SET_USER_SCAN,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     "setuserscan"},
+    {
+     WOAL_GET_SCAN_TABLE,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     "getscantable"},
+    {
+     WOAL_VSIE_CFG,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     "vsiecfg"},
+    {
+     WOAL_WMM_ADDTS,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     "addts"},
+    {
+     WOAL_WMM_DELTS,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     "delts"},
+    {
+     WOAL_WMM_QUEUE_CONFIG,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     "qconfig"},
+    {
+     WOAL_WMM_QUEUE_STATS,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     IW_PRIV_TYPE_BYTE | WOAL_2K_BYTES,
+     "qstats"},
+};
+
+/** Auto Rate */
+#define AUTO_RATE 0xFF
+
+/** moal_802_11_rates  */
+typedef struct _moal_802_11_rates
+{
+        /** Num of rates */
+    t_u8 num_of_rates;
+        /** Rates */
+    t_u8 rates[MLAN_SUPPORTED_RATES];
+} moal_802_11_rates;
+
+int woal_do_ioctl(struct net_device *dev, struct ifreq *req, int i);
+#endif /* _WOAL_PRIV_H_ */
diff --git a/wlan_src/mlinux/moal_proc.c b/wlan_src/mlinux/moal_proc.c
new file mode 100755
index 0000000..e1244b1
--- /dev/null
+++ b/wlan_src/mlinux/moal_proc.c
@@ -0,0 +1,337 @@
+/**  @file moal_proc.c
+  *
+  * @brief This file contains functions for proc file.
+  * 
+  * Copyright (C) 2008-2009, Marvell International Ltd. 
+  *
+  * This software file (the "File") is distributed by Marvell International 
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+  * (the "License").  You may use, redistribute and/or modify this File in 
+  * accordance with the terms and conditions of the License, a copy of which 
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+  * this warranty disclaimer.
+  *
+  */
+
+/********************************************************
+Change log:
+    10/21/2008: initial version
+********************************************************/
+
+#include	"moal_main.h"
+
+/********************************************************
+		Local Variables
+********************************************************/
+#ifdef CONFIG_PROC_FS
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#define PROC_DIR	NULL
+#define MWLAN_PROC_DIR  "mwlan/"
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#define PROC_DIR	&proc_root
+#else
+#define PROC_DIR	proc_net
+#endif
+
+static char *szModes[] = {
+    "Ad-hoc",
+    "Managed",
+    "Auto",
+    "Unknown"
+};
+
+extern int drv_mode;
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/********************************************************
+		Local Functions
+********************************************************/
+/** 
+ *  @brief Proc read function for info
+ *
+ *  @param page	   Pointer to buffer
+ *  @param start   Read data starting position
+ *  @param offset  Offset
+ *  @param count   Counter 
+ *  @param eof     End of file flag
+ *  @param data    Data to output
+ *
+ *  @return 	   Number of output data
+ */
+static int
+woal_info_proc_read(char *page, char **start, off_t offset,
+                    int count, int *eof, void *data)
+{
+    char *p = page;
+    struct net_device *netdev = data;
+    char fmt[64];
+    moal_private *priv = (moal_private *) netdev_priv(netdev);
+    int i;
+    moal_handle *handle = priv->phandle;
+    mlan_bss_info info;
+    struct dev_mc_list *mcptr = netdev->mc_list;
+
+    if (offset) {
+        *eof = 1;
+        goto exit;
+    }
+    if (priv->bss_type == MLAN_BSS_TYPE_STA) {
+        woal_get_version(handle, fmt, sizeof(fmt) - 1);
+        memset(&info, 0, sizeof(info));
+        if (MLAN_STATUS_SUCCESS !=
+            woal_get_bss_info(priv, MOAL_PROC_WAIT, &info)) {
+            *eof = 1;
+            goto exit;
+        }
+        p += sprintf(p, "driver_name = " "\"wlan\"\n");
+    }
+    p += sprintf(p, "driver_version = %s", fmt);
+    p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
+    if (priv->bss_type == MLAN_BSS_TYPE_STA)
+        p += sprintf(p, "bss_mode=\"%s\"\n", szModes[info.bss_mode]);
+    p += sprintf(p, "media_state=\"%s\"\n",
+                 ((priv->media_connected ==
+                   MFALSE) ? "Disconnected" : "Connected"));
+    p += sprintf(p, "mac_address=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
+                 netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
+                 netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+    if (priv->bss_type == MLAN_BSS_TYPE_STA) {
+        p += sprintf(p, "multicast_count=\"%d\"\n", netdev->mc_count);
+        p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
+        p += sprintf(p, "bssid=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
+                     info.bssid[0], info.bssid[1],
+                     info.bssid[2], info.bssid[3],
+                     info.bssid[4], info.bssid[5]);
+        p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
+        p += sprintf(p, "region_code = \"%02x\"\n", (t_u8) info.region_code);
+
+        /* 
+         * Put out the multicast list 
+         */
+        for (i = 0; i < netdev->mc_count; i++) {
+            p += sprintf(p,
+                         "multicast_address[%d]=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
+                         i,
+                         mcptr->dmi_addr[0], mcptr->dmi_addr[1],
+                         mcptr->dmi_addr[2], mcptr->dmi_addr[3],
+                         mcptr->dmi_addr[4], mcptr->dmi_addr[5]);
+
+            mcptr = mcptr->next;
+        }
+    }
+    p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
+    p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
+    p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
+    p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
+    p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
+    p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
+    p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
+    p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
+    p += sprintf(p, "carrier %s\n",
+                 ((netif_carrier_ok(priv->netdev)) ? "on" : "off"));
+    p += sprintf(p, "tx queue %s\n",
+                 ((netif_queue_stopped(priv->netdev)) ? "stopped" : "started"));
+  exit:
+    return (p - page);
+}
+
+/********************************************************
+		Global Functions
+********************************************************/
+/** 
+ *  @brief Convert string to number
+ *
+ *  @param s   	   Pointer to numbered string
+ *
+ *  @return 	   Converted number from string s
+ */
+int
+woal_string_to_number(char *s)
+{
+    int r = 0;
+    int base = 0;
+    int pn = 1;
+
+    if (!strncmp(s, "-", 1)) {
+        pn = -1;
+        s++;
+    }
+    if (!strncmp(s, "0x", 2) || !strncmp(s, "0X", 2)) {
+        base = 16;
+        s += 2;
+    } else
+        base = 10;
+
+    for (s = s; *s; s++) {
+        if ((*s >= '0') && (*s <= '9'))
+            r = (r * base) + (*s - '0');
+        else if ((*s >= 'A') && (*s <= 'F'))
+            r = (r * base) + (*s - 'A' + 10);
+        else if ((*s >= 'a') && (*s <= 'f'))
+            r = (r * base) + (*s - 'a' + 10);
+        else
+            break;
+    }
+
+    return (r * pn);
+}
+
+/** 
+ *  @brief Create the top level proc directory
+ *
+ *  @param handle   Pointer to woal_handle
+ *
+ *  @return 	    N/A
+ */
+void
+woal_proc_init(moal_handle * handle)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
+    struct proc_dir_entry *pde = PROC_DIR;
+#endif
+    ENTER();
+    PRINTM(MINFO, "Create Proc Interface\n");
+    if (!handle->proc_mwlan) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
+        /* Check if directory already exists */
+        for (pde = pde->subdir; pde; pde = pde->next) {
+            if (pde->namelen && !strcmp("mwlan", pde->name)) {
+                /* Directory exists */
+                PRINTM(MWARN, "proc interface already exists!\n");
+                handle->proc_mwlan = pde;
+                break;
+            }
+        }
+        if (pde == NULL) {
+            handle->proc_mwlan = proc_mkdir("mwlan", PROC_DIR);
+            if (!handle->proc_mwlan)
+                PRINTM(MERROR, "Cannot create proc interface!\n");
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+            else
+                atomic_set(&handle->proc_mwlan->count, 1);
+#endif
+        }
+#else
+        handle->proc_mwlan = proc_mkdir("mwlan", PROC_DIR);
+        if (!handle->proc_mwlan) {
+            PRINTM(MERROR, "Cannot create proc interface!\n");
+        }
+#endif
+    }
+
+    LEAVE();
+}
+
+/** 
+ *  @brief Remove the top level proc directory
+ *
+ *  @param handle  pointer moal_handle
+ *
+ *  @return 	   N/A
+ */
+void
+woal_proc_exit(moal_handle * handle)
+{
+    ENTER();
+    PRINTM(MINFO, "Remove Proc Interface\n");
+    if (handle->proc_mwlan) {
+        /* Remove only if we are the only instance using this */
+        if (atomic_read(&(handle->proc_mwlan->count)) > 1) {
+            PRINTM(MWARN, "More than one interface using proc!\n");
+        } else {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+            atomic_dec(&(handle->proc_mwlan->count));
+#endif
+            remove_proc_entry("mwlan", PROC_DIR);
+            handle->proc_mwlan = NULL;
+        }
+    }
+
+    LEAVE();
+}
+
+/** 
+ *  @brief Create proc file for interface
+ *
+ *  @param priv	   pointer moal_private
+ *
+ *  @return 	   N/A
+ */
+void
+woal_create_proc_entry(moal_private * priv)
+{
+    struct net_device *dev = priv->netdev;
+    struct proc_dir_entry *r;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+    char proc_dir_name[20];
+#endif
+    ENTER();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+    if (!priv->proc_entry) {
+        memset(proc_dir_name, 0, sizeof(proc_dir_name));
+        strcpy(proc_dir_name, MWLAN_PROC_DIR);
+        strcat(proc_dir_name, dev->name);
+        /* Try to create mwlan/mlanX first */
+        priv->proc_entry = proc_mkdir(proc_dir_name, PROC_DIR);
+        if (priv->proc_entry) {
+            /* Success. Continue normally */
+            if (!priv->phandle->proc_mwlan) {
+                priv->phandle->proc_mwlan = priv->proc_entry->parent;
+            }
+            atomic_inc(&(priv->phandle->proc_mwlan->count));
+        } else {
+            /* Failure. mwlan may not exist. Try to create that first */
+            priv->phandle->proc_mwlan = proc_mkdir("mwlan", PROC_DIR);
+            if (!priv->phandle->proc_mwlan) {
+                /* Failure. Something broken */
+                LEAVE();
+                return;
+            } else {
+                /* Success. Now retry creating mlanX */
+                priv->proc_entry = proc_mkdir(proc_dir_name, PROC_DIR);
+                atomic_inc(&(priv->phandle->proc_mwlan->count));
+            }
+        }
+#else
+    if (priv->phandle->proc_mwlan && !priv->proc_entry) {
+        priv->proc_entry = proc_mkdir(dev->name, priv->phandle->proc_mwlan);
+        atomic_inc(&(priv->phandle->proc_mwlan->count));
+#endif
+        strcpy(priv->proc_entry_name, dev->name);
+        if (priv->proc_entry) {
+            r = create_proc_read_entry("info", 0, priv->proc_entry,
+                                       woal_info_proc_read, dev);
+        }
+    }
+    LEAVE();
+}
+
+/** 
+ *  @brief Remove proc file
+ *
+ *  @param priv	   Pointer moal_private
+ *
+ *  @return 	   N/A
+ */
+void
+woal_proc_remove(moal_private * priv)
+{
+    ENTER();
+    if (priv->phandle->proc_mwlan && priv->proc_entry) {
+        remove_proc_entry("info", priv->proc_entry);
+        remove_proc_entry(priv->proc_entry_name, priv->phandle->proc_mwlan);
+        atomic_dec(&(priv->phandle->proc_mwlan->count));
+        priv->proc_entry = NULL;
+    }
+    LEAVE();
+}
+#endif
diff --git a/wlan_src/mlinux/moal_sdio.h b/wlan_src/mlinux/moal_sdio.h
new file mode 100755
index 0000000..e94a93e
--- /dev/null
+++ b/wlan_src/mlinux/moal_sdio.h
@@ -0,0 +1,94 @@
+/** @file moal_sdio.h
+  *
+  * @brief This file contains definitions for SDIO interface.
+  * driver. 
+  *
+  * Copyright (C) 2008-2009, Marvell International Ltd. 
+  * 
+  * This software file (the "File") is distributed by Marvell International 
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+  * (the "License").  You may use, redistribute and/or modify this File in 
+  * accordance with the terms and conditions of the License, a copy of which 
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+  * this warranty disclaimer.
+  *
+  */
+/****************************************************
+Change log:
+****************************************************/
+
+#ifndef	_MOAL_SDIO_H
+#define	_MOAL_SDIO_H
+
+#include        <linux/mmc/sdio.h>
+#include        <linux/mmc/sdio_ids.h>
+#include        <linux/mmc/sdio_func.h>
+#include        <linux/mmc/card.h>
+
+#include "moal_main.h"
+
+#ifndef BLOCK_MODE
+/** Block mode */
+#define BLOCK_MODE	1
+#endif
+
+#ifndef BYTE_MODE
+/** Byte Mode */
+#define BYTE_MODE	0
+#endif
+
+#ifndef FIXED_ADDRESS
+/** Fixed address mode */
+#define FIXED_ADDRESS	0
+#endif
+
+/** Default firmware name */
+
+#define DEFAULT_FW_NAME "mrvl/sd8787.bin"
+
+#ifndef DEFAULT_FW_NAME
+#define DEFAULT_FW_NAME ""
+#endif
+
+/********************************************************
+		Global Functions
+********************************************************/
+
+/** Function to write register */
+mlan_status woal_write_reg(moal_handle * handle, t_u32 reg, t_u32 data);
+/** Function to read register */
+mlan_status woal_read_reg(moal_handle * handle, t_u32 reg, t_u32 * data);
+/** Function to write data to IO memory */
+mlan_status woal_write_data_sync(moal_handle * handle, mlan_buffer * pmbuf,
+                                 t_u32 port, t_u32 timeout);
+/** Function to read data from IO memory */
+mlan_status woal_read_data_sync(moal_handle * handle, mlan_buffer * pmbuf,
+                                t_u32 port, t_u32 timeout);
+
+/** Register to bus driver function */
+mlan_status woal_bus_register(void);
+/** Unregister from bus driver function */
+void woal_bus_unregister(void);
+
+/** Register device function */
+mlan_status woal_register_dev(moal_handle * handle);
+/** Unregister device function */
+void woal_unregister_dev(moal_handle * handle);
+
+int woal_sdio_set_bus_clock(moal_handle * handle, t_u8 option);
+/** Structure: SDIO MMC card */
+struct sdio_mmc_card
+{
+        /** sdio_func structure pointer */
+    struct sdio_func *func;
+        /** moal_handle structure pointer */
+    moal_handle *handle;
+};
+
+#endif /* _MOAL_SDIO_H */
diff --git a/wlan_src/mlinux/moal_sdio_mmc.c b/wlan_src/mlinux/moal_sdio_mmc.c
new file mode 100755
index 0000000..2224602
--- /dev/null
+++ b/wlan_src/mlinux/moal_sdio_mmc.c
@@ -0,0 +1,396 @@
+/** @file moal_sdio_mmc.c
+ *
+ *  @brief This file contains SDIO MMC IF (interface) module
+ *  related functions.
+ * 
+ * Copyright (C) 2008-2009, Marvell International Ltd. 
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+/****************************************************
+Change log:
+	02/25/09: Initial creation -
+		  This file supports SDIO MMC only
+****************************************************/
+
+#include <linux/firmware.h>
+
+#include "moal_sdio.h"
+
+/** define marvell vendor id */
+#define MARVELL_VENDOR_ID 0x02df
+
+/********************************************************
+		Local Variables
+********************************************************/
+
+/********************************************************
+		Global Variables
+********************************************************/
+
+/********************************************************
+		Local Functions
+********************************************************/
+
+/** 
+ *  @brief This function handles the interrupt.
+ *  
+ *  @param func	   A pointer to the sdio_func structure
+ *  @return 	   None
+ */
+static void
+woal_sdio_interrupt(struct sdio_func *func)
+{
+    moal_handle *handle;
+    struct sdio_mmc_card *card;
+
+    ENTER();
+
+    card = sdio_get_drvdata(func);
+    if (!card || !card->handle) {
+        PRINTM(MINFO,
+               "sdio_mmc_interrupt(func = %p) card or handle is NULL, card=%p\n",
+               func, card);
+        LEAVE();
+        return;
+    }
+    handle = card->handle;
+
+    PRINTM(MINFO, "*** IN SDIO IRQ ***\n");
+    woal_interrupt(handle);
+
+    LEAVE();
+}
+
+/**  @brief This function handles client driver probe.
+ *  
+ *  @param func	   A pointer to sdio_func structure.
+ *  @param id	   A pointer to sdio_device_id structure.
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+static int
+woal_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
+{
+    int ret = MLAN_STATUS_SUCCESS;
+    struct sdio_mmc_card *card = NULL;
+    moal_handle *handle;
+
+    ENTER();
+
+    PRINTM(MINFO, "vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
+           func->vendor, func->device, func->class, func->num);
+
+    card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
+    if (!card) {
+        PRINTM(MFATAL, "Failed to allocate memory in probe function!\n");
+        return -ENOMEM;
+    }
+
+    card->func = func;
+
+    if (NULL == (handle = woal_add_card(card))) {
+        PRINTM(MERROR, "woal_add_card failed\n");
+        kfree(card);
+        ret = MLAN_STATUS_FAILURE;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/**  @brief This function handles client driver remove.
+ *  
+ *  @param func	   A pointer to sdio_func structure.
+ *  @return 	   n/a
+ */
+static void
+woal_sdio_remove(struct sdio_func *func)
+{
+    struct sdio_mmc_card *card;
+
+    ENTER();
+
+    PRINTM(MINFO, "SDIO func=%d\n", func->num);
+
+    if (func) {
+        card = sdio_get_drvdata(func);
+        if (card) {
+            woal_remove_card(card);
+            kfree(card);
+        }
+    }
+
+    LEAVE();
+}
+
+/** Device ID for SD8787 */
+#define SD_DEVICE_ID_8787   (0x9119)
+
+/** WLAN IDs */
+static const struct sdio_device_id wlan_ids[] = {
+    {SDIO_DEVICE(MARVELL_VENDOR_ID, SD_DEVICE_ID_8787)},
+    {},
+};
+
+static struct sdio_driver wlan_sdio = {
+    .name = "wlan_sdio",
+    .id_table = wlan_ids,
+    .probe = woal_sdio_probe,
+    .remove = woal_sdio_remove,
+};
+
+/********************************************************
+		Global Functions
+********************************************************/
+
+/** 
+ *  @brief This function writes data into card register
+ *
+ *  @param handle   A Pointer to the moal_handle structure
+ *  @param reg      Register offset
+ *  @param data     Value
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_write_reg(moal_handle * handle, t_u32 reg, t_u32 data)
+{
+    mlan_status ret = MLAN_STATUS_FAILURE;
+    sdio_writeb(((struct sdio_mmc_card *) handle->card)->func, (t_u8) data, reg,
+                (int *) &ret);
+    return ret;
+}
+
+/** 
+ *  @brief This function reads data from card register
+ *
+ *  @param handle   A Pointer to the moal_handle structure
+ *  @param reg      Register offset
+ *  @param data     Value
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_read_reg(moal_handle * handle, t_u32 reg, t_u32 * data)
+{
+    mlan_status ret = MLAN_STATUS_FAILURE;
+    t_u8 val;
+
+    val =
+        sdio_readb(((struct sdio_mmc_card *) handle->card)->func, reg,
+                   (int *) &ret);
+    *data = val;
+
+    return ret;
+}
+
+/**
+ *  @brief This function writes multiple bytes into card memory
+ *
+ *  @param handle   A Pointer to the moal_handle structure
+ *  @param pmbuf	Pointer to mlan_buffer structure
+ *  @param port		Port
+ *  @param timeout 	Time out value
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_write_data_sync(moal_handle * handle, mlan_buffer * pmbuf, t_u32 port,
+                     t_u32 timeout)
+{
+    mlan_status ret = MLAN_STATUS_FAILURE;
+    t_u8 *buffer = (t_u8 *) (pmbuf->pbuf + pmbuf->data_offset);
+    t_u8 blkmode = (port & MLAN_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
+    t_u32 blksz = (blkmode == BLOCK_MODE) ? MLAN_SDIO_BLOCK_SIZE : 1;
+    t_u32 blkcnt =
+        (blkmode ==
+         BLOCK_MODE) ? (pmbuf->data_len /
+                        MLAN_SDIO_BLOCK_SIZE) : pmbuf->data_len;
+    t_u32 ioport = (port & MLAN_SDIO_IO_PORT_MASK);
+
+    if (!sdio_writesb
+        (((struct sdio_mmc_card *) handle->card)->func, ioport, buffer,
+         blkcnt * blksz))
+        ret = MLAN_STATUS_SUCCESS;
+
+    return ret;
+}
+
+/**
+ *  @brief This function reads multiple bytes from card memory
+ *
+ *  @param handle   A Pointer to the moal_handle structure
+ *  @param pmbuf	Pointer to mlan_buffer structure
+ *  @param port		Port
+ *  @param timeout 	Time out value
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_read_data_sync(moal_handle * handle, mlan_buffer * pmbuf, t_u32 port,
+                    t_u32 timeout)
+{
+    mlan_status ret = MLAN_STATUS_FAILURE;
+    t_u8 *buffer = (t_u8 *) (pmbuf->pbuf + pmbuf->data_offset);
+    t_u8 blkmode = (port & MLAN_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
+    t_u32 blksz = (blkmode == BLOCK_MODE) ? MLAN_SDIO_BLOCK_SIZE : 1;
+    t_u32 blkcnt =
+        (blkmode ==
+         BLOCK_MODE) ? (pmbuf->data_len /
+                        MLAN_SDIO_BLOCK_SIZE) : pmbuf->data_len;
+    t_u32 ioport = (port & MLAN_SDIO_IO_PORT_MASK);
+
+    if (!sdio_readsb
+        (((struct sdio_mmc_card *) handle->card)->func, buffer, ioport,
+         blkcnt * blksz))
+        ret = MLAN_STATUS_SUCCESS;
+
+    return ret;
+}
+
+/** 
+ *  @brief This function registers the IF module in bus driver
+ *  
+ *  @return	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_bus_register(void)
+{
+    mlan_status ret = MLAN_STATUS_SUCCESS;
+
+    ENTER();
+
+    /* SDIO Driver Registration */
+    if (sdio_register_driver(&wlan_sdio)) {
+        PRINTM(MFATAL, "SDIO Driver Registration Failed \n");
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief This function de-registers the IF module in bus driver
+ *  
+ *  @return 	   None
+ */
+void
+woal_bus_unregister(void)
+{
+    ENTER();
+
+    /* SDIO Driver Unregistration */
+    sdio_unregister_driver(&wlan_sdio);
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function de-registers the device
+ *  
+ *  @param handle A pointer to moal_handle structure
+ *  @return 	  None
+ */
+void
+woal_unregister_dev(moal_handle * handle)
+{
+    ENTER();
+    if (handle->card) {
+        /* Release the SDIO IRQ */
+        sdio_claim_host(((struct sdio_mmc_card *) handle->card)->func);
+        sdio_release_irq(((struct sdio_mmc_card *) handle->card)->func);
+        sdio_disable_func(((struct sdio_mmc_card *) handle->card)->func);
+        sdio_release_host(((struct sdio_mmc_card *) handle->card)->func);
+
+        sdio_set_drvdata(((struct sdio_mmc_card *) handle->card)->func, NULL);
+
+        PRINTM(MWARN, "Making the sdio dev card as NULL\n");
+    }
+
+    LEAVE();
+}
+
+/** 
+ *  @brief This function registers the device
+ *  
+ *  @param handle  A pointer to moal_handle structure
+ *  @return 	   MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+woal_register_dev(moal_handle * handle)
+{
+    int ret = MLAN_STATUS_SUCCESS;
+    struct sdio_mmc_card *card = handle->card;
+    struct sdio_func *func;
+
+    ENTER();
+
+    func = card->func;
+    sdio_claim_host(func);
+    ret = sdio_enable_func(func);
+    if (ret) {
+        PRINTM(MFATAL, "sdio_enable_func() failed: ret=%d\n", ret);
+        goto release_host;
+    }
+
+    /* Request the SDIO IRQ */
+    ret = sdio_claim_irq(func, woal_sdio_interrupt);
+    if (ret) {
+        PRINTM(MFATAL, "sdio_claim_irq failed: ret=%d\n", ret);
+        goto disable_func;
+    }
+
+    /* Set block size */
+    ret = sdio_set_block_size(card->func, MLAN_SDIO_BLOCK_SIZE);
+    if (ret) {
+        PRINTM(MERROR, "sdio_set_block_seize(): cannot set SDIO block size\n");
+        ret = MLAN_STATUS_FAILURE;
+        goto release_irq;
+    }
+
+    sdio_release_host(func);
+    sdio_set_drvdata(func, card);
+
+    handle->hotplug_device = &func->dev;
+
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+
+  release_irq:
+    sdio_release_irq(func);
+  disable_func:
+    sdio_disable_func(func);
+  release_host:
+    sdio_release_host(func);
+    handle->card = NULL;
+
+    LEAVE();
+    return MLAN_STATUS_FAILURE;
+}
+
+/** 
+ *  @brief This function set bus clock on/off
+ *  
+ *  @param handle    A pointer to moal_handle structure
+ *  @param option    TRUE--on , FALSE--off
+ *  @return 	   MLAN_STATUS_SUCCESS
+ */
+int
+woal_sdio_set_bus_clock(moal_handle * handle, t_u8 option)
+{
+    return MLAN_STATUS_SUCCESS;
+}
diff --git a/wlan_src/mlinux/moal_shim.c b/wlan_src/mlinux/moal_shim.c
new file mode 100755
index 0000000..e2d413a
--- /dev/null
+++ b/wlan_src/mlinux/moal_shim.c
@@ -0,0 +1,962 @@
+/** @file moal_shim.c
+  *
+  * @brief This file contains the callback functions registered to MLAN
+  *
+  * Copyright (C) 2008-2009, Marvell International Ltd. 
+  * 
+  * This software file (the "File") is distributed by Marvell International 
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+  * (the "License").  You may use, redistribute and/or modify this File in 
+  * accordance with the terms and conditions of the License, a copy of which 
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+  * this warranty disclaimer.
+  *
+  */
+
+/********************************************************
+Change log:
+    10/21/2008: initial version
+********************************************************/
+
+#include	"moal_main.h"
+#include	"moal_sdio.h"
+
+/********************************************************
+		Local Variables
+********************************************************/
+/** moal_lock */
+typedef struct _moal_lock
+{
+        /** Lock */
+    spinlock_t lock;
+        /** Flags */
+    unsigned long flags;
+} moal_lock;
+
+/********************************************************
+		Global Variables
+********************************************************/
+extern moal_handle *m_handle;
+
+/********************************************************
+		Local Functions
+********************************************************/
+
+/********************************************************
+		Global Functions
+********************************************************/
+/** 
+ *  @brief Alloc a buffer 
+ *   
+ *  @param size 	The size of the buffer to be allocated
+ *  @param ppbuf	Pointer to a buffer location to store buffer pointer allocated
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_malloc(IN t_u32 size, OUT t_u8 ** ppbuf)
+{
+    if (!(*ppbuf = kmalloc(size, GFP_ATOMIC))) {
+        PRINTM(MERROR, "%s: allocate  buffer %d failed!\n", __FUNCTION__,
+               (int) size);
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    m_handle->malloc_count++;
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Free a buffer 
+ *   
+ *  @param pbuf		Pointer to the buffer to be freed
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_mfree(IN t_u8 * pbuf)
+{
+
+    if (!pbuf)
+        return MLAN_STATUS_FAILURE;
+    kfree(pbuf);
+    m_handle->malloc_count--;
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Fill memory with constant byte 
+ *   
+ *  @param pmem		Pointer to the memory area
+ *  @param byte		A constant byte
+ *  @param num		Number of bytes to fill
+ *
+ *  @return    		Pointer to the memory area
+ */
+t_void *
+moal_memset(IN t_void * pmem, IN t_u8 byte, IN t_u32 num)
+{
+    t_void *p = pmem;
+
+    if (pmem && num)
+        p = memset(pmem, byte, num);
+
+    return p;
+}
+
+/** 
+ *  @brief Copy memory from one area to another
+ *   
+ *  @param pdest	Pointer to the dest memory
+ *  @param psrc		Pointer to the src memory
+ *  @param num		Number of bytes to move
+ *
+ *  @return    		Pointer to the dest memory
+ */
+t_void *
+moal_memcpy(IN t_void * pdest, IN const t_void * psrc, IN t_u32 num)
+{
+    t_void *p = pdest;
+
+    if (pdest && psrc && num)
+        p = memcpy(pdest, psrc, num);
+
+    return p;
+}
+
+/** 
+ *  @brief Move memory from one area to another
+ *   
+ *  @param pdest	Pointer to the dest memory
+ *  @param psrc		Pointer to the src memory
+ *  @param num		Number of bytes to move
+ *
+ *  @return    		Pointer to the dest memory
+ */
+t_void *
+moal_memmove(IN t_void * pdest, IN const t_void * psrc, IN t_u32 num)
+{
+    t_void *p = pdest;
+
+    if (pdest && psrc && num)
+        p = memmove(pdest, psrc, num);
+
+    return p;
+}
+
+/** 
+ *  @brief Compare two memory areas
+ *   
+ *  @param pmem1	Pointer to the first memory
+ *  @param pmem2	Pointer to the second memory
+ *  @param num		Number of bytes to compare
+ *
+ *  @return    		Compare result returns by memcmp
+ */
+t_s32
+moal_memcmp(IN const t_void * pmem1, IN const t_void * pmem2, IN t_u32 num)
+{
+    t_s32 result;
+
+    result = memcmp(pmem1, pmem2, num);
+
+    return result;
+}
+
+/** 
+ *  @brief Retrieves the current system time
+ *   
+ *  @param psec		Pointer to buf for the seconds of system time
+ *  @param pusec 	Pointer to buf the micro seconds of system time
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_get_system_time(OUT t_u32 * psec, OUT t_u32 * pusec)
+{
+    struct timeval t;
+
+    do_gettimeofday(&t);
+    *psec = (t_u32) t.tv_sec;
+    *pusec = (t_u32) t.tv_usec;
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Initializes the timer
+ *   
+ *  @param pptimer	Pointer to the timer
+ *  @param callback 	Pointer to callback function
+ *  @param pcontext 	Pointer to context
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE 
+ */
+mlan_status
+moal_init_timer(OUT t_void ** pptimer,
+                IN t_void(*callback) (t_void * pcontext), IN t_void * pcontext)
+{
+    moal_drv_timer *timer = NULL;
+
+    if (!
+        (timer =
+         (moal_drv_timer *) kmalloc(sizeof(moal_drv_timer), GFP_ATOMIC))) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    woal_initialize_timer(timer, callback, pcontext);
+    *pptimer = (t_void *) timer;
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Free the timer
+ *   
+ *  @param ptimer	Pointer to the timer
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_free_timer(IN t_void * ptimer)
+{
+    moal_drv_timer *timer = (moal_drv_timer *) ptimer;
+
+    if (timer) {
+        if ((timer->timer_is_canceled == MFALSE) && timer->time_period) {
+            PRINTM(MERROR, "mlan try to free timer without stop timer!\n");
+            woal_cancel_timer(timer);
+        }
+        kfree(timer);
+    }
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Start the timer
+ *   
+ *  @param ptimer	Pointer to the timer
+ *  @param periodic     Periodic timer
+ *  @param msec		Timer value in milliseconds
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_start_timer(IN t_void * ptimer, IN t_u8 periodic, IN t_u32 msec)
+{
+    if (!ptimer)
+        return MLAN_STATUS_FAILURE;
+
+    ((moal_drv_timer *) ptimer)->timer_is_periodic = periodic;
+    woal_mod_timer((moal_drv_timer *) ptimer, msec);
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Stop the timer
+ *   
+ *  @param ptimer	Pointer to the timer
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_stop_timer(IN t_void * ptimer)
+{
+
+    if (!ptimer) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    woal_cancel_timer((moal_drv_timer *) ptimer);
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Initializes the lock
+ *   
+ *  @param pplock	Pointer to the lock
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE 
+ */
+mlan_status
+moal_init_lock(OUT t_void ** pplock)
+{
+    moal_lock *mlock = NULL;
+
+    if (!(mlock = (moal_lock *) kmalloc(sizeof(moal_lock), GFP_ATOMIC))) {
+        LEAVE();
+        return MLAN_STATUS_FAILURE;
+    }
+    spin_lock_init(&mlock->lock);
+    *pplock = (t_void *) mlock;
+
+    m_handle->lock_count++;
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Free the lock
+ *   
+ *  @param plock	Lock
+ *
+ *  @return    		MLAN_STATUS_SUCCESS
+ */
+mlan_status
+moal_free_lock(IN t_void * plock)
+{
+    moal_lock *mlock = plock;
+
+    if (mlock) {
+        kfree(mlock);
+        m_handle->lock_count--;
+    }
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief Request a spin lock
+ *   
+ *  @param plock	Pointer to the lock
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_spin_lock(IN t_void * plock)
+{
+    moal_lock *mlock = plock;
+
+    if (mlock) {
+        mlock->flags = 0;
+        spin_lock_irqsave(&mlock->lock, mlock->flags);
+
+        return MLAN_STATUS_SUCCESS;
+    } else {
+        return MLAN_STATUS_FAILURE;
+    }
+}
+
+/** 
+ *  @brief Request a spin_unlock
+ *     
+ *  @param plock	Pointer to the lock
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_spin_unlock(IN t_void * plock)
+{
+    moal_lock *mlock = (moal_lock *) plock;
+
+    if (mlock) {
+        spin_unlock_irqrestore(&mlock->lock, mlock->flags);
+
+        return MLAN_STATUS_SUCCESS;
+    } else {
+        return MLAN_STATUS_FAILURE;
+    }
+}
+
+/** 
+ *  @brief This function is called when MLAN completes the initialization firmware.
+ *   
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param status	The status code for mlan_init_fw request
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_init_fw_complete(IN t_void * pmoal_handle, IN mlan_status status)
+{
+    moal_handle *handle = (moal_handle *) pmoal_handle;
+    ENTER();
+    if (status == MLAN_STATUS_SUCCESS)
+        handle->hardware_status = HardwareStatusReady;
+    handle->init_wait_q_woken = MTRUE;
+    wake_up_interruptible(&handle->init_wait_q);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function is called when MLAN shutdown firmware is completed.
+ *   
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param status	The status code for mlan_shutdown request
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_shutdown_fw_complete(IN t_void * pmoal_handle, IN mlan_status status)
+{
+    moal_handle *handle = (moal_handle *) pmoal_handle;
+    ENTER();
+    handle->hardware_status = HardwareStatusNotReady;
+    handle->init_wait_q_woken = MTRUE;
+    wake_up_interruptible(&handle->init_wait_q);
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function is called when an MLAN IOCTL is completed.
+ *   
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param pioctl_req	pointer to strutcture mlan_ioctl_req 
+ *  @param status	The status code for mlan_ioctl request
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_ioctl_complete(IN t_void * pmoal_handle,
+                    IN pmlan_ioctl_req pioctl_req, IN mlan_status status)
+{
+    moal_handle *handle = (moal_handle *) pmoal_handle;
+    moal_private *priv = NULL;
+    wait_queue *wait;
+    ENTER();
+
+    atomic_dec(&handle->ioctl_pending);
+    priv = woal_bss_num_to_priv(handle, pioctl_req->bss_num);
+    if (priv == NULL) {
+        PRINTM(MERROR, "%s: priv is null\n", __FUNCTION__);
+        kfree(pioctl_req);
+        goto done;
+    }
+
+    wait = (wait_queue *) pioctl_req->reserved_1;
+    PRINTM(MCMND,
+           "IOCTL completed: id=0x%lx action=%d,  status=%d, status_code=0x%lx\n",
+           pioctl_req->req_id, (int) pioctl_req->action, status,
+           pioctl_req->status_code);
+    if (wait) {
+        *wait->condition = MTRUE;
+        wait->status = status;
+        if ((status != MLAN_STATUS_SUCCESS) &&
+            (pioctl_req->status_code == MLAN_ERROR_CMD_TIMEOUT)) {
+            PRINTM(MERROR, "IOCTL: command timeout\n");
+        } else {
+            wake_up_interruptible(wait->wait);
+        }
+    } else {
+        if ((status == MLAN_STATUS_SUCCESS) &&
+            (pioctl_req->action == MLAN_ACT_GET))
+            woal_process_ioctl_resp(priv, pioctl_req);
+        if (status != MLAN_STATUS_SUCCESS)
+            PRINTM(MERROR,
+                   "IOCTL failed: id=0x%lx, action=%d, status_code=0x%lx\n",
+                   pioctl_req->req_id, (int) pioctl_req->action,
+                   pioctl_req->status_code);
+        kfree(pioctl_req);
+    }
+  done:
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function allocates mlan_buffer.
+ *   
+ *  @param size		allocation size requested 
+ *  @param pmbuf	pointer to pointer to the allocated buffer 
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_alloc_mlan_buffer(IN t_u32 size, OUT pmlan_buffer * pmbuf)
+{
+    if (NULL == (*pmbuf = woal_alloc_mlan_buffer(size)))
+        return MLAN_STATUS_FAILURE;
+
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function frees mlan_buffer.
+ *   
+ *  @param pmbuf	pointer to buffer to be freed
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_free_mlan_buffer(IN pmlan_buffer pmbuf)
+{
+    if (!pmbuf)
+        return MLAN_STATUS_FAILURE;
+
+    woal_free_mlan_buffer(pmbuf);
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function is called when MLAN complete send data packet.
+ *   
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param pmbuf	Pointer to the mlan buffer structure
+ *  @param status	The status code for mlan_send_packet request
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_send_packet_complete(IN t_void * pmoal_handle,
+                          IN pmlan_buffer pmbuf, IN mlan_status status)
+{
+    moal_private *priv = NULL;
+    moal_handle *handle = (moal_handle *) pmoal_handle;
+    struct sk_buff *skb = NULL;
+    int i;
+    ENTER();
+    if (pmbuf) {
+        priv = woal_bss_num_to_priv(pmoal_handle, pmbuf->bss_num);
+        skb = (struct sk_buff *) pmbuf->pdesc;
+        if (priv) {
+            priv->netdev->trans_start = jiffies;
+            if (skb) {
+                if (status == MLAN_STATUS_SUCCESS) {
+                    priv->stats.tx_packets++;
+                    priv->stats.tx_bytes += skb->len;
+                } else {
+                    priv->stats.tx_errors++;
+                }
+                atomic_dec(&handle->tx_pending);
+                for (i = 0; i < handle->priv_num; i++) {
+                    if ((handle->priv[i]->bss_type == MLAN_BSS_TYPE_STA) &&
+                        (handle->priv[i]->media_connected ||
+                         priv->is_adhoc_link_sensed)) {
+                        if (netif_queue_stopped(handle->priv[i]->netdev))
+                            netif_wake_queue(handle->priv[i]->netdev);
+                    }
+                }
+            }
+        }
+        if (skb)
+            dev_kfree_skb_any(skb);
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function is called when MLAN complete receiving 
+ *  	   data/event/command
+ *
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param pmbuf	Pointer to the mlan buffer structure
+ *  @param port 	Port number for receive
+ *  @param status	The status code for mlan_receive request
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_recv_complete(IN t_void * pmoal_handle,
+                   IN pmlan_buffer pmbuf, IN t_u32 port, IN mlan_status status)
+{
+    moal_private *priv = NULL;
+    moal_handle *handle = (moal_handle *) pmoal_handle;
+    ENTER();
+    if (pmbuf) {
+        priv = woal_bss_num_to_priv(handle, pmbuf->bss_num);
+        if (priv && (pmbuf->buf_type == MLAN_BUF_TYPE_DATA) &&
+            (status == MLAN_STATUS_FAILURE)) {
+            priv->stats.rx_dropped++;
+        }
+        woal_free_mlan_buffer(pmbuf);
+    }
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function write a command/data packet to card.
+ *         This function blocks the call until it finishes
+ *
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param pmbuf	Pointer to the mlan buffer structure
+ *  @param port 	Port number for sent
+ *  @param timeout 	Timeout value in milliseconds (if 0 the wait is forever)
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_write_data_sync(IN t_void * pmoal_handle,
+                     IN pmlan_buffer pmbuf, IN t_u32 port, IN t_u32 timeout)
+{
+    return woal_write_data_sync((moal_handle *) pmoal_handle, pmbuf, port,
+                                timeout);
+}
+
+/** 
+ *  @brief This function read data packet/event/command from card.
+ *         This function blocks the call until it finish
+ *
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param pmbuf	Pointer to the mlan buffer structure
+ *  @param port 	Port number for read
+ *  @param timeout 	Timeout value in milliseconds (if 0 the wait is forever)
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_read_data_sync(IN t_void * pmoal_handle,
+                    IN OUT pmlan_buffer pmbuf, IN t_u32 port, IN t_u32 timeout)
+{
+    return woal_read_data_sync((moal_handle *) pmoal_handle, pmbuf, port,
+                               timeout);
+}
+
+/** 
+ *  @brief This function writes data into card register.
+ *
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param reg          register offset
+ *  @param data         value
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_write_reg(IN t_void * pmoal_handle, IN t_u32 reg, IN t_u32 data)
+{
+    return woal_write_reg((moal_handle *) pmoal_handle, reg, data);
+}
+
+/** 
+ *  @brief This function reads data from card register.
+ *
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param reg          register offset
+ *  @param data         value
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_read_reg(IN t_void * pmoal_handle, IN t_u32 reg, OUT t_u32 * data)
+{
+    return woal_read_reg((moal_handle *) pmoal_handle, reg, data);
+}
+
+/** 
+ *  @brief This function uploads the packet to the network stack
+ *
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param pmbuf	Pointer to the mlan buffer structure
+ *
+ *  @return    		MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
+ */
+mlan_status
+moal_recv_packet(IN t_void * pmoal_handle, IN pmlan_buffer pmbuf)
+{
+    mlan_status status = MLAN_STATUS_SUCCESS;
+    moal_private *priv = NULL;
+    struct sk_buff *skb = NULL;
+    ENTER();
+    if (pmbuf) {
+        priv = woal_bss_num_to_priv(pmoal_handle, pmbuf->bss_num);
+        skb = (struct sk_buff *) pmbuf->pdesc;
+        if (priv) {
+            if (skb) {
+                skb_reserve(skb, pmbuf->data_offset);
+                skb_put(skb, pmbuf->data_len);
+                pmbuf->pdesc = NULL;
+                pmbuf->pbuf = NULL;
+                pmbuf->data_offset = pmbuf->data_len = 0;
+            } else {
+                if (!(skb = dev_alloc_skb(pmbuf->data_len + MLAN_NET_IP_ALIGN))) {
+                    PRINTM(MERROR, "%s fail to alloc skb", __FUNCTION__);
+                    status = MLAN_STATUS_FAILURE;
+                    priv->stats.rx_dropped++;
+                    goto done;
+                }
+                skb_reserve(skb, MLAN_NET_IP_ALIGN);
+                memcpy(skb->data, (t_u8 *) (pmbuf->pbuf + pmbuf->data_offset),
+                       pmbuf->data_len);
+                skb_put(skb, pmbuf->data_len);
+            }
+            skb->dev = priv->netdev;
+            skb->protocol = eth_type_trans(skb, priv->netdev);
+            skb->ip_summed = CHECKSUM_NONE;
+            priv->stats.rx_bytes += skb->len;
+            priv->stats.rx_packets++;
+            if (in_interrupt())
+                netif_rx(skb);
+            else
+                netif_rx_ni(skb);
+        }
+    }
+  done:
+    LEAVE();
+    return status;
+}
+
+/** 
+ *  @brief This function handles event receive
+ *
+ *  @param pmoal_handle Pointer to the MOAL context
+ *  @param pmevent	Pointer to the mlan event structure
+ *
+ *  @return    		MLAN_STATUS_SUCCESS 
+ */
+mlan_status
+moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent)
+{
+    moal_private *priv = NULL;
+    union iwreq_data wrqu;
+    ENTER();
+
+    PRINTM(MEVENT, "event id:0x%x\n", pmevent->event_id);
+    priv = woal_bss_num_to_priv(pmoal_handle, pmevent->bss_num);
+    if (priv == NULL) {
+        PRINTM(MERROR, "%s: priv is null\n", __FUNCTION__);
+        goto done;
+    }
+    switch (pmevent->event_id) {
+    case MLAN_EVENT_ID_FW_ADHOC_LINK_SENSED:
+        priv->is_adhoc_link_sensed = MTRUE;
+        if (!netif_carrier_ok(priv->netdev))
+            netif_carrier_on(priv->netdev);
+        if (netif_queue_stopped(priv->netdev))
+            netif_wake_queue(priv->netdev);
+        woal_send_iwevcustom_event(priv, CUS_EVT_ADHOC_LINK_SENSED);
+        break;
+    case MLAN_EVENT_ID_FW_ADHOC_LINK_LOST:
+        if (!netif_queue_stopped(priv->netdev))
+            netif_stop_queue(priv->netdev);
+        if (netif_carrier_ok(priv->netdev))
+            netif_carrier_off(priv->netdev);
+        priv->is_adhoc_link_sensed = MFALSE;
+        woal_send_iwevcustom_event(priv, CUS_EVT_ADHOC_LINK_LOST);
+        break;
+    case MLAN_EVENT_ID_DRV_CONNECTED:
+        if (pmevent->event_len == ETH_ALEN) {
+            memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
+            memcpy(wrqu.ap_addr.sa_data, pmevent->event_buf, ETH_ALEN);
+            wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+            wireless_send_event(priv->netdev, SIOCGIWAP, &wrqu, NULL);
+        }
+        priv->media_connected = MTRUE;
+        if (!netif_carrier_ok(priv->netdev))
+            netif_carrier_on(priv->netdev);
+        if (netif_queue_stopped(priv->netdev))
+            netif_wake_queue(priv->netdev);
+        break;
+    case MLAN_EVENT_ID_DRV_SCAN_REPORT:
+        PRINTM(MCMND, "Scan report\n");
+        memset(&wrqu, 0, sizeof(union iwreq_data));
+        wireless_send_event(priv->netdev, SIOCGIWSCAN, &wrqu, NULL);
+        if (priv->scan_pending_on_block == MTRUE) {
+            priv->scan_pending_on_block = MFALSE;
+            MOAL_REL_SEMAPHORE(&priv->async_sem);
+        }
+        break;
+    case MLAN_EVENT_ID_DRV_OBSS_SCAN_PARAM:
+        memset(&wrqu, 0, sizeof(union iwreq_data));
+        memmove((pmevent->event_buf + strlen(CUS_EVT_OBSS_SCAN_PARAM) + 1),
+                pmevent->event_buf, pmevent->event_len);
+        memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_OBSS_SCAN_PARAM,
+               strlen(CUS_EVT_OBSS_SCAN_PARAM));
+        pmevent->event_buf[strlen(CUS_EVT_OBSS_SCAN_PARAM)] = 0;
+
+        wrqu.data.pointer = pmevent->event_buf;
+        wrqu.data.length =
+            pmevent->event_len + strlen(CUS_EVT_OBSS_SCAN_PARAM) +
+            IW_EV_LCP_LEN + 1;
+        wireless_send_event(priv->netdev, IWEVCUSTOM, &wrqu,
+                            pmevent->event_buf);
+        break;
+    case MLAN_EVENT_ID_FW_BW_CHANGED:
+        memset(&wrqu, 0, sizeof(union iwreq_data));
+        memmove((pmevent->event_buf + strlen(CUS_EVT_BW_CHANGED) + 1),
+                pmevent->event_buf, pmevent->event_len);
+        memcpy(pmevent->event_buf, (t_u8 *) CUS_EVT_BW_CHANGED,
+               strlen(CUS_EVT_BW_CHANGED));
+        pmevent->event_buf[strlen(CUS_EVT_BW_CHANGED)] = 0;
+
+        wrqu.data.pointer = pmevent->event_buf;
+        wrqu.data.length =
+            pmevent->event_len + strlen(CUS_EVT_BW_CHANGED) + IW_EV_LCP_LEN + 1;
+        wireless_send_event(priv->netdev, IWEVCUSTOM, &wrqu,
+                            pmevent->event_buf);
+        break;
+    case MLAN_EVENT_ID_FW_DISCONNECTED:
+        priv->media_connected = MFALSE;
+        if (!netif_queue_stopped(priv->netdev))
+            netif_stop_queue(priv->netdev);
+        if (netif_carrier_ok(priv->netdev))
+            netif_carrier_off(priv->netdev);
+        memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
+        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+        wireless_send_event(priv->netdev, SIOCGIWAP, &wrqu, NULL);
+        /* Reset wireless stats signal info */
+        priv->w_stats.qual.level = 0;
+        priv->w_stats.qual.noise = 0;
+#ifdef REASSOCIATION
+        if (priv->phandle->reassoc_on == MTRUE) {
+            PRINTM(MINFO, "Reassoc: trigger the timer\n");
+            priv->reassoc_required = MTRUE;
+            priv->phandle->is_reassoc_timer_set = MTRUE;
+            woal_mod_timer(&priv->phandle->reassoc_timer, 500);
+        } else {
+            priv->rate_index = AUTO_RATE;
+        }
+#endif /* REASSOCIATION */
+        break;
+    case MLAN_EVENT_ID_FW_MIC_ERR_UNI:
+#if WIRELESS_EXT >= 18
+        woal_send_mic_error_event(priv, MLAN_EVENT_ID_FW_MIC_ERR_UNI);
+#else
+        woal_send_iwevcustom_event(priv, CUS_EVT_MLME_MIC_ERR_UNI);
+#endif
+        break;
+    case MLAN_EVENT_ID_FW_MIC_ERR_MUL:
+#if WIRELESS_EXT >= 18
+        woal_send_mic_error_event(priv, MLAN_EVENT_ID_FW_MIC_ERR_MUL);
+#else
+        woal_send_iwevcustom_event(priv, CUS_EVT_MLME_FW_MIC_ERR_UNI);
+#endif
+        break;
+    case MLAN_EVENT_ID_FW_BCN_RSSI_LOW:
+        woal_send_iwevcustom_event(priv, CUS_EVT_BEACON_RSSI_LOW);
+        break;
+    case MLAN_EVENT_ID_FW_BCN_RSSI_HIGH:
+        woal_send_iwevcustom_event(priv, CUS_EVT_BEACON_RSSI_HIGH);
+        break;
+    case MLAN_EVENT_ID_FW_BCN_SNR_LOW:
+        woal_send_iwevcustom_event(priv, CUS_EVT_BEACON_SNR_LOW);
+        break;
+    case MLAN_EVENT_ID_FW_BCN_SNR_HIGH:
+        woal_send_iwevcustom_event(priv, CUS_EVT_BEACON_SNR_HIGH);
+        break;
+    case MLAN_EVENT_ID_FW_MAX_FAIL:
+        woal_send_iwevcustom_event(priv, CUS_EVT_MAX_FAIL);
+        break;
+    case MLAN_EVENT_ID_FW_DATA_RSSI_LOW:
+        woal_send_iwevcustom_event(priv, CUS_EVT_DATA_RSSI_LOW);
+        break;
+    case MLAN_EVENT_ID_FW_DATA_SNR_LOW:
+        woal_send_iwevcustom_event(priv, CUS_EVT_DATA_SNR_LOW);
+        break;
+    case MLAN_EVENT_ID_FW_DATA_RSSI_HIGH:
+        woal_send_iwevcustom_event(priv, CUS_EVT_DATA_RSSI_HIGH);
+        break;
+    case MLAN_EVENT_ID_FW_DATA_SNR_HIGH:
+        woal_send_iwevcustom_event(priv, CUS_EVT_DATA_SNR_HIGH);
+        break;
+    case MLAN_EVENT_ID_FW_LINK_QUALITY:
+        woal_send_iwevcustom_event(priv, CUS_EVT_LINK_QUALITY);
+        break;
+    case MLAN_EVENT_ID_FW_PORT_RELEASE:
+        woal_send_iwevcustom_event(priv, CUS_EVT_PORT_RELEASE);
+        break;
+    case MLAN_EVENT_ID_FW_PRE_BCN_LOST:
+        woal_send_iwevcustom_event(priv, CUS_EVT_PRE_BEACON_LOST);
+        break;
+    case MLAN_EVENT_ID_FW_DS_AWAKE:
+        woal_send_iwevcustom_event(priv, CUS_EVT_DEEP_SLEEP_AWAKE);
+        break;
+    case MLAN_EVENT_ID_FW_WMM_CONFIG_CHANGE:
+        woal_send_iwevcustom_event(priv, WMM_CONFIG_CHANGE_INDICATION);
+        break;
+    case MLAN_EVENT_ID_FW_WEP_ICV_ERR:
+        DBG_HEXDUMP(MCMD_D, "WEP ICV error", pmevent->event_buf,
+                    pmevent->event_len);
+        woal_send_iwevcustom_event(priv, CUS_EVT_WEP_ICV_ERR);
+        break;
+
+    case MLAN_EVENT_ID_DRV_DEFER_HANDLING:
+        queue_work(priv->phandle->workqueue, &priv->phandle->main_work);
+        break;
+    case MLAN_EVENT_ID_FW_BG_SCAN:
+        memset(&wrqu, 0, sizeof(union iwreq_data));
+        wireless_send_event(priv->netdev, SIOCGIWSCAN, &wrqu, NULL);
+        break;
+    case MLAN_EVENT_ID_FW_STOP_TX:
+        netif_carrier_off(priv->netdev);
+        break;
+    case MLAN_EVENT_ID_FW_START_TX:
+        netif_carrier_on(priv->netdev);
+        break;
+    case MLAN_EVENT_ID_FW_HS_WAKEUP:
+        if (priv->bss_type == MLAN_BSS_TYPE_STA)
+            woal_send_iwevcustom_event(priv, CUS_EVT_HS_WAKEUP);
+        /* simulate HSCFG_CANCEL command */
+        woal_hs_cfg_cancel(priv, MOAL_NO_WAIT);
+        break;
+    case MLAN_EVENT_ID_DRV_HS_ACTIVATED:
+        if (priv->bss_type == MLAN_BSS_TYPE_STA) {
+            woal_send_iwevcustom_event(priv, CUS_EVT_HS_ACTIVATED);
+        }
+        break;
+    case MLAN_EVENT_ID_DRV_HS_DEACTIVATED:
+        if (priv->bss_type == MLAN_BSS_TYPE_STA)
+            woal_send_iwevcustom_event(priv, CUS_EVT_HS_DEACTIVATED);
+        break;
+    case MLAN_EVENT_ID_DRV_PASSTHU:
+        woal_broadcast_event(priv, pmevent->event_buf, pmevent->event_len);
+        break;
+
+    default:
+        break;
+    }
+  done:
+    LEAVE();
+    return MLAN_STATUS_SUCCESS;
+}
+
+/** 
+ *  @brief This function prints the debug message in mlan
+ *
+ *  @param level	debug level
+ *  @param pformat	point to string format buf
+ *
+ *  @return    		N/A 
+ */
+t_void
+moal_print(IN t_u32 level, IN t_s8 * pformat, IN ...)
+{
+#ifdef	DEBUG_LEVEL1
+    va_list args;
+
+    if (level & MHEX_DUMP) {
+        t_u8 *buf = NULL;
+        int len = 0;
+
+        va_start(args, pformat);
+        buf = (t_u8 *) va_arg(args, t_u8 *);
+        len = (int) va_arg(args, int);
+        va_end(args);
+
+#ifdef DEBUG_LEVEL2
+        if (level & MINFO)
+            HEXDUMP((char *) pformat, buf, len);
+        else
+#endif /* DEBUG_LEVEL2 */
+        {
+            if (level & MCMD_D)
+                DBG_HEXDUMP(MCMD_D, (char *) pformat, buf, len);
+            if (level & MDAT_D)
+                DBG_HEXDUMP(MDAT_D, (char *) pformat, buf, len);
+            if (level & MIF_D)
+                DBG_HEXDUMP(MIF_D, (char *) pformat, buf, len);
+            if (level & MFW_D)
+                DBG_HEXDUMP(MFW_D, (char *) pformat, buf, len);
+        }
+    } else if (drvdbg & level) {
+        va_start(args, pformat);
+#ifndef DEBUG_LEVEL2
+        if (!(level & (MINFO | MWARN | MENTRY)))
+#endif /* DEBUG_LEVEL2 */
+            vprintk(pformat, args);
+        va_end(args);
+    }
+#endif /* DEBUG_LEVEL1 */
+}
diff --git a/wlan_src/mlinux/moal_shim.h b/wlan_src/mlinux/moal_shim.h
new file mode 100755
index 0000000..e5769df
--- /dev/null
+++ b/wlan_src/mlinux/moal_shim.h
@@ -0,0 +1,78 @@
+/** @file moal_shim.h
+  *
+  * @brief This file contains declaration referring to
+  * functions defined in moal module
+  *
+  * Copyright (C) 2008-2009, Marvell International Ltd. 
+  * 
+  * This software file (the "File") is distributed by Marvell International 
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+  * (the "License").  You may use, redistribute and/or modify this File in 
+  * accordance with the terms and conditions of the License, a copy of which 
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+  * this warranty disclaimer.
+  *
+  */
+/*************************************************************
+Change Log:
+    10/21/2008: initial version
+************************************************************/
+
+#ifndef _MOAL_H
+#define _MOAL_H
+mlan_status moal_init_fw_complete(IN t_void * pmoal_handle,
+                                  IN mlan_status status);
+mlan_status moal_shutdown_fw_complete(IN t_void * pmoal_handle,
+                                      IN mlan_status status);
+mlan_status moal_ioctl_complete(IN t_void * pmoal_handle,
+                                IN pmlan_ioctl_req pioctl_req,
+                                IN mlan_status status);
+mlan_status moal_alloc_mlan_buffer(IN t_u32 size, OUT pmlan_buffer * pmbuf);
+mlan_status moal_free_mlan_buffer(IN pmlan_buffer pmbuf);
+mlan_status moal_send_packet_complete(IN t_void * pmoal_handle,
+                                      IN pmlan_buffer pmbuf,
+                                      IN mlan_status status);
+mlan_status moal_recv_complete(IN t_void * pmoal_handle,
+                               IN pmlan_buffer pmbuf,
+                               IN t_u32 port, IN mlan_status status);
+/** moal_write_reg */
+mlan_status moal_write_reg(IN t_void * pmoal_handle,
+                           IN t_u32 reg, IN t_u32 data);
+/** moal_read_reg */
+mlan_status moal_read_reg(IN t_void * pmoal_handle,
+                          IN t_u32 reg, OUT t_u32 * data);
+mlan_status moal_write_data_sync(IN t_void * pmoal_handle,
+                                 IN pmlan_buffer pmbuf,
+                                 IN t_u32 port, IN t_u32 timeout);
+mlan_status moal_read_data_sync(IN t_void * pmoal_handle,
+                                IN OUT pmlan_buffer pmbuf,
+                                IN t_u32 port, IN t_u32 timeout);
+mlan_status moal_recv_packet(IN t_void * pmoal_handle, IN pmlan_buffer pmbuf);
+mlan_status moal_recv_event(IN t_void * pmoal_handle, IN pmlan_event pmevent);
+mlan_status moal_malloc(IN t_u32 size, OUT t_u8 ** ppbuf);
+mlan_status moal_mfree(IN t_u8 * pbuf);
+t_void *moal_memset(IN t_void * pmem, IN t_u8 byte, IN t_u32 num);
+t_void *moal_memcpy(IN t_void * pdest, IN const t_void * psrc, IN t_u32 num);
+t_void *moal_memmove(IN t_void * pdest, IN const t_void * psrc, IN t_u32 num);
+t_s32 moal_memcmp(IN const t_void * pmem1,
+                  IN const t_void * pmem2, IN t_u32 num);
+mlan_status moal_get_system_time(OUT t_u32 * psec, OUT t_u32 * pusec);
+mlan_status moal_init_lock(OUT t_void ** pplock);
+mlan_status moal_free_lock(IN t_void * plock);
+mlan_status moal_spin_lock(IN t_void * plock);
+mlan_status moal_spin_unlock(IN t_void * plock);
+t_void moal_print(IN t_u32 level, IN t_s8 * pformat, IN ...);
+mlan_status moal_init_timer(OUT t_void ** pptimer,
+                            IN t_void(*callback) (t_void * pcontext),
+                            IN t_void * pcontext);
+mlan_status moal_free_timer(IN t_void * ptimer);
+mlan_status moal_start_timer(IN t_void * ptimer,
+                             IN t_u8 periodic, IN t_u32 msec);
+mlan_status moal_stop_timer(IN t_void * ptimer);
+#endif /*_MOAL_H */
diff --git a/wlan_src/mlinux/moal_wext.c b/wlan_src/mlinux/moal_wext.c
new file mode 100755
index 0000000..f919d5f
--- /dev/null
+++ b/wlan_src/mlinux/moal_wext.c
@@ -0,0 +1,2761 @@
+/** @file  moal_wext.c
+  *
+  * @brief This file contains wireless extension standard ioctl functions
+  *
+  * Copyright (C) 2008-2009, Marvell International Ltd.
+  *
+  * This software file (the "File") is distributed by Marvell International
+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+  * (the "License").  You may use, redistribute and/or modify this File in
+  * accordance with the terms and conditions of the License, a copy of which
+  * is available by writing to the Free Software Foundation, Inc.,
+  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+  *
+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+  * this warranty disclaimer.
+  *
+  */
+
+/************************************************************************
+Change log:
+    10/21/2008: initial version
+************************************************************************/
+
+#include        "moal_main.h"
+
+/** Approximate amount of data needed to pass a scan result back to iwlist */
+#define MAX_SCAN_CELL_SIZE  (IW_EV_ADDR_LEN             \
+                             + MLAN_MAX_SSID_LENGTH   \
+                             + IW_EV_UINT_LEN           \
+                             + IW_EV_FREQ_LEN           \
+                             + IW_EV_QUAL_LEN           \
+                             + MLAN_MAX_SSID_LENGTH    \
+                             + IW_EV_PARAM_LEN          \
+                             + 40)      /* 40 for WPAIE */
+/** Macro for minimum size of scan buffer */
+#define MIN_ACCEPTED_GET_SCAN_BUF 8000
+/** Macro for maximum size of scan response buffer */
+#define MAX_SCAN_RSP_BUF (16 * 1024)
+
+/********************************************************
+                Global Variables
+********************************************************/
+
+/********************************************************
+                Local Functions
+********************************************************/
+
+/**
+ *  @brief Compare two SSIDs
+ *
+ *  @param ssid1    A pointer to ssid to compare
+ *  @param ssid2    A pointer to ssid to compare
+ *
+ *  @return         0--ssid is same, otherwise is different
+ */
+t_s32
+woal_ssid_cmp(mlan_802_11_ssid * ssid1, mlan_802_11_ssid * ssid2)
+{
+    ENTER();
+
+    if (!ssid1 || !ssid2) {
+        LEAVE();
+        return -1;
+    }
+    if (ssid1->ssid_len != ssid2->ssid_len) {
+        LEAVE();
+        return -1;
+    }
+
+    LEAVE();
+    return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
+}
+
+/**
+ *  @brief Sort Channels
+ *
+ *  @param freq                 A pointer to iw_freq structure
+ *  @param num                  Number of Channels
+ *
+ *  @return                     N/A
+ */
+static inline void
+woal_sort_channels(struct iw_freq *freq, int num)
+{
+    int i, j;
+    struct iw_freq temp;
+
+    for (i = 0; i < num; i++)
+        for (j = i + 1; j < num; j++)
+            if (freq[i].i > freq[j].i) {
+                temp.i = freq[i].i;
+                temp.m = freq[i].m;
+
+                freq[i].i = freq[j].i;
+                freq[i].m = freq[j].m;
+
+                freq[j].i = temp.i;
+                freq[j].m = temp.m;
+            }
+}
+
+/**
+ *  @brief Set Radio On/OFF
+ *
+ *  @param priv                 A pointer to moal_private structure
+ *  @param option               Radio Option
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+int
+woal_set_radio(moal_private * priv, t_u8 option)
+{
+    int ret = 0;
+    mlan_ds_radio_cfg *radio = NULL;
+    mlan_ioctl_req *req = NULL;
+    ENTER();
+    if ((option != 0) && (option != 1)) {
+        ret = -EINVAL;
+        goto done;
+    }
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_radio_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    radio = (mlan_ds_radio_cfg *) req->pbuf;
+    radio->sub_command = MLAN_OID_RADIO_CTRL;
+    req->req_id = MLAN_IOCTL_RADIO_CFG;
+    req->action = MLAN_ACT_SET;
+    radio->param.radio_on_off = option;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set Adapter Node Name
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param dwrq                 A pointer to iw_point structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_nick(struct net_device *dev, struct iw_request_info *info,
+              struct iw_point *dwrq, char *extra)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    ENTER();
+    /* 
+     * Check the size of the string
+     */
+    if (dwrq->length > 16) {
+        LEAVE();
+        return -E2BIG;
+    }
+    memset(priv->nick_name, 0, sizeof(priv->nick_name));
+    memcpy(priv->nick_name, extra, dwrq->length);
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Get Adapter Node Name
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param dwrq                 A pointer to iw_point structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_nick(struct net_device *dev, struct iw_request_info *info,
+              struct iw_point *dwrq, char *extra)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    ENTER();
+    /* 
+     * Get the Nick Name saved
+     */
+    strncpy(extra, (char *) priv->nick_name, 16);
+    extra[16] = '\0';
+    /* 
+     * If none, we may want to get the one that was set
+     */
+
+    /* 
+     * Push it out !
+     */
+    dwrq->length = strlen(extra) + 1;
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Commit handler: called after a bunch of SET operations
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param cwrq         A pointer to char buffer
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_config_commit(struct net_device *dev,
+                   struct iw_request_info *info, char *cwrq, char *extra)
+{
+    ENTER();
+
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Get name
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param cwrq         A pointer to char buffer
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_get_name(struct net_device *dev, struct iw_request_info *info,
+              char *cwrq, char *extra)
+{
+    const char *cp;
+    char comm[6] = { "COMM-" };
+    char mrvl[6] = { "MRVL-" };
+    int cnt;
+
+    ENTER();
+
+    strcpy(cwrq, mrvl);
+
+    cp = strstr(driver_version, comm);
+    if (cp == driver_version)   /* Skip leading "COMM-" */
+        cp = driver_version + strlen(comm);
+    else
+        cp = driver_version;
+
+    cnt = strlen(mrvl);
+    cwrq += cnt;
+    while (cnt < 16 && (*cp != '-')) {
+        *cwrq++ = toupper(*cp++);
+        cnt++;
+    }
+    *cwrq = '\0';
+
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Set frequency
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param fwrq                 A pointer to iw_freq structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_freq(struct net_device *dev, struct iw_request_info *info,
+              struct iw_freq *fwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_bss *bss = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    bss = (mlan_ds_bss *) req->pbuf;
+    /* 
+     * If setting by frequency, convert to a channel 
+     */
+    if (fwrq->e == 1) {
+        long f = fwrq->m / 100000;
+        bss->param.bss_chan.freq = f;
+    } else
+        bss->param.bss_chan.channel = fwrq->m;
+
+    bss->sub_command = MLAN_OID_BSS_CHANNEL;
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_SET;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (MLAN_STATUS_SUCCESS !=
+        woal_change_adhoc_chan(priv, bss->param.bss_chan.channel))
+        ret = -EFAULT;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get frequency
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param fwrq                 A pointer to iw_freq structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_freq(struct net_device *dev, struct iw_request_info *info,
+              struct iw_freq *fwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_bss *bss = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_BSS_CHANNEL;
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_GET;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    fwrq->m = (long) bss->param.bss_chan.freq * 100000;
+    fwrq->i = (long) bss->param.bss_chan.channel;
+    fwrq->e = 1;
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set wlan mode
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param uwrq                 Wireless mode to set
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_bss_mode(struct net_device *dev, struct iw_request_info *info,
+                  t_u32 * uwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_bss *bss = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_bss));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    bss = (mlan_ds_bss *) req->pbuf;
+    bss->sub_command = MLAN_OID_BSS_MODE;
+    req->req_id = MLAN_IOCTL_BSS;
+    req->action = MLAN_ACT_SET;
+
+    switch (*uwrq) {
+    case IW_MODE_INFRA:
+        bss->param.bss_mode = MLAN_BSS_MODE_INFRA;
+        break;
+    case IW_MODE_ADHOC:
+        bss->param.bss_mode = MLAN_BSS_MODE_IBSS;
+        break;
+    case IW_MODE_AUTO:
+        bss->param.bss_mode = MLAN_BSS_MODE_AUTO;
+        break;
+    default:
+        ret = -EINVAL;
+        break;
+    }
+    if (ret)
+        goto done;
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get current BSSID
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param awrq         A pointer to sockaddr structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_get_wap(struct net_device *dev, struct iw_request_info *info,
+             struct sockaddr *awrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_bss_info bss_info;
+
+    ENTER();
+
+    memset(&bss_info, 0, sizeof(bss_info));
+
+    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+
+    if (bss_info.media_connected == MTRUE) {
+        memcpy(awrq->sa_data, &bss_info.bssid, MLAN_MAC_ADDR_LENGTH);
+    } else {
+        memset(awrq->sa_data, 0, MLAN_MAC_ADDR_LENGTH);
+    }
+    awrq->sa_family = ARPHRD_ETHER;
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Connect to the AP or Ad-hoc Network with specific bssid
+ *
+ * NOTE: Scan should be issued by application before this function is called
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param awrq         A pointer to iw_param structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_set_wap(struct net_device *dev, struct iw_request_info *info,
+             struct sockaddr *awrq, char *extra)
+{
+    int ret = 0;
+    const t_u8 bcast[MLAN_MAC_ADDR_LENGTH] = { 255, 255, 255, 255, 255, 255 };
+    const t_u8 zero_mac[MLAN_MAC_ADDR_LENGTH] = { 0, 0, 0, 0, 0, 0 };
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ssid_bssid ssid_bssid;
+    mlan_bss_info bss_info;
+
+    ENTER();
+
+    if (awrq->sa_family != ARPHRD_ETHER) {
+        ret = -EINVAL;
+        goto done;
+    }
+
+    PRINTM(MINFO, "ASSOC: WAP: sa_data: %02x:%02x:%02x:%02x:%02x:%02x\n",
+           (t_u8) awrq->sa_data[0], (t_u8) awrq->sa_data[1],
+           (t_u8) awrq->sa_data[2], (t_u8) awrq->sa_data[3],
+           (t_u8) awrq->sa_data[4], (t_u8) awrq->sa_data[5]);
+
+    if (MLAN_STATUS_SUCCESS !=
+        woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
+        ret = -EFAULT;
+        goto done;
+    }
+#ifdef REASSOCIATION
+    /* Cancel re-association */
+    priv->reassoc_required = MFALSE;
+#endif
+
+    /* zero_mac means disconnect */
+    if (!memcmp(zero_mac, awrq->sa_data, MLAN_MAC_ADDR_LENGTH)) {
+        woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
+        goto done;
+    }
+
+    /* Broadcast MAC means search for best network */
+    memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid));
+
+    if (memcmp(bcast, awrq->sa_data, MLAN_MAC_ADDR_LENGTH)) {
+        /* Check if we are already assoicated to the AP */
+        if (bss_info.media_connected == MTRUE) {
+            if (!memcmp(awrq->sa_data, &bss_info.bssid, ETH_ALEN))
+                goto done;
+            /* disconnect before try to assoicate to the new AP */
+            woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
+        }
+        memcpy(&ssid_bssid.bssid, awrq->sa_data, ETH_ALEN);
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_set_ewpa_mode(priv, MOAL_IOCTL_WAIT,
+                                                  &ssid_bssid)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (MLAN_STATUS_SUCCESS != woal_find_best_network(priv,
+                                                      MOAL_IOCTL_WAIT,
+                                                      &ssid_bssid)) {
+        PRINTM(MERROR, "ASSOC: WAP: MAC address not found in BSSID List\n");
+        ret = -ENETUNREACH;
+        goto done;
+    }
+    /* Zero SSID implies use BSSID to connect */
+    memset(&ssid_bssid.ssid, 0, sizeof(mlan_802_11_ssid));
+    if (MLAN_STATUS_SUCCESS != woal_bss_start(priv,
+                                              MOAL_IOCTL_WAIT, &ssid_bssid)) {
+        ret = -EFAULT;
+        goto done;
+    }
+#ifdef REASSOCIATION
+    memset(&bss_info, 0, sizeof(bss_info));
+    if (MLAN_STATUS_SUCCESS != woal_get_bss_info(priv,
+                                                 MOAL_IOCTL_WAIT, &bss_info)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    memcpy(&priv->prev_ssid_bssid.ssid, &bss_info.ssid,
+           sizeof(mlan_802_11_ssid));
+    memcpy(&priv->prev_ssid_bssid.bssid, &bss_info.bssid, MLAN_MAC_ADDR_LENGTH);
+#endif /* REASSOCIATION */
+
+  done:
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get wlan mode
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param uwrq                 A pointer to t_u32 string
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_bss_mode(struct net_device *dev, struct iw_request_info *info,
+                  t_u32 * uwrq, char *extra)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    ENTER();
+    *uwrq = woal_get_mode(priv, MOAL_IOCTL_WAIT);
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Set sensitivity
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_sens(struct net_device *dev, struct iw_request_info *info,
+              struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+
+    ENTER();
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get sensitivity
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_sens(struct net_device *dev, struct iw_request_info *info,
+              struct iw_param *vwrq, char *extra)
+{
+    int ret = -1;
+
+    ENTER();
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set Tx power
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_txpow(struct net_device *dev, struct iw_request_info *info,
+               struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_power_cfg *pcfg = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+    if (vwrq->disabled) {
+        woal_set_radio(priv, 0);
+        goto done;
+    }
+    woal_set_radio(priv, 1);
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_power_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    pcfg = (mlan_ds_power_cfg *) req->pbuf;
+    pcfg->sub_command = MLAN_OID_POWER_CFG;
+    req->req_id = MLAN_IOCTL_POWER_CFG;
+    req->action = MLAN_ACT_SET;
+    if (!vwrq->fixed)
+        pcfg->param.power_cfg.is_power_auto = 1;
+    else {
+        pcfg->param.power_cfg.is_power_auto = 0;
+        pcfg->param.power_cfg.power_level = vwrq->value;
+    }
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get Tx power
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_txpow(struct net_device *dev, struct iw_request_info *info,
+               struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_power_cfg *pcfg = NULL;
+    mlan_ioctl_req *req = NULL;
+    mlan_bss_info bss_info;
+
+    ENTER();
+    memset(&bss_info, 0, sizeof(bss_info));
+    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_power_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    pcfg = (mlan_ds_power_cfg *) req->pbuf;
+    pcfg->sub_command = MLAN_OID_POWER_CFG;
+    req->req_id = MLAN_IOCTL_POWER_CFG;
+    req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    vwrq->value = pcfg->param.power_cfg.power_level;
+    if (pcfg->param.power_cfg.is_power_auto)
+        vwrq->fixed = 0;
+    else
+        vwrq->fixed = 1;
+    if (bss_info.radio_on) {
+        vwrq->disabled = 0;
+        vwrq->flags = IW_TXPOW_DBM;
+    } else {
+        vwrq->disabled = 1;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief  Set power management 
+ *   
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static int
+woal_set_power(struct net_device *dev, struct iw_request_info *info,
+               struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_pm_cfg *pm_cfg = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    pm_cfg = (mlan_ds_pm_cfg *) req->pbuf;
+    pm_cfg->sub_command = MLAN_OID_PM_CFG_IEEE_PS;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+    req->action = MLAN_ACT_SET;
+
+    PRINTM(MINFO, "PS_MODE set power disabled=%d\n", vwrq->disabled);
+    if (vwrq->disabled)
+        pm_cfg->param.ps_mode = 0;
+    else {
+        /* Check not support case only (vwrq->disabled == FALSE) */
+        if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+            PRINTM(MERROR, "Setting power timeout command is not supported\n");
+            ret = -EINVAL;
+            goto done;
+        } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
+            PRINTM(MERROR, "Setting power period command is not supported\n");
+            ret = -EINVAL;
+            goto done;
+        }
+        pm_cfg->param.ps_mode = 1;
+    }
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+    }
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief  Get power management 
+ *   
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     MLAN_STATUS_SUCCESS --success, otherwise fail
+ */
+static int
+woal_get_power(struct net_device *dev, struct iw_request_info *info,
+               struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_pm_cfg *pm_cfg = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_pm_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    pm_cfg = (mlan_ds_pm_cfg *) req->pbuf;
+    pm_cfg->sub_command = MLAN_OID_PM_CFG_IEEE_PS;
+    req->req_id = MLAN_IOCTL_PM_CFG;
+    req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (pm_cfg->param.ps_mode)
+        vwrq->disabled = 0;
+    else
+        vwrq->disabled = 1;
+
+    vwrq->value = 0;
+
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set Tx retry count
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_retry(struct net_device *dev, struct iw_request_info *info,
+               struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_snmp_mib *mib = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    if (vwrq->flags == IW_RETRY_LIMIT) {
+        /* 
+         * The MAC has a 4-bit Total_Tx_Count register
+         * Total_Tx_Count = 1 + Tx_Retry_Count
+         */
+/** Minimum transmission retry count */
+#define TX_RETRY_MIN 0
+/** Maximum transmission retry count */
+#define TX_RETRY_MAX 14
+        if (vwrq->value < TX_RETRY_MIN || vwrq->value > TX_RETRY_MAX) {
+            ret = -EINVAL;
+            goto done;
+        }
+
+        req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib));
+        if (req == NULL) {
+            ret = -ENOMEM;
+            goto done;
+        }
+
+        mib = (mlan_ds_snmp_mib *) req->pbuf;
+        mib->sub_command = MLAN_OID_SNMP_MIB_RETRY_COUNT;
+        mib->param.retry_count = vwrq->value;
+        req->req_id = MLAN_IOCTL_SNMP_MIB;
+        req->action = MLAN_ACT_SET;
+
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+    } else {
+        ret = -EOPNOTSUPP;
+        goto done;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get Tx retry count
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_retry(struct net_device *dev, struct iw_request_info *info,
+               struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_snmp_mib *mib = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    mib = (mlan_ds_snmp_mib *) req->pbuf;
+    mib->sub_command = MLAN_OID_SNMP_MIB_RETRY_COUNT;
+    req->req_id = MLAN_IOCTL_SNMP_MIB;
+    req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    vwrq->disabled = 0;
+    if (!vwrq->flags) {
+        vwrq->flags = IW_RETRY_LIMIT;
+        /* Get Tx retry count */
+        vwrq->value = mib->param.retry_count;
+    }
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set encryption key
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param dwrq                 A pointer to iw_point structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_encode(struct net_device *dev, struct iw_request_info *info,
+                struct iw_point *dwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_encrypt_key *pkey = NULL;
+    int index = 0;
+    t_u32 auth_mode = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_SET;
+
+    /* Check index */
+    index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+    if (index > 3) {
+        PRINTM(MERROR, "Key index #%d out of range\n", index);
+        ret = -EINVAL;
+        goto done;
+    }
+    if (dwrq->length > MAX_WEP_KEY_SIZE) {
+        pkey = (mlan_ds_encrypt_key *) extra;
+        if (pkey->key_len <= MAX_WEP_KEY_SIZE) {
+            dwrq->length = pkey->key_len;
+            dwrq->flags = pkey->key_index + 1;
+        }
+    }
+    sec->param.encrypt_key.key_len = 0;
+    if (dwrq->length) {
+        if (dwrq->length > MAX_WEP_KEY_SIZE) {
+            PRINTM(MERROR, "Key length (%d) out of range\n", dwrq->length);
+            ret = -EINVAL;
+            goto done;
+        }
+        if (index < 0)
+            sec->param.encrypt_key.is_current_wep_key = MTRUE;
+        else
+            sec->param.encrypt_key.key_index = index;
+        if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
+            memcpy(sec->param.encrypt_key.key_material, extra, dwrq->length);
+            /* Set the length */
+            if (dwrq->length > MIN_WEP_KEY_SIZE)
+                sec->param.encrypt_key.key_len = MAX_WEP_KEY_SIZE;
+            else
+                sec->param.encrypt_key.key_len = MIN_WEP_KEY_SIZE;
+        }
+    } else {
+        /* 
+         * No key provided so it is either enable key, 
+         * on or off
+         */
+        if (dwrq->flags & IW_ENCODE_DISABLED) {
+            PRINTM(MINFO, "*** iwconfig mlanX key off ***\n");
+            sec->param.encrypt_key.key_disable = MTRUE;
+        } else {
+            /* 
+             * iwconfig mlanX key [n]
+             * iwconfig mlanX key on 
+             * Do we want to just set the transmit key index ? 
+             */
+            if (index < 0) {
+                PRINTM(MINFO, "*** iwconfig mlanX key on ***\n");
+                sec->param.encrypt_key.is_current_wep_key = MTRUE;
+            } else
+                sec->param.encrypt_key.key_index = index;
+        }
+    }
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    if (dwrq->flags & (IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)) {
+        if (dwrq->flags & IW_ENCODE_RESTRICTED) {
+            /* iwconfig mlanX restricted key [1] */
+            auth_mode = MLAN_AUTH_MODE_SHARED;
+            PRINTM(MINFO, "Auth mode restricted!\n");
+        } else if (dwrq->flags & IW_ENCODE_OPEN) {
+            /* iwconfig mlanX key [2] open */
+            auth_mode = MLAN_AUTH_MODE_OPEN;
+            PRINTM(MINFO, "Auth mode open!\n");
+        }
+        if (MLAN_STATUS_SUCCESS !=
+            woal_set_auth_mode(priv, MOAL_IOCTL_WAIT, auth_mode))
+            ret = -EFAULT;
+    }
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get encryption key
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param dwrq                 A pointer to iw_point structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_encode(struct net_device *dev, struct iw_request_info *info,
+                struct iw_point *dwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_sec_cfg *sec = NULL;
+    mlan_ioctl_req *req = NULL;
+    t_u32 auth_mode;
+    int index = (dwrq->flags & IW_ENCODE_INDEX);
+
+    ENTER();
+    if (index < 0 || index > 4) {
+        PRINTM(MERROR, "Key index #%d out of range\n", index);
+        ret = -EINVAL;
+        goto done;
+    }
+    if (MLAN_STATUS_SUCCESS !=
+        woal_get_auth_mode(priv, MOAL_IOCTL_WAIT, &auth_mode)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    dwrq->flags = 0;
+    /* 
+     * Check encryption mode 
+     */
+    switch (auth_mode) {
+    case MLAN_AUTH_MODE_OPEN:
+        dwrq->flags = IW_ENCODE_OPEN;
+        break;
+
+    case MLAN_AUTH_MODE_SHARED:
+    case MLAN_AUTH_MODE_NETWORKEAP:
+        dwrq->flags = IW_ENCODE_RESTRICTED;
+        break;
+    default:
+        dwrq->flags = IW_ENCODE_DISABLED | IW_ENCODE_OPEN;
+        break;
+    }
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_GET;
+
+    if (!index)
+        sec->param.encrypt_key.is_current_wep_key = MTRUE;
+    else
+        sec->param.encrypt_key.key_index = index - 1;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    memset(extra, 0, 16);
+    if (sec->param.encrypt_key.key_len) {
+        memcpy(extra, sec->param.encrypt_key.key_material,
+               sec->param.encrypt_key.key_len);
+        dwrq->length = sec->param.encrypt_key.key_len;
+        dwrq->flags |= (sec->param.encrypt_key.key_index + 1);
+        dwrq->flags &= ~IW_ENCODE_DISABLED;
+    } else if (sec->param.encrypt_key.key_disable)
+        dwrq->flags |= IW_ENCODE_DISABLED;
+    else
+        dwrq->flags &= ~IW_ENCODE_DISABLED;
+
+    dwrq->flags |= IW_ENCODE_NOKEY;
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set data rate
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param vwrq         A pointer to iw_param structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_set_rate(struct net_device *dev, struct iw_request_info *info,
+              struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_rate *rate = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    rate = (mlan_ds_rate *) req->pbuf;
+    rate->sub_command = MLAN_OID_RATE_CFG;
+    req->req_id = MLAN_IOCTL_RATE;
+    req->action = MLAN_ACT_SET;
+    if (vwrq->value == -1) {
+        rate->param.rate_cfg.is_rate_auto = 1;
+    } else {
+        rate->param.rate_cfg.is_rate_auto = 0;
+        rate->param.rate_cfg.rate_type = MLAN_RATE_VALUE;
+        rate->param.rate_cfg.rate = vwrq->value / 500000;
+    }
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get data rate
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param vwrq         A pointer to iw_param structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0 --success, otherwise fail
+ */
+static int
+woal_get_rate(struct net_device *dev, struct iw_request_info *info,
+              struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_rate *rate = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_rate));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    rate = (mlan_ds_rate *) req->pbuf;
+    rate->param.rate_cfg.rate_type = MLAN_RATE_VALUE;
+    rate->sub_command = MLAN_OID_RATE_CFG;
+    req->req_id = MLAN_IOCTL_RATE;
+    req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (rate->param.rate_cfg.is_rate_auto)
+        vwrq->fixed = 0;
+    else
+        vwrq->fixed = 1;
+    vwrq->value = rate->param.rate_cfg.rate * 500000;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set RTS threshold
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_rts(struct net_device *dev, struct iw_request_info *info,
+             struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_snmp_mib *mib = NULL;
+    mlan_ioctl_req *req = NULL;
+    int rthr = vwrq->value;
+
+    ENTER();
+
+    if (vwrq->disabled) {
+        rthr = MLAN_RTS_MAX_VALUE;
+    } else {
+        if (rthr < MLAN_RTS_MIN_VALUE || rthr > MLAN_RTS_MAX_VALUE) {
+            ret = -EINVAL;
+            goto done;
+        }
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    mib = (mlan_ds_snmp_mib *) req->pbuf;
+    mib->sub_command = MLAN_OID_SNMP_MIB_RTS_THRESHOLD;
+    mib->param.rts_threshold = rthr;
+    req->req_id = MLAN_IOCTL_SNMP_MIB;
+    req->action = MLAN_ACT_SET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get RTS threshold
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_rts(struct net_device *dev, struct iw_request_info *info,
+             struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_snmp_mib *mib = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    mib = (mlan_ds_snmp_mib *) req->pbuf;
+    mib->sub_command = MLAN_OID_SNMP_MIB_RTS_THRESHOLD;
+    req->req_id = MLAN_IOCTL_SNMP_MIB;
+    req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    vwrq->value = mib->param.rts_threshold;
+    vwrq->disabled = ((vwrq->value < MLAN_RTS_MIN_VALUE)
+                      || (vwrq->value > MLAN_RTS_MAX_VALUE));
+    vwrq->fixed = 1;
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set Fragment threshold
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_frag(struct net_device *dev, struct iw_request_info *info,
+              struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_snmp_mib *mib = NULL;
+    mlan_ioctl_req *req = NULL;
+    int fthr = vwrq->value;
+
+    ENTER();
+
+    if (vwrq->disabled) {
+        fthr = MLAN_FRAG_MAX_VALUE;
+    } else {
+        if (fthr < MLAN_FRAG_MIN_VALUE || fthr > MLAN_FRAG_MAX_VALUE) {
+            ret = -EINVAL;
+            goto done;
+        }
+    }
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    mib = (mlan_ds_snmp_mib *) req->pbuf;
+    mib->sub_command = MLAN_OID_SNMP_MIB_FRAG_THRESHOLD;
+    mib->param.frag_threshold = fthr;
+    req->req_id = MLAN_IOCTL_SNMP_MIB;
+    req->action = MLAN_ACT_SET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get Fragment threshold
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_frag(struct net_device *dev, struct iw_request_info *info,
+              struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_snmp_mib *mib = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_snmp_mib));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    mib = (mlan_ds_snmp_mib *) req->pbuf;
+    mib->sub_command = MLAN_OID_SNMP_MIB_FRAG_THRESHOLD;
+    req->req_id = MLAN_IOCTL_SNMP_MIB;
+    req->action = MLAN_ACT_GET;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    vwrq->value = mib->param.frag_threshold;
+    vwrq->disabled = ((vwrq->value < MLAN_FRAG_MIN_VALUE)
+                      || (vwrq->value > MLAN_FRAG_MAX_VALUE));
+    vwrq->fixed = 1;
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get IE
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param dwrq                 A pointer to iw_point structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_gen_ie(struct net_device *dev, struct iw_request_info *info,
+                struct iw_point *dwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_misc_cfg *misc = NULL;
+    mlan_ioctl_req *req = NULL;
+    int copy_size = 0;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    misc = (mlan_ds_misc_cfg *) req->pbuf;
+    misc->sub_command = MLAN_OID_MISC_GEN_IE;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+    req->action = MLAN_ACT_GET;
+    misc->param.gen_ie.type = MLAN_IE_TYPE_GEN_IE;
+
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    copy_size = MIN(misc->param.gen_ie.len, dwrq->length);
+    memcpy(extra, misc->param.gen_ie.ie_data, copy_size);
+    dwrq->length = copy_size;
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set IE
+ *
+ *  Pass an opaque block of data, expected to be IEEE IEs, to the driver 
+ *    for eventual passthrough to the firmware in an associate/join 
+ *    (and potentially start) command.
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param dwrq                 A pointer to iw_point structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_gen_ie(struct net_device *dev, struct iw_request_info *info,
+                struct iw_point *dwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_ds_misc_cfg *misc = NULL;
+    mlan_ioctl_req *req = NULL;
+
+    ENTER();
+
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+
+    misc = (mlan_ds_misc_cfg *) req->pbuf;
+    misc->sub_command = MLAN_OID_MISC_GEN_IE;
+    req->req_id = MLAN_IOCTL_MISC_CFG;
+    req->action = MLAN_ACT_SET;
+
+    if (dwrq->length > MAX_IE_SIZE) {
+        ret = -EFAULT;
+        goto done;
+    }
+    misc->param.gen_ie.type = MLAN_IE_TYPE_GEN_IE;
+    misc->param.gen_ie.len = dwrq->length;
+    memcpy(misc->param.gen_ie.ie_data, extra, misc->param.gen_ie.len);
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+        ret = -EFAULT;
+        goto done;
+    }
+  done:
+    if (req)
+        kfree(req);
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief  Extended version of encoding configuration 
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param dwrq         A pointer to iw_point structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return              0 --success, otherwise fail
+ */
+static int
+woal_set_encode_ext(struct net_device *dev,
+                    struct iw_request_info *info,
+                    struct iw_point *dwrq, char *extra)
+{
+    struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    int key_index;
+    t_u8 *pkey_material = NULL;
+    mlan_ioctl_req *req = NULL;
+    mlan_ds_sec_cfg *sec = NULL;
+    int ret = 0;
+
+    ENTER();
+    key_index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+    if (key_index < 0 || key_index > 3) {
+        ret = -EINVAL;
+        goto done;
+    }
+    if (ext->key_len > (dwrq->length - sizeof(struct iw_encode_ext))) {
+        ret = -EINVAL;
+        goto done;
+    }
+    req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_sec_cfg));
+    if (req == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    sec = (mlan_ds_sec_cfg *) req->pbuf;
+    sec->sub_command = MLAN_OID_SEC_CFG_ENCRYPT_KEY;
+    req->req_id = MLAN_IOCTL_SEC_CFG;
+    req->action = MLAN_ACT_SET;
+    pkey_material = (t_u8 *) (ext + 1);
+    sec->param.encrypt_key.key_len = ext->key_len;
+    /* Disable Key */
+    if ((dwrq->flags & IW_ENCODE_DISABLED) && !ext->key_len) {
+        sec->param.encrypt_key.key_disable = MTRUE;
+    } else if (ext->key_len <= MAX_WEP_KEY_SIZE) {
+        /* Set WEP key */
+        sec->param.encrypt_key.key_index = key_index;
+        memcpy(sec->param.encrypt_key.key_material, pkey_material,
+               ext->key_len);
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT)) {
+            ret = -EFAULT;
+            goto done;
+        }
+        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+            sec->param.encrypt_key.key_len = 0;
+        }
+    } else {
+        /* Set WPA key */
+        sec->param.encrypt_key.key_index = key_index;
+        memcpy(sec->param.encrypt_key.key_material, pkey_material,
+               ext->key_len);
+#define IW_ENCODE_ALG_SMS4   0x20
+        /* Set WAPI key */
+        if (ext->alg == IW_ENCODE_ALG_SMS4) {
+            sec->param.encrypt_key.is_wapi_key = MTRUE;
+            memcpy(sec->param.encrypt_key.mac_addr, (u8 *) ext->addr.sa_data,
+                   ETH_ALEN);
+            memcpy(sec->param.encrypt_key.pn, ext->tx_seq, PN_SIZE);
+        }
+    }
+    if (MLAN_STATUS_SUCCESS != woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT))
+        ret = -EFAULT;
+  done:
+    if (req)
+        kfree(req);
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief  Extended version of encoding configuration 
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param dwrq         A pointer to iw_point structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             -EOPNOTSUPP
+ */
+static int
+woal_get_encode_ext(struct net_device *dev,
+                    struct iw_request_info *info,
+                    struct iw_point *dwrq, char *extra)
+{
+    ENTER();
+    LEAVE();
+    return -EOPNOTSUPP;
+}
+
+/** 
+ *  @brief  Request MLME operation 
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param dwrq         A pointer to iw_point structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0--success, otherwise fail
+ */
+static int
+woal_set_mlme(struct net_device *dev,
+              struct iw_request_info *info, struct iw_point *dwrq, char *extra)
+{
+    struct iw_mlme *mlme = (struct iw_mlme *) extra;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    int ret = 0;
+
+    ENTER();
+    if ((mlme->cmd == IW_MLME_DEAUTH) || (mlme->cmd == IW_MLME_DISASSOC)) {
+        if (MLAN_STATUS_SUCCESS !=
+            woal_disconnect(priv, MOAL_IOCTL_WAIT, (t_u8 *) mlme->addr.sa_data))
+            ret = -EFAULT;
+    }
+    LEAVE();
+    return ret;
+}
+
+/** @brief Set authentication mode parameters
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_set_auth(struct net_device *dev, struct iw_request_info *info,
+              struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    t_u32 auth_mode = 0;
+    t_u32 encrypt_mode = 0;
+    ENTER();
+
+    switch (vwrq->flags & IW_AUTH_INDEX) {
+    case IW_AUTH_CIPHER_PAIRWISE:
+    case IW_AUTH_CIPHER_GROUP:
+        if (vwrq->value & IW_AUTH_CIPHER_NONE)
+            encrypt_mode = MLAN_ENCRYPTION_MODE_NONE;
+        else if (vwrq->value & IW_AUTH_CIPHER_WEP40)
+            encrypt_mode = MLAN_ENCRYPTION_MODE_WEP40;
+        else if (vwrq->value & IW_AUTH_CIPHER_WEP104)
+            encrypt_mode = MLAN_ENCRYPTION_MODE_WEP104;
+        else if (vwrq->value & IW_AUTH_CIPHER_TKIP)
+            encrypt_mode = MLAN_ENCRYPTION_MODE_TKIP;
+        else if (vwrq->value & IW_AUTH_CIPHER_CCMP)
+            encrypt_mode = MLAN_ENCRYPTION_MODE_CCMP;
+        if (MLAN_STATUS_SUCCESS !=
+            woal_set_encrypt_mode(priv, MOAL_IOCTL_WAIT, encrypt_mode))
+            ret = -EFAULT;
+        break;
+    case IW_AUTH_80211_AUTH_ALG:
+        switch (vwrq->value) {
+        case IW_AUTH_ALG_SHARED_KEY:
+            auth_mode = MLAN_AUTH_MODE_SHARED;
+            break;
+        case IW_AUTH_ALG_LEAP:
+            auth_mode = MLAN_AUTH_MODE_NETWORKEAP;
+            break;
+        case IW_AUTH_ALG_OPEN_SYSTEM:
+        default:
+            auth_mode = MLAN_AUTH_MODE_OPEN;
+            break;
+        }
+        if (MLAN_STATUS_SUCCESS !=
+            woal_set_auth_mode(priv, MOAL_IOCTL_WAIT, auth_mode))
+            ret = -EFAULT;
+        break;
+    case IW_AUTH_WPA_ENABLED:
+        if (MLAN_STATUS_SUCCESS !=
+            woal_set_wpa_enable(priv, MOAL_IOCTL_WAIT, vwrq->value))
+            ret = -EFAULT;
+        break;
+#define IW_AUTH_WAPI_ENABLED    0x20
+    case IW_AUTH_WAPI_ENABLED:
+        if (MLAN_STATUS_SUCCESS !=
+            woal_set_wapi_enable(priv, MOAL_IOCTL_WAIT, vwrq->value))
+            ret = -EFAULT;
+        break;
+    case IW_AUTH_WPA_VERSION:
+    case IW_AUTH_KEY_MGMT:
+    case IW_AUTH_TKIP_COUNTERMEASURES:
+    case IW_AUTH_DROP_UNENCRYPTED:
+    case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+    case IW_AUTH_ROAMING_CONTROL:
+    case IW_AUTH_PRIVACY_INVOKED:
+    default:
+        ret = -EOPNOTSUPP;
+        break;
+    }
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Get authentication mode parameters
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param vwrq                 A pointer to iw_param structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_auth(struct net_device *dev, struct iw_request_info *info,
+              struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    t_u32 encrypt_mode = 0;
+    t_u32 auth_mode;
+    t_u32 wpa_enable;
+    ENTER();
+    switch (vwrq->flags & IW_AUTH_INDEX) {
+    case IW_AUTH_CIPHER_PAIRWISE:
+    case IW_AUTH_CIPHER_GROUP:
+        if (MLAN_STATUS_SUCCESS !=
+            woal_get_encrypt_mode(priv, MOAL_IOCTL_WAIT, &encrypt_mode))
+            ret = -EFAULT;
+        else {
+            if (encrypt_mode == MLAN_ENCRYPTION_MODE_NONE)
+                vwrq->value = IW_AUTH_CIPHER_NONE;
+            else if (encrypt_mode == MLAN_ENCRYPTION_MODE_WEP40)
+                vwrq->value = IW_AUTH_CIPHER_WEP40;
+            else if (encrypt_mode == MLAN_ENCRYPTION_MODE_TKIP)
+                vwrq->value = IW_AUTH_CIPHER_TKIP;
+            else if (encrypt_mode == MLAN_ENCRYPTION_MODE_CCMP)
+                vwrq->value = IW_AUTH_CIPHER_CCMP;
+            else if (encrypt_mode == MLAN_ENCRYPTION_MODE_WEP104)
+                vwrq->value = IW_AUTH_CIPHER_WEP104;
+        }
+        break;
+    case IW_AUTH_80211_AUTH_ALG:
+        if (MLAN_STATUS_SUCCESS !=
+            woal_get_auth_mode(priv, MOAL_IOCTL_WAIT, &auth_mode))
+            ret = -EFAULT;
+        else {
+            if (auth_mode == MLAN_AUTH_MODE_SHARED)
+                vwrq->value = IW_AUTH_ALG_SHARED_KEY;
+            else if (auth_mode == MLAN_AUTH_MODE_NETWORKEAP)
+                vwrq->value = IW_AUTH_ALG_LEAP;
+            else
+                vwrq->value = IW_AUTH_ALG_OPEN_SYSTEM;
+        }
+        break;
+    case IW_AUTH_WPA_ENABLED:
+        if (MLAN_STATUS_SUCCESS !=
+            woal_get_wpa_enable(priv, MOAL_IOCTL_WAIT, &wpa_enable))
+            ret = -EFAULT;
+        else
+            vwrq->value = wpa_enable;
+        break;
+    case IW_AUTH_WPA_VERSION:
+    case IW_AUTH_KEY_MGMT:
+    case IW_AUTH_TKIP_COUNTERMEASURES:
+    case IW_AUTH_DROP_UNENCRYPTED:
+    case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+    case IW_AUTH_ROAMING_CONTROL:
+    case IW_AUTH_PRIVACY_INVOKED:
+    default:
+        ret = -EOPNOTSUPP;
+        goto done;
+    }
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/* Data rate listing
+ *      MULTI_BANDS:
+ *              abg             a       b       b/g
+ *  Infra       G(12)           A(8)    B(4)    G(12)
+ *  Adhoc       A+B(12)         A(8)    B(4)    B(4)
+ *      non-MULTI_BANDS:
+                                        b       b/g
+ *  Infra                               B(4)    G(12)
+ *  Adhoc                               B(4)    B(4)
+ */
+/**
+ *  @brief Get Range Info
+ *
+ *  @param dev                  A pointer to net_device structure
+ *  @param info                 A pointer to iw_request_info structure
+ *  @param dwrq                 A pointer to iw_point structure
+ *  @param extra                A pointer to extra data buf
+ *
+ *  @return                     0 --success, otherwise fail
+ */
+static int
+woal_get_range(struct net_device *dev, struct iw_request_info *info,
+               struct iw_point *dwrq, char *extra)
+{
+    int i;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    struct iw_range *range = (struct iw_range *) extra;
+    moal_802_11_rates rates;
+    mlan_chan_list chan_list;
+    mlan_bss_info bss_info;
+
+    ENTER();
+
+    dwrq->length = sizeof(struct iw_range);
+    memset(range, 0, sizeof(struct iw_range));
+
+    range->min_nwid = 0;
+    range->max_nwid = 0;
+
+    memset(&rates, 0, sizeof(rates));
+    woal_get_data_rates(priv, MOAL_IOCTL_WAIT, &rates);
+    range->num_bitrates = rates.num_of_rates;
+
+    for (i = 0; i < MIN(range->num_bitrates, IW_MAX_BITRATES) && rates.rates[i];
+         i++) {
+        range->bitrate[i] = (rates.rates[i] & 0x7f) * 500000;
+    }
+    range->num_bitrates = i;
+    PRINTM(MINFO, "IW_MAX_BITRATES=%d num_bitrates=%d\n", IW_MAX_BITRATES,
+           range->num_bitrates);
+
+    range->num_frequency = 0;
+
+    memset(&chan_list, 0, sizeof(chan_list));
+
+    woal_get_channel_list(priv, MOAL_IOCTL_WAIT, &chan_list);
+
+    range->num_frequency = MIN(chan_list.num_of_chan, IW_MAX_FREQUENCIES);
+
+    for (i = 0; i < range->num_frequency; i++) {
+        range->freq[i].i = (long) chan_list.cf[i].channel;
+        range->freq[i].m = (long) chan_list.cf[i].freq * 100000;
+        range->freq[i].e = 1;
+    }
+
+    PRINTM(MINFO, "IW_MAX_FREQUENCIES=%d num_frequency=%d\n",
+           IW_MAX_FREQUENCIES, range->num_frequency);
+
+    range->num_channels = range->num_frequency;
+
+    woal_sort_channels(&range->freq[0], range->num_frequency);
+
+    /* 
+     * Set an indication of the max TCP throughput in bit/s that we can
+     * expect using this interface
+     */
+    if (i > 2)
+        range->throughput = 5000 * 1000;
+    else
+        range->throughput = 1500 * 1000;
+
+    range->min_rts = MLAN_RTS_MIN_VALUE;
+    range->max_rts = MLAN_RTS_MAX_VALUE;
+    range->min_frag = MLAN_FRAG_MIN_VALUE;
+    range->max_frag = MLAN_FRAG_MAX_VALUE;
+
+    range->encoding_size[0] = 5;
+    range->encoding_size[1] = 13;
+    range->num_encoding_sizes = 2;
+    range->max_encoding_tokens = 4;
+
+/** Minimum power period */
+#define IW_POWER_PERIOD_MIN 1000000     /* 1 sec */
+/** Maximum power period */
+#define IW_POWER_PERIOD_MAX 120000000   /* 2 min */
+/** Minimum power timeout value */
+#define IW_POWER_TIMEOUT_MIN 1000       /* 1 ms */
+/** Maximim power timeout value */
+#define IW_POWER_TIMEOUT_MAX 1000000    /* 1 sec */
+
+    /* Power Management duration & timeout */
+    range->min_pmp = IW_POWER_PERIOD_MIN;
+    range->max_pmp = IW_POWER_PERIOD_MAX;
+    range->min_pmt = IW_POWER_TIMEOUT_MIN;
+    range->max_pmt = IW_POWER_TIMEOUT_MAX;
+    range->pmp_flags = IW_POWER_PERIOD;
+    range->pmt_flags = IW_POWER_TIMEOUT;
+    range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
+
+    /* 
+     * Minimum version we recommend
+     */
+    range->we_version_source = 15;
+
+    /* 
+     * Version we are compiled with
+     */
+    range->we_version_compiled = WIRELESS_EXT;
+
+    range->retry_capa = IW_RETRY_LIMIT;
+    range->retry_flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+
+    range->min_retry = MLAN_TX_RETRY_MIN;
+    range->max_retry = MLAN_TX_RETRY_MAX;
+
+    /* 
+     * Set the qual, level and noise range values
+     */
+    /* 
+     * need to put the right values here
+     */
+/** Maximum quality percentage */
+#define IW_MAX_QUAL_PERCENT 100
+/** Average quality percentage */
+#define IW_AVG_QUAL_PERCENT 70
+    range->max_qual.qual = IW_MAX_QUAL_PERCENT;
+    range->max_qual.level = 0;
+    range->max_qual.noise = 0;
+
+    range->avg_qual.qual = IW_AVG_QUAL_PERCENT;
+    range->avg_qual.level = 0;
+    range->avg_qual.noise = 0;
+
+    range->sensitivity = 0;
+    /* 
+     * Setup the supported power level ranges
+     */
+    memset(range->txpower, 0, sizeof(range->txpower));
+
+    memset(&bss_info, 0, sizeof(bss_info));
+
+    woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info);
+
+    range->txpower[0] = bss_info.min_power_level;
+    range->txpower[1] = bss_info.max_power_level;
+    range->num_txpower = 2;
+    range->txpower_capa = IW_TXPOW_DBM | IW_TXPOW_RANGE;
+
+    LEAVE();
+    return 0;
+}
+
+/**
+ *  @brief Scan Network
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param vwrq         A pointer to iw_param structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0--success, otherwise fail
+ */
+int
+woal_set_scan(struct net_device *dev, struct iw_request_info *info,
+              struct iw_param *vwrq, char *extra)
+{
+    int ret = 0;
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+#ifdef REASSOCIATION
+    moal_handle *handle = priv->phandle;
+#endif
+#if WIRELESS_EXT >= 18
+    struct iw_scan_req *req;
+    struct iw_point *dwrq = (struct iw_point *) vwrq;
+#endif
+    mlan_802_11_ssid req_ssid;
+
+    ENTER();
+
+    if (priv->scan_pending_on_block == MTRUE) {
+        PRINTM(MCMND, "scan already in processing...\n");
+        LEAVE();
+        return ret;
+    }
+#ifdef REASSOCIATION
+    if (MOAL_ACQ_SEMAPHORE_BLOCK(&handle->reassoc_sem)) {
+        PRINTM(MERROR, "Acquire semaphore error, woal_set_scan\n");
+        LEAVE();
+        return -EBUSY;
+    }
+#endif /* REASSOCIATION */
+
+    memset(&req_ssid, 0x00, sizeof(mlan_802_11_ssid));
+
+#if WIRELESS_EXT >= 18
+    if ((dwrq->flags & IW_SCAN_THIS_ESSID) &&
+        (dwrq->length == sizeof(struct iw_scan_req))) {
+        req = (struct iw_scan_req *) extra;
+
+        if (req->essid_len <= MLAN_MAX_SSID_LENGTH) {
+
+            req_ssid.ssid_len = req->essid_len;
+            memcpy(req_ssid.ssid, (t_u8 *) req->essid, req->essid_len);
+            if (MLAN_STATUS_SUCCESS !=
+                woal_request_scan(priv, MOAL_NO_WAIT, &req_ssid)) {
+                ret = -EFAULT;
+                goto done;
+            }
+        }
+    } else {
+#endif
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_scan(priv, MOAL_NO_WAIT, &req_ssid)) {
+            ret = -EFAULT;
+            goto done;
+        }
+#if WIRELESS_EXT >= 18
+    }
+#endif
+
+    if (priv->phandle->surprise_removed) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+  done:
+#ifdef REASSOCIATION
+    MOAL_REL_SEMAPHORE(&handle->reassoc_sem);
+#endif
+
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief Set essid
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param dwrq         A pointer to iw_point structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0--success, otherwise fail
+ */
+static int
+woal_set_essid(struct net_device *dev, struct iw_request_info *info,
+               struct iw_point *dwrq, char *extra)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_802_11_ssid req_ssid;
+    mlan_ssid_bssid ssid_bssid;
+#ifdef REASSOCIATION
+    moal_handle *handle = priv->phandle;
+    mlan_bss_info bss_info;
+#endif
+    int ret = 0;
+    t_u32 mode = 0;
+
+    ENTER();
+
+#ifdef REASSOCIATION
+    /* Cancel re-association */
+    priv->reassoc_required = MFALSE;
+
+    if (MOAL_ACQ_SEMAPHORE_BLOCK(&handle->reassoc_sem)) {
+        PRINTM(MERROR, "Acquire semaphore error, woal_set_essid\n");
+        LEAVE();
+        return -EBUSY;
+    }
+#endif /* REASSOCIATION */
+
+    /* Check the size of the string */
+    if (dwrq->length > IW_ESSID_MAX_SIZE + 1) {
+        ret = -E2BIG;
+        goto setessid_ret;
+    }
+    memset(&req_ssid, 0, sizeof(mlan_802_11_ssid));
+    memset(&ssid_bssid, 0, sizeof(mlan_ssid_bssid));
+
+    /* 
+     * Check if we asked for `any' or 'particular'
+     */
+    if (!dwrq->flags) {
+        /* Do normal SSID scanning */
+        if (MLAN_STATUS_SUCCESS !=
+            woal_request_scan(priv, MOAL_IOCTL_WAIT, NULL)) {
+            ret = -EFAULT;
+            goto setessid_ret;
+        }
+    } else {
+        /* Set the SSID */
+#if WIRELESS_EXT > 20
+        req_ssid.ssid_len = dwrq->length;
+#else
+        req_ssid.ssid_len = dwrq->length - 1;
+#endif
+        memcpy(req_ssid.ssid, extra,
+               MIN(req_ssid.ssid_len, MLAN_MAX_SSID_LENGTH));
+        if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
+            PRINTM(MERROR, "Invalid SSID - aborting set_essid\n");
+            ret = -EINVAL;
+            goto setessid_ret;
+        }
+        PRINTM(MINFO, "Requested new SSID = %s\n",
+               (req_ssid.ssid_len > 0) ? (char *) req_ssid.ssid : "NULL");
+
+        if (dwrq->flags != 0xFFFF) {
+            /* Do specific SSID scanning */
+            if (MLAN_STATUS_SUCCESS != woal_request_scan(priv, MOAL_IOCTL_WAIT,
+                                                         &req_ssid)) {
+                ret = -EFAULT;
+                goto setessid_ret;
+            }
+        }
+
+        memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(mlan_802_11_ssid));
+    }
+
+    /* disconnect before try to associate */
+    woal_disconnect(priv, MOAL_IOCTL_WAIT, NULL);
+    if (MLAN_STATUS_SUCCESS !=
+        woal_set_ewpa_mode(priv, MOAL_IOCTL_WAIT, &ssid_bssid)) {
+        ret = -EFAULT;
+        goto setessid_ret;
+    }
+    mode = woal_get_mode(priv, MOAL_IOCTL_WAIT);
+
+    if (mode != IW_MODE_ADHOC) {
+        if (MLAN_STATUS_SUCCESS !=
+            woal_find_best_network(priv, MOAL_IOCTL_WAIT, &ssid_bssid)) {
+            ret = -EFAULT;
+            goto setessid_ret;
+        }
+    }
+
+    /* Connect to BSS by ESSID */
+    memset(&ssid_bssid.bssid, 0, MLAN_MAC_ADDR_LENGTH);
+
+    if (MLAN_STATUS_SUCCESS != woal_bss_start(priv,
+                                              MOAL_IOCTL_WAIT, &ssid_bssid)) {
+        ret = -EFAULT;
+        goto setessid_ret;
+    }
+#ifdef REASSOCIATION
+    memset(&bss_info, 0, sizeof(bss_info));
+    if (MLAN_STATUS_SUCCESS != woal_get_bss_info(priv,
+                                                 MOAL_IOCTL_WAIT, &bss_info)) {
+        ret = -EFAULT;
+        goto setessid_ret;
+    }
+    memcpy(&priv->prev_ssid_bssid.ssid, &bss_info.ssid,
+           sizeof(mlan_802_11_ssid));
+    memcpy(&priv->prev_ssid_bssid.bssid, &bss_info.bssid, MLAN_MAC_ADDR_LENGTH);
+#endif /* REASSOCIATION */
+
+  setessid_ret:
+
+#ifdef REASSOCIATION
+    MOAL_REL_SEMAPHORE(&handle->reassoc_sem);
+#endif
+
+    LEAVE();
+    return ret;
+}
+
+/** 
+ *  @brief Get current essid 
+ *   
+ *  @param dev      A pointer to net_device structure
+ *  @param info     A pointer to iw_request_info structure
+ *  @param dwrq     A pointer to iw_point structure
+ *  @param extra    A pointer to extra data buf
+ *
+ *  @return         0--success, otherwise fail
+ */
+static int
+woal_get_essid(struct net_device *dev, struct iw_request_info *info,
+               struct iw_point *dwrq, char *extra)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    mlan_bss_info bss_info;
+    int ret = 0;
+
+    ENTER();
+
+    memset(&bss_info, 0, sizeof(bss_info));
+
+    if (MLAN_STATUS_SUCCESS !=
+        woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
+        ret = -EFAULT;
+        goto done;
+    }
+
+    if (bss_info.media_connected) {
+        dwrq->length = MIN(dwrq->length, bss_info.ssid.ssid_len);
+        memcpy(extra, bss_info.ssid.ssid, dwrq->length);
+    } else
+        dwrq->length = 0;
+
+    if (bss_info.scan_table_idx)
+        dwrq->flags = (bss_info.scan_table_idx + 1) & IW_ENCODE_INDEX;
+    else
+        dwrq->flags = 1;
+
+  done:
+    LEAVE();
+    return ret;
+}
+
+/**
+ *  @brief This function validates a SSID as being able to be printed
+ *
+ *  @param pssid   SSID structure to validate
+ *
+ *  @return        MTRUE or MFALSE
+ */
+static BOOLEAN
+woal_ssid_valid(mlan_802_11_ssid * pssid)
+{
+    int ssid_idx;
+
+    ENTER();
+
+    for (ssid_idx = 0; ssid_idx < pssid->ssid_len; ssid_idx++)
+        if (!isprint(pssid->ssid[ssid_idx])) {
+            LEAVE();
+            return MFALSE;
+        }
+
+    LEAVE();
+    return MTRUE;
+}
+
+/**
+ *  @brief  Retrieve the scan table entries via wireless tools IOCTL call
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param dwrq         A pointer to iw_point structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0--success, otherwise fail
+ */
+int
+woal_get_scan(struct net_device *dev, struct iw_request_info *info,
+              struct iw_point *dwrq, char *extra)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    int ret = 0;
+    char *current_ev = extra;
+    char *end_buf = extra + IW_SCAN_MAX_DATA;
+    char *current_val;          /* For rates */
+    struct iw_event iwe;        /* Temporary buffer */
+    int i;
+    int j;
+    mlan_scan_resp scan_resp;
+    mlan_bss_info bss_info;
+    BSSDescriptor_t *scan_table;
+    mlan_ds_get_signal rssi;
+    t_u16 buf_size = 16 + 256 * 2;
+    char *buf = NULL;
+    char *ptr;
+    t_u8 *praw_data;
+    int beacon_size;
+    t_u8 *pbeacon;
+    IEEEtypes_ElementId_e element_id;
+    t_u8 element_len;
+
+    ENTER();
+
+    if (priv->scan_pending_on_block == MTRUE)
+        return -EAGAIN;
+
+    if (!(buf = kmalloc((buf_size), GFP_ATOMIC))) {
+        PRINTM(MERROR, "Cannot allocate buffer!\n");
+        ret = -EFAULT;
+        goto done;
+    }
+
+    memset(&bss_info, 0, sizeof(bss_info));
+    if (MLAN_STATUS_SUCCESS !=
+        woal_get_bss_info(priv, MOAL_IOCTL_WAIT, &bss_info)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    memset(&scan_resp, 0, sizeof(scan_resp));
+    if (MLAN_STATUS_SUCCESS != woal_get_scan_table(priv,
+                                                   MOAL_IOCTL_WAIT,
+                                                   &scan_resp)) {
+        ret = -EFAULT;
+        goto done;
+    }
+    scan_table = (BSSDescriptor_t *) scan_resp.pscan_table;
+    if (dwrq->length)
+        end_buf = extra + dwrq->length;
+    if (priv->media_connected == MTRUE) {
+        PRINTM(MINFO, "Current Ssid: %-32s\n", bss_info.ssid.ssid);
+    }
+    PRINTM(MINFO, "Scan: Get: NumInScanTable = %d\n",
+           (int) scan_resp.num_in_scan_table);
+
+#if WIRELESS_EXT > 13
+    /* The old API using SIOCGIWAPLIST had a hard limit of IW_MAX_AP. The new
+       API using SIOCGIWSCAN is only limited by buffer size WE-14 -> WE-16 the
+       buffer is limited to IW_SCAN_MAX_DATA bytes which is 4096. */
+    for (i = 0; i < scan_resp.num_in_scan_table; i++) {
+        if ((current_ev + MAX_SCAN_CELL_SIZE) >= end_buf) {
+            PRINTM(MINFO, "i=%d break out: current_ev=%p end_buf=%p "
+                   "MAX_SCAN_CELL_SIZE=%d\n",
+                   i, current_ev, end_buf, MAX_SCAN_CELL_SIZE);
+            ret = -E2BIG;
+            break;
+        }
+        if (!scan_table[i].freq) {
+            PRINTM(MERROR, "Invalid channel number %d\n",
+                   (int) scan_table[i].channel);
+            continue;
+        }
+        PRINTM(MINFO, "i=%d  Ssid: %-32s\n", i, scan_table[i].ssid.ssid);
+        if (woal_ssid_valid(&scan_table[i].ssid) == MFALSE) {
+            continue;
+        }
+
+        /* First entry *MUST* be the AP MAC address */
+        iwe.cmd = SIOCGIWAP;
+        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+        memcpy(iwe.u.ap_addr.sa_data, &scan_table[i].mac_address, ETH_ALEN);
+
+        iwe.len = IW_EV_ADDR_LEN;
+        current_ev =
+            IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, iwe.len);
+
+        /* Add the ESSID */
+        iwe.u.data.length = scan_table[i].ssid.ssid_len;
+
+        if (iwe.u.data.length > 32) {
+            iwe.u.data.length = 32;
+        }
+
+        iwe.cmd = SIOCGIWESSID;
+        iwe.u.essid.flags = (i + 1) & IW_ENCODE_INDEX;
+        iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
+        current_ev =
+            IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe,
+                                 (t_s8 *) scan_table[i].ssid.ssid);
+
+        /* Add mode */
+        iwe.cmd = SIOCGIWMODE;
+        if (scan_table[i].bss_mode == MLAN_BSS_MODE_IBSS)
+            iwe.u.mode = IW_MODE_ADHOC;
+        else if (scan_table[i].bss_mode == MLAN_BSS_MODE_INFRA)
+            iwe.u.mode = IW_MODE_MASTER;
+        else
+            iwe.u.mode = IW_MODE_AUTO;
+
+        iwe.len = IW_EV_UINT_LEN;
+        current_ev =
+            IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, iwe.len);
+
+        /* Frequency */
+        iwe.cmd = SIOCGIWFREQ;
+        iwe.u.freq.m = (long) scan_table[i].freq * 100000;
+        iwe.u.freq.e = 1;
+        iwe.len = IW_EV_FREQ_LEN;
+        current_ev =
+            IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, iwe.len);
+
+        memset(&iwe, 0, sizeof(iwe));
+        /* Add quality statistics */
+        iwe.cmd = IWEVQUAL;
+        iwe.u.qual.level = SCAN_RSSI(scan_table[i].rssi);
+        iwe.u.qual.qual = 0;
+        if (!bss_info.bcn_nf_last) {
+            iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
+        } else {
+            iwe.u.qual.noise = bss_info.bcn_nf_last;
+        }
+        if ((bss_info.bss_mode == MLAN_BSS_MODE_IBSS) &&
+            !woal_ssid_cmp(&bss_info.ssid, &scan_table[i].ssid)
+            && bss_info.adhoc_state == ADHOC_STARTED) {
+            memset(&rssi, 0, sizeof(mlan_ds_get_signal));
+            if (MLAN_STATUS_SUCCESS !=
+                woal_get_signal_info(priv, MOAL_IOCTL_WAIT, &rssi)) {
+                ret = -EFAULT;
+                break;
+            }
+            iwe.u.qual.level = rssi.data_rssi_avg;
+        }
+        iwe.len = IW_EV_QUAL_LEN;
+        current_ev =
+            IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, iwe.len);
+
+        /* Add encryption capability */
+        iwe.cmd = SIOCGIWENCODE;
+        if (scan_table[i].privacy) {
+            iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+        } else {
+            iwe.u.data.flags = IW_ENCODE_DISABLED;
+        }
+        iwe.u.data.length = 0;
+        iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
+        current_ev =
+            IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, NULL);
+
+        current_val = current_ev + IW_EV_LCP_LEN;
+
+        iwe.cmd = SIOCGIWRATE;
+
+        iwe.u.bitrate.fixed = 0;
+        iwe.u.bitrate.disabled = 0;
+        iwe.u.bitrate.value = 0;
+
+        /* Bit rate given in 500 kb/s units (+ 0x80) */
+        for (j = 0; j < sizeof(scan_table[i].supported_rates); j++) {
+            if (!scan_table[i].supported_rates[j]) {
+                break;
+            }
+
+            iwe.u.bitrate.value =
+                (scan_table[i].supported_rates[j] & 0x7f) * 500000;
+            iwe.len = IW_EV_PARAM_LEN;
+            current_val =
+                IWE_STREAM_ADD_VALUE(info, current_ev, current_val, end_buf,
+                                     &iwe, iwe.len);
+
+        }
+        if ((bss_info.bss_mode == MLAN_BSS_MODE_IBSS) &&
+            !woal_ssid_cmp(&bss_info.ssid, &scan_table[i].ssid)
+            && bss_info.adhoc_state == ADHOC_STARTED) {
+            iwe.u.bitrate.value = 22 * 500000;
+            iwe.len = IW_EV_PARAM_LEN;
+            current_val =
+                IWE_STREAM_ADD_VALUE(info, current_ev, current_val, end_buf,
+                                     &iwe, iwe.len);
+        }
+
+        /* Check if an event is added */
+        if ((current_val - current_ev) >= IW_EV_PARAM_LEN)
+            current_ev = current_val;
+
+        /* Beacon Interval */
+        memset(&iwe, 0, sizeof(iwe));
+        memset(buf, 0, buf_size);
+        ptr = buf;
+        ptr += sprintf(ptr, "Beacon interval=%d", scan_table[i].beacon_period);
+
+        iwe.u.data.length = strlen(buf);
+        iwe.cmd = IWEVCUSTOM;
+        iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
+        current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, buf);
+        current_val = current_ev + IW_EV_LCP_LEN + strlen(buf);
+
+        /* Parse and send the IEs */
+        pbeacon = scan_table[i].pbeacon_buf;
+        beacon_size = scan_table[i].beacon_buf_size;
+
+        /* Skip time stamp, beacon interval and capability */
+        if (pbeacon) {
+            pbeacon += sizeof(scan_table[i].beacon_period) +
+                sizeof(scan_table[i].time_stamp) +
+                sizeof(scan_table[i].cap_info);
+            beacon_size -= sizeof(scan_table[i].beacon_period) +
+                sizeof(scan_table[i].time_stamp) +
+                sizeof(scan_table[i].cap_info);
+        }
+
+        while (beacon_size >= sizeof(IEEEtypes_Header_t)) {
+            element_id = (IEEEtypes_ElementId_e) (*(t_u8 *) pbeacon);
+            element_len = *((t_u8 *) pbeacon + 1);
+            if (beacon_size < (int) element_len + sizeof(IEEEtypes_Header_t)) {
+                PRINTM(MERROR, "Get scan: Error in processing IE, "
+                       "bytes left < IE length\n");
+                break;
+            }
+
+            switch (element_id) {
+            case VENDOR_SPECIFIC_221:
+            case RSN_IE:
+            case WAPI_IE:
+                praw_data = (t_u8 *) pbeacon;
+                memset(&iwe, 0, sizeof(iwe));
+                memset(buf, 0, buf_size);
+                ptr = buf;
+                memcpy(buf, praw_data,
+                       element_len + sizeof(IEEEtypes_Header_t));
+                iwe.cmd = IWEVGENIE;
+                iwe.u.data.length = element_len + sizeof(IEEEtypes_Header_t);
+                iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
+                current_ev =
+                    IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, buf);
+                current_val = current_ev + IW_EV_LCP_LEN + strlen(buf);
+                break;
+            default:
+                break;
+            }
+            pbeacon += element_len + sizeof(IEEEtypes_Header_t);
+            beacon_size -= element_len + sizeof(IEEEtypes_Header_t);
+        }
+
+#if WIRELESS_EXT > 14
+        memset(&iwe, 0, sizeof(iwe));
+        memset(buf, 0, buf_size);
+        ptr = buf;
+        ptr += sprintf(ptr, "band=");
+        memset(&iwe, 0, sizeof(iwe));
+        if (scan_table[i].bss_band == BAND_A)
+            ptr += sprintf(ptr, "a");
+        else
+            ptr += sprintf(ptr, "bg");
+        iwe.u.data.length = strlen(buf);
+        PRINTM(MINFO, "iwe.u.data.length %d\n", iwe.u.data.length);
+        PRINTM(MINFO, "BUF: %s \n", buf);
+        iwe.cmd = IWEVCUSTOM;
+        iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
+        current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, buf);
+        current_val = current_ev + IW_EV_LCP_LEN + strlen(buf);
+#endif
+        current_val = current_ev + IW_EV_LCP_LEN;
+
+        /* 
+         * Check if we added any event
+         */
+        if ((current_val - current_ev) > IW_EV_LCP_LEN)
+            current_ev = current_val;
+    }
+
+    dwrq->length = (current_ev - extra);
+    dwrq->flags = 0;
+#endif
+
+  done:
+    if (buf)
+        kfree(buf);
+    LEAVE();
+    return ret;
+}
+
+/**
+ * iwconfig settable callbacks
+ */
+static const iw_handler woal_handler[] = {
+    (iw_handler) woal_config_commit,    /* SIOCSIWCOMMIT */
+    (iw_handler) woal_get_name, /* SIOCGIWNAME */
+    (iw_handler) NULL,          /* SIOCSIWNWID */
+    (iw_handler) NULL,          /* SIOCGIWNWID */
+    (iw_handler) woal_set_freq, /* SIOCSIWFREQ */
+    (iw_handler) woal_get_freq, /* SIOCGIWFREQ */
+    (iw_handler) woal_set_bss_mode,     /* SIOCSIWMODE */
+    (iw_handler) woal_get_bss_mode,     /* SIOCGIWMODE */
+    (iw_handler) woal_set_sens, /* SIOCSIWSENS */
+    (iw_handler) woal_get_sens, /* SIOCGIWSENS */
+    (iw_handler) NULL,          /* SIOCSIWRANGE */
+    (iw_handler) woal_get_range,        /* SIOCGIWRANGE */
+    (iw_handler) NULL,          /* SIOCSIWPRIV */
+    (iw_handler) NULL,          /* SIOCGIWPRIV */
+    (iw_handler) NULL,          /* SIOCSIWSTATS */
+    (iw_handler) NULL,          /* SIOCGIWSTATS */
+#if WIRELESS_EXT > 15
+    iw_handler_set_spy,         /* SIOCSIWSPY */
+    iw_handler_get_spy,         /* SIOCGIWSPY */
+    iw_handler_set_thrspy,      /* SIOCSIWTHRSPY */
+    iw_handler_get_thrspy,      /* SIOCGIWTHRSPY */
+#else /* WIRELESS_EXT > 15 */
+#ifdef WIRELESS_SPY
+    (iw_handler) NULL,          /* SIOCSIWSPY */
+    (iw_handler) NULL,          /* SIOCGIWSPY */
+#else /* WIRELESS_SPY */
+    (iw_handler) NULL,          /* SIOCSIWSPY */
+    (iw_handler) NULL,          /* SIOCGIWSPY */
+#endif /* WIRELESS_SPY */
+    (iw_handler) NULL,          /* -- hole -- */
+    (iw_handler) NULL,          /* -- hole -- */
+#endif /* WIRELESS_EXT > 15 */
+    (iw_handler) woal_set_wap,  /* SIOCSIWAP */
+    (iw_handler) woal_get_wap,  /* SIOCGIWAP */
+#if WIRELESS_EXT >= 18
+    (iw_handler) woal_set_mlme, /* SIOCSIWMLME */
+#else
+    (iw_handler) NULL,          /* -- hole -- */
+#endif
+    /* (iw_handler) wlan_get_aplist, *//* SIOCGIWAPLIST */
+    NULL,                       /* SIOCGIWAPLIST */
+#if WIRELESS_EXT > 13
+    (iw_handler) woal_set_scan, /* SIOCSIWSCAN */
+    (iw_handler) woal_get_scan, /* SIOCGIWSCAN */
+#else /* WIRELESS_EXT > 13 */
+    (iw_handler) NULL,          /* SIOCSIWSCAN */
+    (iw_handler) NULL,          /* SIOCGIWSCAN */
+#endif /* WIRELESS_EXT > 13 */
+    (iw_handler) woal_set_essid,        /* SIOCSIWESSID */
+    (iw_handler) woal_get_essid,        /* SIOCGIWESSID */
+    (iw_handler) woal_set_nick, /* SIOCSIWNICKN */
+    (iw_handler) woal_get_nick, /* SIOCGIWNICKN */
+    (iw_handler) NULL,          /* -- hole -- */
+    (iw_handler) NULL,          /* -- hole -- */
+    (iw_handler) woal_set_rate, /* SIOCSIWRATE */
+    (iw_handler) woal_get_rate, /* SIOCGIWRATE */
+    (iw_handler) woal_set_rts,  /* SIOCSIWRTS */
+    (iw_handler) woal_get_rts,  /* SIOCGIWRTS */
+    (iw_handler) woal_set_frag, /* SIOCSIWFRAG */
+    (iw_handler) woal_get_frag, /* SIOCGIWFRAG */
+    (iw_handler) woal_set_txpow,        /* SIOCSIWTXPOW */
+    (iw_handler) woal_get_txpow,        /* SIOCGIWTXPOW */
+    (iw_handler) woal_set_retry,        /* SIOCSIWRETRY */
+    (iw_handler) woal_get_retry,        /* SIOCGIWRETRY */
+    (iw_handler) woal_set_encode,       /* SIOCSIWENCODE */
+    (iw_handler) woal_get_encode,       /* SIOCGIWENCODE */
+    (iw_handler) woal_set_power,        /* SIOCSIWPOWER */
+    (iw_handler) woal_get_power,        /* SIOCGIWPOWER */
+#if (WIRELESS_EXT >= 18)
+    (iw_handler) NULL,          /* -- hole -- */
+    (iw_handler) NULL,          /* -- hole -- */
+    (iw_handler) woal_set_gen_ie,       /* SIOCSIWGENIE */
+    (iw_handler) woal_get_gen_ie,       /* SIOCGIWGENIE */
+    (iw_handler) woal_set_auth, /* SIOCSIWAUTH */
+    (iw_handler) woal_get_auth, /* SIOCGIWAUTH */
+    (iw_handler) woal_set_encode_ext,   /* SIOCSIWENCODEEXT */
+    (iw_handler) woal_get_encode_ext,   /* SIOCGIWENCODEEXT */
+#endif /* WIRELESSS_EXT >= 18 */
+};
+
+/**
+ * iwpriv settable callbacks
+ */
+static const iw_handler woal_private_handler[] = {
+    NULL,                       /* SIOCIWFIRSTPRIV */
+};
+
+/********************************************************
+                Global Functions
+********************************************************/
+
+/** wlan_handler_def */
+struct iw_handler_def woal_handler_def = {
+  num_standard:sizeof(woal_handler) / sizeof(iw_handler),
+  num_private:sizeof(woal_private_handler) / sizeof(iw_handler),
+  num_private_args:sizeof(woal_private_args) / sizeof(struct iw_priv_args),
+  standard:(iw_handler *) woal_handler,
+  private:(iw_handler *) woal_private_handler,
+  private_args:(struct iw_priv_args *) woal_private_args,
+#if WIRELESS_EXT > 20
+  get_wireless_stats:woal_get_wireless_stats,
+#endif
+};
+
+/**
+ *  @brief Get wireless statistics
+ *
+ *  @param dev          A pointer to net_device structure
+ *
+ *  @return             A pointer to iw_statistics buf
+ */
+struct iw_statistics *
+woal_get_wireless_stats(struct net_device *dev)
+{
+    moal_private *priv = (moal_private *) netdev_priv(dev);
+    t_u16 wait_option = MOAL_NO_WAIT;
+
+    ENTER();
+
+    /* 
+     * Since schedule() is not allowed from an atomic context
+     * such as when dev_base_lock for netdevices is acquired
+     * for reading/writing in kernel before this call, HostCmd
+     * is issued in non-blocking way in such contexts and
+     * blocking in other cases.
+     */
+    if (write_can_lock(&dev_base_lock)
+        && (!in_atomic() || current->exit_state))
+        wait_option = MOAL_WSTATS_WAIT;
+
+    priv->w_stats.status = woal_get_mode(priv, wait_option);
+    priv->w_stats.discard.retries = priv->stats.tx_errors;
+
+    /* Send RSSI command to get beacon RSSI/NF, valid only if associated */
+    if (priv->media_connected == MTRUE) {
+        woal_get_signal_info(priv, wait_option, NULL);
+    }
+    if (!priv->w_stats.qual.noise && priv->media_connected == MTRUE)
+        priv->w_stats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
+
+    priv->w_stats.qual.qual = 0;
+    PRINTM(MINFO, "Signal Level = %#x\n", priv->w_stats.qual.level);
+    PRINTM(MINFO, "Noise = %#x\n", priv->w_stats.qual.noise);
+    priv->w_stats.discard.code = 0;
+    woal_get_stats_info(priv, wait_option, NULL);
+
+    LEAVE();
+    return &priv->w_stats;
+}
diff --git a/wlan_src/mlinux/moal_wext.h b/wlan_src/mlinux/moal_wext.h
new file mode 100755
index 0000000..b402e90
--- /dev/null
+++ b/wlan_src/mlinux/moal_wext.h
@@ -0,0 +1,105 @@
+/** @file moal_wext.h
+ *
+ * @brief This file contains definition for wireless extension IOCTL call.
+ *  
+ * Copyright (C) 2008-2009, Marvell International Ltd.  
+ *
+ * This software file (the "File") is distributed by Marvell International 
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
+ * (the "License").  You may use, redistribute and/or modify this File in 
+ * accordance with the terms and conditions of the License, a copy of which 
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
+ * this warranty disclaimer.
+ *
+ */
+
+/********************************************************
+Change log:
+    10/21/2008: initial version
+********************************************************/
+
+#ifndef _WOAL_WEXT_H_
+#define _WOAL_WEXT_H_
+
+/** Custom event : AdHoc link sensed */
+#define CUS_EVT_ADHOC_LINK_SENSED	"EVENT=ADHOC_LINK_SENSED"
+/** Custom event : AdHoc link lost */
+#define CUS_EVT_ADHOC_LINK_LOST		"EVENT=ADHOC_LINK_LOST"
+/** Custom event : MIC failure, unicast */
+#define CUS_EVT_MLME_MIC_ERR_UNI	"MLME-MICHAELMICFAILURE.indication unicast "
+/** Custom event : MIC failure, multicast */
+#define CUS_EVT_MLME_MIC_ERR_MUL	"MLME-MICHAELMICFAILURE.indication multicast "
+/** Custom event : Beacon RSSI low */
+#define CUS_EVT_BEACON_RSSI_LOW		"EVENT=BEACON_RSSI_LOW"
+/** Custom event : Beacon SNR low */
+#define CUS_EVT_BEACON_SNR_LOW		"EVENT=BEACON_SNR_LOW"
+/** Custom event : Beacon RSSI high */
+#define CUS_EVT_BEACON_RSSI_HIGH	"EVENT=BEACON_RSSI_HIGH"
+/** Custom event : Beacon SNR high */
+#define CUS_EVT_BEACON_SNR_HIGH		"EVENT=BEACON_SNR_HIGH"
+/** Custom event : Max fail */
+#define CUS_EVT_MAX_FAIL		"EVENT=MAX_FAIL"
+/** Custom event : Data RSSI low */
+#define CUS_EVT_DATA_RSSI_LOW		"EVENT=DATA_RSSI_LOW"
+/** Custom event : Data SNR low */
+#define CUS_EVT_DATA_SNR_LOW		"EVENT=DATA_SNR_LOW"
+/** Custom event : Data RSSI high */
+#define CUS_EVT_DATA_RSSI_HIGH		"EVENT=DATA_RSSI_HIGH"
+/** Custom event : Data SNR high */
+#define CUS_EVT_DATA_SNR_HIGH		"EVENT=DATA_SNR_HIGH"
+/** Custom event : Link Quality */
+#define CUS_EVT_LINK_QUALITY		"EVENT=LINK_QUALITY"
+/** Custom event : Port Release */
+#define CUS_EVT_PORT_RELEASE		"EVENT=PORT_RELEASE"
+/** Custom event : Pre-Beacon Lost */
+#define CUS_EVT_PRE_BEACON_LOST		"EVENT=PRE_BEACON_LOST"
+
+/** Custom event : Deep Sleep awake */
+#define CUS_EVT_DEEP_SLEEP_AWAKE	"EVENT=DS_AWAKE"
+
+/** Custom event : Host Sleep activated */
+#define CUS_EVT_HS_ACTIVATED		"HS_ACTIVATED "
+/** Custom event : Host Sleep deactivated */
+#define CUS_EVT_HS_DEACTIVATED		"HS_DEACTIVATED "
+/** Custom event : Host Sleep wakeup */
+#define CUS_EVT_HS_WAKEUP		"HS_WAKEUP"
+
+/** Custom indiciation message sent to the application layer for WMM changes */
+#define WMM_CONFIG_CHANGE_INDICATION  "WMM_CONFIG_CHANGE.indication"
+
+/** Custom event : WEP ICV error */
+#define CUS_EVT_WEP_ICV_ERR		"EVENT=WEP_ICV_ERR"
+
+/** Custom event : BW changed */
+#define CUS_EVT_BW_CHANGED		"EVENT=BW_CHANGED"
+/** Custom event : OBSS scan parameter */
+#define CUS_EVT_OBSS_SCAN_PARAM		"EVENT=OBSS_SCAN_PARAM"
+
+/** NF value for default scan */
+#define MRVDRV_NF_DEFAULT_SCAN_VALUE		(-96)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+/** Add event */
+#define IWE_STREAM_ADD_EVENT(i, c, e, w, l) iwe_stream_add_event((i), (c), (e), (w), (l))
+/** Add point */
+#define IWE_STREAM_ADD_POINT(i, c, e, w, p) iwe_stream_add_point((i), (c), (e), (w), (p))
+/** Add value */
+#define IWE_STREAM_ADD_VALUE(i, c, v, e, w, l)  iwe_stream_add_value((i), (c), (v), (e), (w), (l))
+#else
+/** Add event */
+#define IWE_STREAM_ADD_EVENT(i, c, e, w, l) iwe_stream_add_event((c), (e), (w), (l))
+/** Add point */
+#define IWE_STREAM_ADD_POINT(i, c, e, w, p) iwe_stream_add_point((c), (e), (w), (p))
+/** Add value */
+#define IWE_STREAM_ADD_VALUE(i, c, v, e, w, l)  iwe_stream_add_value((c), (v), (e), (w), (l))
+#endif
+
+extern struct iw_handler_def woal_handler_def;
+struct iw_statistics *woal_get_wireless_stats(struct net_device *dev);
+#endif /* _WOAL_WEXT_H_ */