Patchwork Staging: rt28x0: updates from vendor's V2.1.0.0 drivers

login
register
mail settings
Submitter Ricardo Salveti de Araujo
Date April 10, 2010, 4:50 a.m.
Message ID <1270875009-4774-1-git-send-email-ricardo.salveti@openbossa.org>
Download mbox | patch
Permalink /patch/49899/
State Rejected
Delegated to: Andy Whitcroft
Headers show

Comments

Ricardo Salveti de Araujo - April 10, 2010, 4:50 a.m.
This patch is a fix for the bug 496093 on launchpad, where the rt2860
based devices frequently fails to connect to mixed mode WPA/WPA2 secured
wireless networks.

At the current Lucid kernel, the connection with mixed mode APs are very
instable, disconnecting all the time, and besides breaking the driver
sometimes.

This patch basically updates the RT2860/RT2870/RT3070 drivers, with the
vendor's 2.1.0.0 release. At mainline we have many other patches, but
most are just cosmetic changes, to follow the kernel coding style.

The update got into 2.6.33, and it's still a staging driver.

The only thing that changed comparing to the original patch is that I had
to include the fix created by bug #441990.

Besides the patch being huge, it also updates the rt2870 as a side effect,
as most of the references inside rt2870 are pointing to rt2860. We could
backport just the rt2860 update, but than we would need to move the current
references from rt2860 at rt2870 inside the driver's directory. As this
patch is already incorporated at mainline, I think that the work to
maintain the current rt2870 codebase is not worthy.

Applying this patch will basically update a stage driver, so no important
side effect.

Tested this patch with rt2860 (ID 1814:0781, from EeePC 1000HE) and wasn't
able to reproduce the bug. It should worth a note that this doesn't seems
to fix the issue for 2870, as the comment #54 says.

From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Date: Tue, 22 Sep 2009 20:44:07 +0200
Subject: [PATCH] Staging: rt28x0: updates from vendor's V2.1.0.0 drivers

Port changes from:

* 2009_0420_RT2860_Linux_STA_V2.1.0.0
* 2009_0302_RT2870_Linux_STA_v2.1.0.0
* 2009_0525_RT3070_Linux_STA_v2.1.1.0

to in-kernel drivers.

From the RT2860 driver release note:

[2.1.0.0]
1. New generation schema for multiple OS porting
2. Fixed Ad-hoc ping failed in noisy environment. (Probe Response has too
    many retry packet then cause "not enough space in MgmtRing")
3. Fixed WPA(2)PSK issue when group cipher of AP is WEP40 or WEP104.
4. Modified iwpriv ra0 get_site_survey:
	In scan list result: Security shows "NONE" when AP is OPEN/NONE,
	shows "WEP" when AP is OPEN/WEP or SHARED/WEP, shows
	"WPAPSK(WPA2PSK)/TKIP(AES)" when AP is WPAPSK(WPA2PSK)/TKIP(AES)
	shows "WPA(WPA2)/TKIP(AES)" when AP is WPA(WPA2)/TKIP(AES)
5. Support kthread.
6. Add New A band channel list region 15 contains the whole channels in
   the A band region 4 and the new CE channel 167,169,171,173
7. Add New IEEE802.11r functionality.
8. Fixed WPA2-Enterprise failed when AP reboot or turn off then turn on.
9. Fixed STA cannot connect to 11B only AP when the setting of is PHY_11GN.

From the RT2870 driver release note:

[V2.1.0.0]
1. New generation schema for multiple OS porting.
2. Fixed Ad-hoc ping failed in noisy environment. (Probe Response has too
   many retry packet then cause "not enough space in MgmtRing").
3. Fixed WPS failed with D-Link DIR-628 in 5GHz.
4. Change FastRoaming in DAT file to AutoRoaming.
5. Support kthread.
6. Add New A band channel list region 15 contains the whole channels in
   the A band region and the new CE channel 167,169,171,173.
7. New IEEE802.11r functionality.

From the RT3070 driver release note:

Version V2.1.1.0
       1. Linux kernel 2.6.29 support.
       2. Fix eFuse write from BIN file bug.

Version 2.1.0.0
       1. New generation schema for multiple OS porting
       2. Fixed Ad-hoc ping failed in noisy environment.
       3. Modified iwpriv ra0 get_site_survey:
       4. Change FastRoaming in DAT file to AutoRoaming.
       5. Support kthread.
       6. New IEEE802.11r functionality.

Tested with RT2860 and RT3070 chipsets.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@openbossa.org>
(cherry picked from commit ca97b8388838ee9ea4b4bad04948f8f7f8a607a3)

BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/496093

---
 drivers/staging/rt2860/2860_main_dev.c         | 1319 ------
 drivers/staging/rt2860/Makefile                |   26 +-
 drivers/staging/rt2860/aironet.h               |  210 -
 drivers/staging/rt2860/ap.h                    |   12 +-
 drivers/staging/rt2860/chip/mac_pci.h          |  365 ++
 drivers/staging/rt2860/chip/mac_usb.h          |  365 ++
 drivers/staging/rt2860/chip/rt2860.h           |   56 +
 drivers/staging/rt2860/chip/rt2870.h           |   47 +
 drivers/staging/rt2860/chip/rt3070.h           |   68 +
 drivers/staging/rt2860/chip/rt30xx.h           |   48 +
 drivers/staging/rt2860/chip/rtmp_mac.h         | 1334 ++++++
 drivers/staging/rt2860/chip/rtmp_phy.h         |  405 ++
 drivers/staging/rt2860/chips/rt3070.c          |  185 +
 drivers/staging/rt2860/chips/rt30xx.c          |  525 +++
 drivers/staging/rt2860/chlist.h                | 1223 +------
 drivers/staging/rt2860/common/2860_rtmp_init.c |  897 -----
 drivers/staging/rt2860/common/action.c         |   12 +-
 drivers/staging/rt2860/common/ba_action.c      |  147 +-
 drivers/staging/rt2860/common/cmm_aes.c        | 1404 +++++++
 drivers/staging/rt2860/common/cmm_asic.c       | 2531 ++++++++++++
 drivers/staging/rt2860/common/cmm_cfg.c        |  290 ++
 drivers/staging/rt2860/common/cmm_data.c       |  906 +----
 drivers/staging/rt2860/common/cmm_data_pci.c   | 1153 ++++++
 drivers/staging/rt2860/common/cmm_data_usb.c   |  968 +++++
 drivers/staging/rt2860/common/cmm_info.c       |  820 +++--
 drivers/staging/rt2860/common/cmm_mac_pci.c    | 1504 +++++++
 drivers/staging/rt2860/common/cmm_mac_usb.c    | 1216 ++++++
 drivers/staging/rt2860/common/cmm_profile.c    | 1736 ++++++++
 drivers/staging/rt2860/common/cmm_sanity.c     |  233 +-
 drivers/staging/rt2860/common/cmm_sync.c       |   70 +-
 drivers/staging/rt2860/common/cmm_tkip.c       |  882 ++++
 drivers/staging/rt2860/common/cmm_wep.c        |  499 +++
 drivers/staging/rt2860/common/cmm_wpa.c        | 2428 +++++++++++-
 drivers/staging/rt2860/common/crypt_hmac.c     |  194 +
 drivers/staging/rt2860/common/crypt_md5.c      |  352 ++
 drivers/staging/rt2860/common/crypt_sha2.c     |  535 +++
 drivers/staging/rt2860/common/dfs.c            |   66 +-
 drivers/staging/rt2860/common/ee_efuse.c       | 1525 +++++++
 drivers/staging/rt2860/common/ee_prom.c        |  270 ++
 drivers/staging/rt2860/common/eeprom.c         | 1460 +-------
 drivers/staging/rt2860/common/firmware.h       |    2 +-
 drivers/staging/rt2860/common/firmware_3070.h  |  517 +++
 drivers/staging/rt2860/common/md5.c            | 1415 -------
 drivers/staging/rt2860/common/mlme.c           | 5122 ++++++------------------
 drivers/staging/rt2860/common/rt_channel.c     | 1280 ++++++
 drivers/staging/rt2860/common/rt_rf.c          |  194 +
 drivers/staging/rt2860/common/rtmp_init.c      | 1963 ++++------
 drivers/staging/rt2860/common/rtmp_mcu.c       |  233 ++
 drivers/staging/rt2860/common/rtmp_timer.c     |  323 ++
 drivers/staging/rt2860/common/rtmp_tkip.c      | 1586 --------
 drivers/staging/rt2860/common/rtmp_wep.c       |  497 ---
 drivers/staging/rt2860/common/spectrum.c       |  460 ++-
 drivers/staging/rt2860/config.mk               |  241 --
 drivers/staging/rt2860/crypt_hmac.h            |   82 +
 drivers/staging/rt2860/crypt_md5.h             |   80 +
 drivers/staging/rt2860/crypt_sha2.h            |  109 +
 drivers/staging/rt2860/dfs.h                   |   32 +-
 drivers/staging/rt2860/eeprom.h                |   93 +
 drivers/staging/rt2860/iface/rtmp_pci.h        |   83 +
 drivers/staging/rt2860/iface/rtmp_usb.h        |  200 +
 drivers/staging/rt2860/md5.h                   |  107 -
 drivers/staging/rt2860/mlme.h                  |   89 +-
 drivers/staging/rt2860/oid.h                   |  135 +-
 drivers/staging/rt2860/pci_main_dev.c          |  873 ++++
 drivers/staging/rt2860/rt2860.h                |  333 --
 drivers/staging/rt2860/rt28xx.h                | 1688 --------
 drivers/staging/rt2860/rt_config.h             |   32 +-
 drivers/staging/rt2860/rt_linux.c              |  615 +++-
 drivers/staging/rt2860/rt_linux.h              |  972 +++---
 drivers/staging/rt2860/rt_main_dev.c           |  750 ++---
 drivers/staging/rt2860/rt_pci_rbus.c           |  877 ++++
 drivers/staging/rt2860/rt_profile.c            | 1839 +---------
 drivers/staging/rt2860/rt_usb.c                |  828 ++++
 drivers/staging/rt2860/rtmp.h                  | 2876 ++++++--------
 drivers/staging/rt2860/rtmp_chip.h             |  265 ++
 drivers/staging/rt2860/rtmp_def.h              |  289 +-
 drivers/staging/rt2860/rtmp_dot11.h            |  102 +
 drivers/staging/rt2860/rtmp_iface.h            |   84 +
 drivers/staging/rt2860/rtmp_mcu.h              |   55 +
 drivers/staging/rt2860/rtmp_os.h               |   98 +
 drivers/staging/rt2860/rtmp_timer.h            |  156 +
 drivers/staging/rt2860/rtmp_type.h             |   55 +-
 drivers/staging/rt2860/rtusb_io.h              |  189 +
 drivers/staging/rt2860/spectrum.h              |  169 +-
 drivers/staging/rt2860/spectrum_def.h          |  148 +-
 drivers/staging/rt2860/sta/aironet.c           | 1312 ------
 drivers/staging/rt2860/sta/assoc.c             |  327 +--
 drivers/staging/rt2860/sta/auth.c              |  138 +-
 drivers/staging/rt2860/sta/auth_rsp.c          |   16 +-
 drivers/staging/rt2860/sta/connect.c           |  637 ++--
 drivers/staging/rt2860/sta/rtmp_data.c         |  257 +-
 drivers/staging/rt2860/sta/sanity.c            |   44 +-
 drivers/staging/rt2860/sta/sync.c              |  398 +--
 drivers/staging/rt2860/sta/wpa.c               | 1992 +---------
 drivers/staging/rt2860/sta_ioctl.c             |  761 +++--
 drivers/staging/rt2860/usb_main_dev.c          |  898 +++++
 drivers/staging/rt2860/wpa.h                   |  104 +-
 drivers/staging/rt2870/2870_main_dev.c         | 1531 -------
 drivers/staging/rt2870/Makefile                |   32 +-
 drivers/staging/rt2870/chips/rt3070.c          |    1 +
 drivers/staging/rt2870/chips/rt30xx.c          |    1 +
 drivers/staging/rt2870/common/2870_rtmp_init.c | 1730 --------
 drivers/staging/rt2870/common/acction.c        |    1 +
 drivers/staging/rt2870/common/cmm_aes.c        |    1 +
 drivers/staging/rt2870/common/cmm_asic.c       |    1 +
 drivers/staging/rt2870/common/cmm_cfg.c        |    1 +
 drivers/staging/rt2870/common/cmm_data_2870.c  |  936 -----
 drivers/staging/rt2870/common/cmm_data_usb.c   |    1 +
 drivers/staging/rt2870/common/cmm_mac_usb.c    |    1 +
 drivers/staging/rt2870/common/cmm_profile.c    |    1 +
 drivers/staging/rt2870/common/cmm_tkip.c       |    1 +
 drivers/staging/rt2870/common/cmm_wep.c        |    1 +
 drivers/staging/rt2870/common/crypt_hmac.c     |    1 +
 drivers/staging/rt2870/common/crypt_md5.c      |    1 +
 drivers/staging/rt2870/common/crypt_sha2.c     |    1 +
 drivers/staging/rt2870/common/ee_efuse.c       |    1 +
 drivers/staging/rt2870/common/rt_channel.c     |    1 +
 drivers/staging/rt2870/common/rt_rf.c          |    1 +
 drivers/staging/rt2870/common/rtmp_mcu.c       |    1 +
 drivers/staging/rt2870/common/rtmp_timer.c     |    1 +
 drivers/staging/rt2870/common/rtusb_bulk.c     |   37 +-
 drivers/staging/rt2870/common/rtusb_data.c     |   55 +
 drivers/staging/rt2870/common/rtusb_io.c       |  465 +--
 drivers/staging/rt2870/rt2870.h                |  583 ---
 drivers/staging/rt2870/rt_usb.c                |    1 +
 drivers/staging/rt2870/usb_main_dev.c          |    1 +
 drivers/staging/rt3070/firmware.h              |    2 +-
 127 files changed, 36854 insertions(+), 31844 deletions(-)
 delete mode 100644 drivers/staging/rt2860/2860_main_dev.c
 delete mode 100644 drivers/staging/rt2860/aironet.h
 create mode 100644 drivers/staging/rt2860/chip/mac_pci.h
 create mode 100644 drivers/staging/rt2860/chip/mac_usb.h
 create mode 100644 drivers/staging/rt2860/chip/rt2860.h
 create mode 100644 drivers/staging/rt2860/chip/rt2870.h
 create mode 100644 drivers/staging/rt2860/chip/rt3070.h
 create mode 100644 drivers/staging/rt2860/chip/rt30xx.h
 create mode 100644 drivers/staging/rt2860/chip/rtmp_mac.h
 create mode 100644 drivers/staging/rt2860/chip/rtmp_phy.h
 create mode 100644 drivers/staging/rt2860/chips/rt3070.c
 create mode 100644 drivers/staging/rt2860/chips/rt30xx.c
 delete mode 100644 drivers/staging/rt2860/common/2860_rtmp_init.c
 create mode 100644 drivers/staging/rt2860/common/cmm_aes.c
 create mode 100644 drivers/staging/rt2860/common/cmm_asic.c
 create mode 100644 drivers/staging/rt2860/common/cmm_cfg.c
 create mode 100644 drivers/staging/rt2860/common/cmm_data_pci.c
 create mode 100644 drivers/staging/rt2860/common/cmm_data_usb.c
 create mode 100644 drivers/staging/rt2860/common/cmm_mac_pci.c
 create mode 100644 drivers/staging/rt2860/common/cmm_mac_usb.c
 create mode 100644 drivers/staging/rt2860/common/cmm_profile.c
 create mode 100644 drivers/staging/rt2860/common/cmm_tkip.c
 create mode 100644 drivers/staging/rt2860/common/cmm_wep.c
 create mode 100644 drivers/staging/rt2860/common/crypt_hmac.c
 create mode 100644 drivers/staging/rt2860/common/crypt_md5.c
 create mode 100644 drivers/staging/rt2860/common/crypt_sha2.c
 create mode 100644 drivers/staging/rt2860/common/ee_efuse.c
 create mode 100644 drivers/staging/rt2860/common/ee_prom.c
 create mode 100644 drivers/staging/rt2860/common/firmware_3070.h
 delete mode 100644 drivers/staging/rt2860/common/md5.c
 create mode 100644 drivers/staging/rt2860/common/rt_channel.c
 create mode 100644 drivers/staging/rt2860/common/rt_rf.c
 create mode 100644 drivers/staging/rt2860/common/rtmp_mcu.c
 create mode 100644 drivers/staging/rt2860/common/rtmp_timer.c
 delete mode 100644 drivers/staging/rt2860/common/rtmp_tkip.c
 delete mode 100644 drivers/staging/rt2860/common/rtmp_wep.c
 delete mode 100644 drivers/staging/rt2860/config.mk
 create mode 100644 drivers/staging/rt2860/crypt_hmac.h
 create mode 100644 drivers/staging/rt2860/crypt_md5.h
 create mode 100644 drivers/staging/rt2860/crypt_sha2.h
 create mode 100644 drivers/staging/rt2860/eeprom.h
 create mode 100644 drivers/staging/rt2860/iface/rtmp_pci.h
 create mode 100644 drivers/staging/rt2860/iface/rtmp_usb.h
 delete mode 100644 drivers/staging/rt2860/md5.h
 create mode 100644 drivers/staging/rt2860/pci_main_dev.c
 delete mode 100644 drivers/staging/rt2860/rt2860.h
 delete mode 100644 drivers/staging/rt2860/rt28xx.h
 create mode 100644 drivers/staging/rt2860/rt_pci_rbus.c
 create mode 100644 drivers/staging/rt2860/rt_usb.c
 create mode 100644 drivers/staging/rt2860/rtmp_chip.h
 create mode 100644 drivers/staging/rt2860/rtmp_dot11.h
 create mode 100644 drivers/staging/rt2860/rtmp_iface.h
 create mode 100644 drivers/staging/rt2860/rtmp_mcu.h
 create mode 100644 drivers/staging/rt2860/rtmp_os.h
 create mode 100644 drivers/staging/rt2860/rtmp_timer.h
 create mode 100644 drivers/staging/rt2860/rtusb_io.h
 delete mode 100644 drivers/staging/rt2860/sta/aironet.c
 create mode 100644 drivers/staging/rt2860/usb_main_dev.c
 delete mode 100644 drivers/staging/rt2870/2870_main_dev.c
 create mode 100644 drivers/staging/rt2870/chips/rt3070.c
 create mode 100644 drivers/staging/rt2870/chips/rt30xx.c
 delete mode 100644 drivers/staging/rt2870/common/2870_rtmp_init.c
 create mode 100644 drivers/staging/rt2870/common/acction.c
 create mode 100644 drivers/staging/rt2870/common/cmm_aes.c
 create mode 100644 drivers/staging/rt2870/common/cmm_asic.c
 create mode 100644 drivers/staging/rt2870/common/cmm_cfg.c
 delete mode 100644 drivers/staging/rt2870/common/cmm_data_2870.c
 create mode 100644 drivers/staging/rt2870/common/cmm_data_usb.c
 create mode 100644 drivers/staging/rt2870/common/cmm_mac_usb.c
 create mode 100644 drivers/staging/rt2870/common/cmm_profile.c
 create mode 100644 drivers/staging/rt2870/common/cmm_tkip.c
 create mode 100644 drivers/staging/rt2870/common/cmm_wep.c
 create mode 100644 drivers/staging/rt2870/common/crypt_hmac.c
 create mode 100644 drivers/staging/rt2870/common/crypt_md5.c
 create mode 100644 drivers/staging/rt2870/common/crypt_sha2.c
 create mode 100644 drivers/staging/rt2870/common/ee_efuse.c
 create mode 100644 drivers/staging/rt2870/common/rt_channel.c
 create mode 100644 drivers/staging/rt2870/common/rt_rf.c
 create mode 100644 drivers/staging/rt2870/common/rtmp_mcu.c
 create mode 100644 drivers/staging/rt2870/common/rtmp_timer.c
 delete mode 100644 drivers/staging/rt2870/rt2870.h
 create mode 100644 drivers/staging/rt2870/rt_usb.c
 create mode 100644 drivers/staging/rt2870/usb_main_dev.c

Patch

diff --git a/drivers/staging/rt2860/2860_main_dev.c b/drivers/staging/rt2860/2860_main_dev.c
deleted file mode 100644
index c2f0296..0000000
--- a/drivers/staging/rt2860/2860_main_dev.c
+++ /dev/null
@@ -1,1319 +0,0 @@ 
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    2870_main_dev.c
-
-    Abstract:
-    Create and register network interface.
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-*/
-
-#include "rt_config.h"
-
-extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
-									IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
-
-static void rx_done_tasklet(unsigned long data);
-static void mgmt_dma_done_tasklet(unsigned long data);
-static void ac0_dma_done_tasklet(unsigned long data);
-static void ac1_dma_done_tasklet(unsigned long data);
-static void ac2_dma_done_tasklet(unsigned long data);
-static void ac3_dma_done_tasklet(unsigned long data);
-static void hcca_dma_done_tasklet(unsigned long data);
-static void fifo_statistic_full_tasklet(unsigned long data);
-
-
-/*---------------------------------------------------------------------*/
-/* Symbol & Macro Definitions                                          */
-/*---------------------------------------------------------------------*/
-#define RT2860_INT_RX_DLY				(1<<0)		// bit 0
-#define RT2860_INT_TX_DLY				(1<<1)		// bit 1
-#define RT2860_INT_RX_DONE				(1<<2)		// bit 2
-#define RT2860_INT_AC0_DMA_DONE			(1<<3)		// bit 3
-#define RT2860_INT_AC1_DMA_DONE			(1<<4)		// bit 4
-#define RT2860_INT_AC2_DMA_DONE			(1<<5)		// bit 5
-#define RT2860_INT_AC3_DMA_DONE			(1<<6)		// bit 6
-#define RT2860_INT_HCCA_DMA_DONE		(1<<7)		// bit 7
-#define RT2860_INT_MGMT_DONE			(1<<8)		// bit 8
-
-#define INT_RX			RT2860_INT_RX_DONE
-
-#define INT_AC0_DLY		(RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_AC1_DLY		(RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_AC2_DLY		(RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_AC3_DLY		(RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_HCCA_DLY 	(RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY)
-#define INT_MGMT_DLY	RT2860_INT_MGMT_DONE
-
-/*---------------------------------------------------------------------*/
-/* Prototypes of Functions Used                                        */
-/*---------------------------------------------------------------------*/
-/* function declarations */
-static INT __devinit rt2860_init_one (struct pci_dev *pci_dev, const struct pci_device_id  *ent);
-static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev);
-static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id  *ent);
-void init_thread_task(PRTMP_ADAPTER pAd);
-static void __exit rt2860_cleanup_module(void);
-static int __init rt2860_init_module(void);
-
-#ifdef CONFIG_PM
-static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
-static int rt2860_resume(struct pci_dev *pci_dev);
-#endif // CONFIG_PM //
-
-
-//
-// Ralink PCI device table, include all supported chipsets
-//
-static struct pci_device_id rt2860_pci_tbl[] __devinitdata =
-{
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)},		//RT28602.4G
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7708)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7728)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7758)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7727)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)},
-    {0,}		// terminate list
-};
-
-MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
-MODULE_LICENSE("GPL");
-#ifdef MODULE_VERSION
-MODULE_VERSION(STA_DRIVER_VERSION);
-#endif
-
-//
-// Our PCI driver structure
-//
-static struct pci_driver rt2860_driver =
-{
-    name:       "rt2860",
-    id_table:   rt2860_pci_tbl,
-    probe:      rt2860_init_one,
-    remove:     __devexit_p(rt2860_remove_one),
-
-#ifdef CONFIG_PM
-	suspend:	rt2860_suspend,
-	resume:		rt2860_resume,
-#endif
-};
-
-
-#ifdef CONFIG_PM
-
-VOID RT2860RejectPendingPackets(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	// clear PS packets
-	// clear TxSw packets
-}
-
-static int rt2860_suspend(
-	struct pci_dev *pci_dev,
-	pm_message_t state)
-{
-	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
-	INT32 retval;
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
-
-	if (net_dev == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	}
-	else
-	{
-		pAd = net_dev->ml_priv;
-
-		/* we can not use IFF_UP because ra0 down but ra1 up */
-		/* and 1 suspend/resume function for 1 module, not for each interface */
-		/* so Linux will call suspend/resume function once */
-		if (VIRTUAL_IF_NUM(pAd) > 0)
-		{
-			// avoid users do suspend after interface is down
-
-			// stop interface
-			netif_carrier_off(net_dev);
-			netif_stop_queue(net_dev);
-
-			// mark device as removed from system and therefore no longer available
-			netif_device_detach(net_dev);
-
-			// mark halt flag
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-			// take down the device
-			rt28xx_close((PNET_DEV)net_dev);
-
-			RT_MOD_DEC_USE_COUNT();
-		}
-	}
-
-	// reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html
-	// enable device to generate PME# when suspended
-	// pci_choose_state(): Choose the power state of a PCI device to be suspended
-	retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1);
-	// save the PCI configuration space of a device before suspending
-	pci_save_state(pci_dev);
-	// disable PCI device after use
-	pci_disable_device(pci_dev);
-
-	retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n"));
-	return retval;
-}
-
-static int rt2860_resume(
-	struct pci_dev *pci_dev)
-{
-	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
-	INT32 retval;
-
-
-	// set the power state of a PCI device
-	// PCI has 4 power states, DO (normal) ~ D3(less power)
-	// in include/linux/pci.h, you can find that
-	// #define PCI_D0          ((pci_power_t __force) 0)
-	// #define PCI_D1          ((pci_power_t __force) 1)
-	// #define PCI_D2          ((pci_power_t __force) 2)
-	// #define PCI_D3hot       ((pci_power_t __force) 3)
-	// #define PCI_D3cold      ((pci_power_t __force) 4)
-	// #define PCI_UNKNOWN     ((pci_power_t __force) 5)
-	// #define PCI_POWER_ERROR ((pci_power_t __force) -1)
-	retval = pci_set_power_state(pci_dev, PCI_D0);
-
-	// restore the saved state of a PCI device
-	pci_restore_state(pci_dev);
-
-	// initialize device before it's used by a driver
-	if (pci_enable_device(pci_dev))
-	{
-		printk("pci enable fail!\n");
-		return 0;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n"));
-
-	if (net_dev == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	}
-	else
-		pAd = net_dev->ml_priv;
-
-	if (pAd != NULL)
-	{
-		/* we can not use IFF_UP because ra0 down but ra1 up */
-		/* and 1 suspend/resume function for 1 module, not for each interface */
-		/* so Linux will call suspend/resume function once */
-		if (VIRTUAL_IF_NUM(pAd) > 0)
-		{
-			// mark device as attached from system and restart if needed
-			netif_device_attach(net_dev);
-
-			if (rt28xx_open((PNET_DEV)net_dev) != 0)
-			{
-				// open fail
-				DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
-				return 0;
-			}
-
-			// increase MODULE use count
-			RT_MOD_INC_USE_COUNT();
-
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-			netif_start_queue(net_dev);
-			netif_carrier_on(net_dev);
-			netif_wake_queue(net_dev);
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
-	return 0;
-}
-#endif // CONFIG_PM //
-
-
-static INT __init rt2860_init_module(VOID)
-{
-	return pci_register_driver(&rt2860_driver);
-}
-
-
-//
-// Driver module unload function
-//
-static VOID __exit rt2860_cleanup_module(VOID)
-{
-    pci_unregister_driver(&rt2860_driver);
-}
-
-module_init(rt2860_init_module);
-module_exit(rt2860_cleanup_module);
-
-
-static INT __devinit rt2860_init_one (
-    IN  struct pci_dev              *pci_dev,
-    IN  const struct pci_device_id  *ent)
-{
-    INT rc;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_init_one\n"));
-
-    // wake up and enable device
-    if (pci_enable_device (pci_dev))
-    {
-        rc = -EIO;
-    }
-    else
-    {
-        rc = rt2860_probe(pci_dev, ent);
-    }
-
-    DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_init_one\n"));
-    return rc;
-}
-
-
-static VOID __devexit rt2860_remove_one(
-    IN  struct pci_dev  *pci_dev)
-{
-    struct net_device   *net_dev = pci_get_drvdata(pci_dev);
-    RTMP_ADAPTER        *pAd = net_dev->ml_priv;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
-
-	if (pAd != NULL)
-	{
-		// Unregister network device
-		unregister_netdev(net_dev);
-
-		// Unmap CSR base address
-		iounmap((char *)(net_dev->base_addr));
-
-		RTMPFreeAdapter(pAd);
-
-		// release memory region
-		release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-	}
-	else
-	{
-		// Unregister network device
-		unregister_netdev(net_dev);
-
-		// Unmap CSR base address
-		iounmap((char *)(net_dev->base_addr));
-
-		// release memory region
-		release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-	}
-
-	// Free pre-allocated net_device memory
-	free_netdev(net_dev);
-}
-
-//
-// PCI device probe & initialization function
-//
-static INT __devinit   rt2860_probe(
-    IN  struct pci_dev              *pci_dev,
-    IN  const struct pci_device_id  *ent)
-{
-	PRTMP_ADAPTER pAd;
-    INT rv = 0;
-
-    rv = (INT)rt28xx_probe((void *)pci_dev, (void *)ent, 0, &pAd);
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE);
-	return rv;
-}
-
-
-void init_thread_task(IN PRTMP_ADAPTER pAd)
-{
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->hcca_dma_done_task, hcca_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd);
-}
-
-void kill_thread_task(IN PRTMP_ADAPTER pAd)
-{
-	POS_COOKIE pObj;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	tasklet_kill(&pObj->rx_done_task);
-	tasklet_kill(&pObj->mgmt_dma_done_task);
-	tasklet_kill(&pObj->ac0_dma_done_task);
-	tasklet_kill(&pObj->ac1_dma_done_task);
-	tasklet_kill(&pObj->ac2_dma_done_task);
-	tasklet_kill(&pObj->ac3_dma_done_task);
-	tasklet_kill(&pObj->hcca_dma_done_task);
-	tasklet_kill(&pObj->tbtt_task);
-	tasklet_kill(&pObj->fifo_statistic_full_task);
-}
-
-
-static void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode)
-{
-	u32 regValue;
-
-	pAd->int_disable_mask &= ~(mode);
-	regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
-	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);     // 1:enable
-
-	if (regValue != 0)
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-}
-
-
-static void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode)
-{
-	u32 regValue;
-
-	pAd->int_disable_mask |= mode;
-	regValue = 	pAd->int_enable_reg & ~(pAd->int_disable_mask);
-	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);     // 0: disable
-
-	if (regValue == 0)
-	{
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-	}
-}
-
-static void mgmt_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.MgmtDmaDone = 1;
-	pAd->int_pending &= ~INT_MGMT_DLY;
-
-	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
-
-	// if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any
-	// bug report output
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if (pAd->int_pending & INT_MGMT_DLY)
-	{
-		tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_MGMT_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void rx_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-	BOOLEAN	bReschedule = 0;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	pAd->int_pending &= ~(INT_RX);
-
-	bReschedule = STARxDoneInterruptHandle(pAd, 0);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid rotting packet
-	 */
-	if (pAd->int_pending & INT_RX || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->rx_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable RxINT again */
-	rt2860_int_enable(pAd, INT_RX);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-
-}
-
-void fifo_statistic_full_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	pAd->int_pending &= ~(FifoStaFullInt);
-	NICUpdateFifoStaCounters(pAd);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid rotting packet
-	 */
-	if (pAd->int_pending & FifoStaFullInt)
-	{
-		tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable RxINT again */
-
-	rt2860_int_enable(pAd, FifoStaFullInt);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-
-}
-
-static void hcca_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-
-	IntSource.word = 0;
-	IntSource.field.HccaDmaDone = 1;
-	pAd->int_pending &= ~INT_HCCA_DLY;
-
-	RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if (pAd->int_pending & INT_HCCA_DLY)
-	{
-		tasklet_hi_schedule(&pObj->hcca_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_HCCA_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac3_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac3DmaDone = 1;
-	pAd->int_pending &= ~INT_AC3_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC3_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC3_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac2_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac2DmaDone = 1;
-	pAd->int_pending &= ~INT_AC2_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC2_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC2_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac1_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac1DmaDone = 1;
-	pAd->int_pending &= ~INT_AC1_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC1_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC1_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac0_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
-    INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN bReschedule = 0;
-
-	// Do nothing if the driver is starting halt state.
-	// This might happen when timer already been fired before cancel timer with mlmehalt
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-    pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac0DmaDone = 1;
-	pAd->int_pending &= ~INT_AC0_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC0_DLY) || bReschedule)
-	{
-		tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC0_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-
-int print_int_count;
-
-IRQ_HANDLE_TYPE
-rt2860_interrupt(int irq, void *dev_instance)
-{
-	struct net_device *net_dev = (struct net_device *) dev_instance;
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
-	INT_SOURCE_CSR_STRUC	IntSource;
-	POS_COOKIE pObj;
-	BOOLEAN	bOldValue;
-
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-
-	/* Note 03312008: we can not return here before
-		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
-		Or kernel will panic after ifconfig ra0 down sometimes */
-
-
-	//
-	// Inital the Interrupt source.
-	//
-	IntSource.word = 0x00000000L;
-//	McuIntSource.word = 0x00000000L;
-
-	//
-	// Get the interrupt sources & saved to local variable
-	//
-	//RTMP_IO_READ32(pAd, where, &McuIntSource.word);
-	//RTMP_IO_WRITE32(pAd, , McuIntSource.word);
-
-	//
-	// Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp
-	// And at the same time, clock maybe turned off that say there is no DMA service.
-	// when ASIC get to sleep.
-	// To prevent system hang on power saving.
-	// We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up.
-	//
-	// RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
-	// RT2860 => when ASIC is sleeping, MAC register can be read and written.
-
-	bOldValue = pAd->bPCIclkOff;
-	pAd->bPCIclkOff = FALSE;
-	{
-		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
-	}
-	pAd->bPCIclkOff = bOldValue;
-
-	// Do nothing if Reset in progress
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-	{
-		return IRQ_HANDLED;
-	}
-
-	//
-	// Handle interrupt, walk through all bits
-	// Should start from highest priority interrupt
-	// The priority can be adjust by altering processing if statement
-	//
-
-	// If required spinlock, each interrupt service routine has to acquire
-	// and release itself.
-	//
-
-	// Do nothing if NIC doesn't exist
-	if (IntSource.word == 0xffffffff)
-	{
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
-		printk("snowpin - IntSource.word == 0xffffffff\n");
-		return IRQ_HANDLED;
-	}
-
-	if (IntSource.word & TxCoherent)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
-		RTMPHandleRxCoherentInterrupt(pAd);
-	}
-
-	if (IntSource.word & RxCoherent)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
-		RTMPHandleRxCoherentInterrupt(pAd);
-	}
-
-	if (IntSource.word & FifoStaFullInt)
-	{
-#if 1
-		if ((pAd->int_disable_mask & FifoStaFullInt) == 0)
-		{
-			/* mask FifoStaFullInt */
-			rt2860_int_disable(pAd, FifoStaFullInt);
-			tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
-		}
-		pAd->int_pending |= FifoStaFullInt;
-#else
-		NICUpdateFifoStaCounters(pAd);
-#endif
-	}
-
-	if (IntSource.word & INT_MGMT_DLY)
-	{
-		if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 )
-		{
-			rt2860_int_disable(pAd, INT_MGMT_DLY);
-			tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
-		}
-		pAd->int_pending |= INT_MGMT_DLY ;
-	}
-
-	if (IntSource.word & INT_RX)
-	{
-		if ((pAd->int_disable_mask & INT_RX) == 0)
-		{
-			/* mask RxINT */
-			rt2860_int_disable(pAd, INT_RX);
-			tasklet_hi_schedule(&pObj->rx_done_task);
-		}
-		pAd->int_pending |= INT_RX;
-	}
-
-	if (IntSource.word & INT_HCCA_DLY)
-	{
-
-		if ((pAd->int_disable_mask & INT_HCCA_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_HCCA_DLY);
-			tasklet_hi_schedule(&pObj->hcca_dma_done_task);
-		}
-		pAd->int_pending |= INT_HCCA_DLY;
-	}
-
-	if (IntSource.word & INT_AC3_DLY)
-	{
-
-		if ((pAd->int_disable_mask & INT_AC3_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC3_DLY);
-			tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-		}
-		pAd->int_pending |= INT_AC3_DLY;
-	}
-
-	if (IntSource.word & INT_AC2_DLY)
-	{
-
-		if ((pAd->int_disable_mask & INT_AC2_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC2_DLY);
-			tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-		}
-		pAd->int_pending |= INT_AC2_DLY;
-	}
-
-	if (IntSource.word & INT_AC1_DLY)
-	{
-
-		pAd->int_pending |= INT_AC1_DLY;
-
-		if ((pAd->int_disable_mask & INT_AC1_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC1_DLY);
-			tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-		}
-
-	}
-
-	if (IntSource.word & INT_AC0_DLY)
-	{
-		pAd->int_pending |= INT_AC0_DLY;
-
-		if ((pAd->int_disable_mask & INT_AC0_DLY) == 0)
-		{
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC0_DLY);
-			tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-		}
-
-	}
-
-    if (IntSource.word & PreTBTTInt)
-	{
-		RTMPHandlePreTBTTInterrupt(pAd);
-	}
-
-	if (IntSource.word & TBTTInt)
-	{
-		RTMPHandleTBTTInterrupt(pAd);
-	}
-
-	if (IntSource.word & AutoWakeupInt)
-		RTMPHandleTwakeupInterrupt(pAd);
-
-    return  IRQ_HANDLED;
-}
-
-/*
-========================================================================
-Routine Description:
-    Check the chipset vendor/product ID.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-
-Return Value:
-    TRUE				Check ok
-	FALSE				Check fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXChipsetCheck(
-	IN void *_dev_p)
-{
-	/* always TRUE */
-	return TRUE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Init net device structure.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-    *net_dev			Point to the net device
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    TRUE				Init ok
-	FALSE				Init fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXNetDevInit(
-	IN void 				*_dev_p,
-	IN struct  net_device	*net_dev,
-	IN RTMP_ADAPTER 		*pAd)
-{
-	struct pci_dev *pci_dev = (struct pci_dev *)_dev_p;
-    const CHAR	*print_name;
-    ULONG	csr_addr;
-
-
-	print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
-
-	net_dev->base_addr = 0;
-	net_dev->irq = 0;
-
-    if (pci_request_regions(pci_dev, print_name))
-        goto err_out_free_netdev;
-
-    // interrupt IRQ number
-    net_dev->irq = pci_dev->irq;
-
-    // map physical address to virtual address for accessing register
-    csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0),
-										pci_resource_len(pci_dev, 0));
-
-    if (!csr_addr)
-    {
-        DBGPRINT(RT_DEBUG_ERROR,
-				("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",
-				print_name, (ULONG)pci_resource_len(pci_dev, 0),
-				(ULONG)pci_resource_start(pci_dev, 0)));
-        goto err_out_free_res;
-    }
-
-    // Save CSR virtual address and irq to device structure
-    net_dev->base_addr = csr_addr;
-    pAd->CSRBaseAddress = (PUCHAR)net_dev->base_addr;
-
-    // Set DMA master
-    pci_set_master(pci_dev);
-
-    net_dev->priv_flags = INT_MAIN;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n",
-        	net_dev->name, (ULONG)pci_resource_start(pci_dev, 0),
-			(ULONG)csr_addr, pci_dev->irq));
-	return TRUE;
-
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-err_out_free_res:
-    pci_release_regions(pci_dev);
-err_out_free_netdev:
-	/* free netdev in caller, not here */
-	return FALSE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Init net device structure.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    TRUE				Config ok
-	FALSE				Config fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXProbePostConfig(
-	IN void 				*_dev_p,
-	IN RTMP_ADAPTER 		*pAd,
-	IN INT32				argc)
-{
-	/* no use */
-	return TRUE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Disable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28XXDMADisable(
-	IN RTMP_ADAPTER 		*pAd)
-{
-	WPDMA_GLO_CFG_STRUC     GloCfg;
-
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE =1;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Enable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28XXDMAEnable(
-	IN RTMP_ADAPTER 		*pAd)
-{
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-	int i = 0;
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
-		RTMPusecDelay(1000);
-		i++;
-	}while ( i <200);
-
-	RTMPusecDelay(50);
-
-	GloCfg.field.EnTXWriteBackDDONE = 1;
-	GloCfg.field.WPDMABurstSIZE = 2;
-	GloCfg.field.EnableRxDMA = 1;
-	GloCfg.field.EnableTxDMA = 1;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-}
-
-/*
-========================================================================
-Routine Description:
-    Write Beacon buffer to Asic.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28xx_UpdateBeaconToAsic(
-	IN RTMP_ADAPTER		*pAd,
-	IN INT				apidx,
-	IN ULONG			FrameLen,
-	IN ULONG			UpdatePos)
-{
-	ULONG				CapInfoPos = 0;
-	UCHAR  			*ptr, *ptr_update, *ptr_capinfo;
-	UINT  			i;
-	BOOLEAN			bBcnReq = FALSE;
-	UCHAR			bcn_idx = 0;
-
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __func__));
-		return;
-	}
-
-	if (bBcnReq == FALSE)
-	{
-		/* when the ra interface is down, do not send its beacon frame */
-		/* clear all zero */
-		for(i=0; i<TXWI_SIZE; i+=4)
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
-	}
-	else
-	{
-		ptr = (PUCHAR)&pAd->BeaconTxWI;
-
-		for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
-		{
-			UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longptr);
-			ptr += 4;
-		}
-
-		// Update CapabilityInfo in Beacon
-		for (i = CapInfoPos; i < (CapInfoPos+2); i++)
-		{
-			RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo);
-			ptr_capinfo ++;
-		}
-
-		if (FrameLen > UpdatePos)
-		{
-			for (i= UpdatePos; i< (FrameLen); i++)
-			{
-				RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update);
-				ptr_update ++;
-			}
-		}
-
-	}
-
-}
-
-VOID RTMPInitPCIeLinkCtrlValue(
-	IN	PRTMP_ADAPTER	pAd)
-{
-}
-
-VOID RTMPFindHostPCIDev(
-    IN	PRTMP_ADAPTER	pAd)
-{
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value.
-		Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1
-
-	========================================================================
-*/
-VOID RTMPPCIeLinkCtrlValueRestore(
-	IN	PRTMP_ADAPTER	pAd,
-	IN   UCHAR		Level)
-{
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value.
-		Because now frequently set our device to mode 1 or mode 3 will cause problem.
-
-	========================================================================
-*/
-VOID RTMPPCIeLinkCtrlSetting(
-	IN	PRTMP_ADAPTER	pAd,
-	IN 	USHORT		Max)
-{
-}
-
-VOID rt2860_stop(struct net_device *net_dev)
-{
-    PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
-    if (net_dev == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	}
-	else
-		pAd = net_dev->ml_priv;
-
-	if (pAd != NULL)
-	{
-	    // stop interface
-		netif_carrier_off(net_dev);
-		netif_stop_queue(net_dev);
-
-		// mark device as removed from system and therefore no longer available
-		netif_device_detach(net_dev);
-
-		// mark halt flag
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-		// take down the device
-		rt28xx_close((PNET_DEV)net_dev);
-		RT_MOD_DEC_USE_COUNT();
-	}
-    return;
-}
-
-/*
- * invaild or writeback cache
- * and convert virtual address to physical address
- */
-dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction)
-{
-	PRTMP_ADAPTER pAd;
-	POS_COOKIE pObj;
-
-	/*
-		------ Porting Information ------
-		> For Tx Alloc:
-			mgmt packets => sd_idx = 0
-			SwIdx: pAd->MgmtRing.TxCpuIdx
-			pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
-
-			data packets => sd_idx = 1
-	 		TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
-	 		QueIdx: pTxBlk->QueIdx
-	 		pTxD  : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
-
-	 	> For Rx Alloc:
-	 		sd_idx = -1
-	*/
-
-	pAd = (PRTMP_ADAPTER)handle;
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	if (sd_idx == 1)
-	{
-		PTX_BLK		pTxBlk;
-		pTxBlk = (PTX_BLK)ptr;
-		return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction);
-	}
-	else
-	{
-		return pci_map_single(pObj->pci_dev, ptr, size, direction);
-	}
-
-}
-
-void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction)
-{
-	PRTMP_ADAPTER pAd;
-	POS_COOKIE pObj;
-
-	pAd=(PRTMP_ADAPTER)handle;
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
-
-}
-
diff --git a/drivers/staging/rt2860/Makefile b/drivers/staging/rt2860/Makefile
index c9fe925..4404ddb 100644
--- a/drivers/staging/rt2860/Makefile
+++ b/drivers/staging/rt2860/Makefile
@@ -2,26 +2,33 @@  obj-$(CONFIG_RT2860)	+= rt2860sta.o
 
 # TODO: all of these should be removed
 EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-EXTRA_CFLAGS += -DRT2860
+EXTRA_CFLAGS += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860
 EXTRA_CFLAGS += -DDBG
 
 rt2860sta-objs :=	\
-	common/md5.o		\
+	common/crypt_md5.o	\
+	common/crypt_sha2.o	\
+	common/crypt_hmac.o	\
 	common/mlme.o		\
-	common/rtmp_wep.o	\
+	common/cmm_wep.o	\
 	common/action.o		\
 	common/cmm_data.o	\
 	common/rtmp_init.o	\
-	common/rtmp_tkip.o	\
+	common/cmm_tkip.o	\
+	common/cmm_aes.o	\
 	common/cmm_sync.o	\
 	common/eeprom.o		\
 	common/cmm_sanity.o	\
 	common/cmm_info.o	\
+	common/cmm_cfg.o	\
 	common/cmm_wpa.o	\
 	common/dfs.o		\
 	common/spectrum.o	\
+	common/rtmp_timer.o	\
+	common/rt_channel.o	\
+	common/cmm_profile.o	\
+	common/cmm_asic.o	\
 	sta/assoc.o		\
-	sta/aironet.o		\
 	sta/auth.o		\
 	sta/auth_rsp.o		\
 	sta/sync.o		\
@@ -34,6 +41,9 @@  rt2860sta-objs :=	\
 	rt_main_dev.o		\
 	sta_ioctl.o		\
 	common/ba_action.o	\
-	common/2860_rtmp_init.o	\
-	2860_main_dev.o		\
-	common/cmm_data_2860.o
+	pci_main_dev.o		\
+	rt_pci_rbus.o		\
+	common/cmm_mac_pci.o	\
+	common/cmm_data_pci.o	\
+	common/ee_prom.o	\
+	common/rtmp_mcu.o
diff --git a/drivers/staging/rt2860/aironet.h b/drivers/staging/rt2860/aironet.h
deleted file mode 100644
index 1e07b19..0000000
--- a/drivers/staging/rt2860/aironet.h
+++ /dev/null
@@ -1,210 +0,0 @@ 
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	aironet.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-	Paul Lin	04-06-15		Initial
-*/
-
-#ifndef	__AIRONET_H__
-#define	__AIRONET_H__
-
-// Measurement Type definition
-#define	MSRN_TYPE_UNUSED				0
-#define	MSRN_TYPE_CHANNEL_LOAD_REQ		1
-#define	MSRN_TYPE_NOISE_HIST_REQ		2
-#define	MSRN_TYPE_BEACON_REQ			3
-#define	MSRN_TYPE_FRAME_REQ				4
-
-// Scan Mode in Beacon Request
-#define	MSRN_SCAN_MODE_PASSIVE			0
-#define	MSRN_SCAN_MODE_ACTIVE			1
-#define	MSRN_SCAN_MODE_BEACON_TABLE		2
-
-// PHY type definition for Aironet beacon report, CCX 2 table 36-9
-#define	PHY_FH							1
-#define	PHY_DSS							2
-#define	PHY_UNUSED						3
-#define	PHY_OFDM						4
-#define	PHY_HR_DSS						5
-#define	PHY_ERP							6
-
-// RPI table in dBm
-#define	RPI_0			0			//	Power <= -87
-#define	RPI_1			1			//	-87 < Power <= -82
-#define	RPI_2			2			//	-82 < Power <= -77
-#define	RPI_3			3			//	-77 < Power <= -72
-#define	RPI_4			4			//	-72 < Power <= -67
-#define	RPI_5			5			//	-67 < Power <= -62
-#define	RPI_6			6			//	-62 < Power <= -57
-#define	RPI_7			7			//	-57 < Power
-
-// Cisco Aironet IAPP definetions
-#define	AIRONET_IAPP_TYPE					0x32
-#define	AIRONET_IAPP_SUBTYPE_REQUEST		0x01
-#define	AIRONET_IAPP_SUBTYPE_REPORT			0x81
-
-// Measurement Request detail format
-typedef	struct	_MEASUREMENT_REQUEST	{
-	UCHAR	Channel;
-	UCHAR	ScanMode;			// Use only in beacon request, other requests did not use this field
-	USHORT	Duration;
-}	MEASUREMENT_REQUEST, *PMEASUREMENT_REQUEST;
-
-// Beacon Measurement Report
-// All these field might change to UCHAR, because we didn't do anything to these report.
-// We copy all these beacons and report to CCX 2 AP.
-typedef	struct	_BEACON_REPORT	{
-	UCHAR	Channel;
-	UCHAR	Spare;
-	USHORT	Duration;
-	UCHAR	PhyType;			// Definiation is listed above table 36-9
-	UCHAR	RxPower;
-	UCHAR	BSSID[6];
-	UCHAR	ParentTSF[4];
-	UCHAR	TargetTSF[8];
-	USHORT	BeaconInterval;
-	USHORT	CapabilityInfo;
-}	BEACON_REPORT, *PBEACON_REPORT;
-
-// Frame Measurement Report (Optional)
-typedef	struct	_FRAME_REPORT	{
-	UCHAR	Channel;
-	UCHAR	Spare;
-	USHORT	Duration;
-	UCHAR	TA;
-	UCHAR	BSSID[6];
-	UCHAR	RSSI;
-	UCHAR	Count;
-}	FRAME_REPORT, *PFRAME_REPORT;
-
-#pragma pack(1)
-// Channel Load Report
-typedef	struct	_CHANNEL_LOAD_REPORT	{
-	UCHAR	Channel;
-	UCHAR	Spare;
-	USHORT	Duration;
-	UCHAR	CCABusy;
-}	CHANNEL_LOAD_REPORT, *PCHANNEL_LOAD_REPORT;
-#pragma pack()
-
-// Nosie Histogram Report
-typedef	struct	_NOISE_HIST_REPORT	{
-	UCHAR	Channel;
-	UCHAR	Spare;
-	USHORT	Duration;
-	UCHAR	Density[8];
-}	NOISE_HIST_REPORT, *PNOISE_HIST_REPORT;
-
-// Radio Management Capability element
-typedef	struct	_RADIO_MANAGEMENT_CAPABILITY	{
-	UCHAR	Eid;				// TODO: Why the Eid is 1 byte, not normal 2 bytes???
-	UCHAR	Length;
-	UCHAR	AironetOui[3];		// AIronet OUI (00 40 96)
-	UCHAR	Type;				// Type / Version
-	USHORT	Status;				// swap16 required
-}	RADIO_MANAGEMENT_CAPABILITY, *PRADIO_MANAGEMENT_CAPABILITY;
-
-// Measurement Mode Bit definition
-typedef	struct	_MEASUREMENT_MODE	{
-	UCHAR	Rsvd:4;
-	UCHAR	Report:1;
-	UCHAR	NotUsed:1;
-	UCHAR	Enable:1;
-	UCHAR	Parallel:1;
-}	MEASUREMENT_MODE, *PMEASUREMENT_MODE;
-
-// Measurement Request element, This is little endian mode
-typedef	struct	_MEASUREMENT_REQUEST_ELEMENT	{
-	USHORT				Eid;
-	USHORT				Length;				// swap16 required
-	USHORT				Token;				// non-zero unique token
-	UCHAR				Mode;				// Measurement Mode
-	UCHAR				Type;				// Measurement type
-}	MEASUREMENT_REQUEST_ELEMENT, *PMEASUREMENT_REQUEST_ELEMENT;
-
-// Measurement Report element, This is little endian mode
-typedef	struct	_MEASUREMENT_REPORT_ELEMENT	{
-	USHORT				Eid;
-	USHORT				Length;				// swap16 required
-	USHORT				Token;				// non-zero unique token
-	UCHAR				Mode;				// Measurement Mode
-	UCHAR				Type;				// Measurement type
-}	MEASUREMENT_REPORT_ELEMENT, *PMEASUREMENT_REPORT_ELEMENT;
-
-// Cisco Aironet IAPP Frame Header, Network byte order used
-typedef	struct	_AIRONET_IAPP_HEADER {
-	UCHAR	CiscoSnapHeader[8];	// 8 bytes Cisco snap header
-	USHORT	Length;				// IAPP ID & length, remember to swap16 in LE system
-	UCHAR	Type;				// IAPP type
-	UCHAR	SubType;			// IAPP subtype
-	UCHAR	DA[6];				// Destination MAC address
-	UCHAR	SA[6];				// Source MAC address
-	USHORT	Token;				// Dialog token, no need to swap16 since it is for yoken usage only
-}	AIRONET_IAPP_HEADER, *PAIRONET_IAPP_HEADER;
-
-// Radio Measurement Request frame
-typedef	struct	_AIRONET_RM_REQUEST_FRAME	{
-    AIRONET_IAPP_HEADER	IAPP;			// Common header
-	UCHAR				Delay;			// Activation Delay
-	UCHAR				Offset;			// Measurement offset
-}	AIRONET_RM_REQUEST_FRAME, *PAIRONET_RM_REQUEST_FRAME;
-
-// Radio Measurement Report frame
-typedef	struct	_AIRONET_RM_REPORT_FRAME	{
-    AIRONET_IAPP_HEADER	IAPP;			// Common header
-}	AIRONET_RM_REPORT_FRAME, *PAIRONET_RM_REPORT_FRAME;
-
-// Saved element request actions which will saved in StaCfg.
-typedef	struct	_RM_REQUEST_ACTION	{
-	MEASUREMENT_REQUEST_ELEMENT	ReqElem;		// Saved request element
-	MEASUREMENT_REQUEST			Measurement;	// Saved measurement within the request element
-}	RM_REQUEST_ACTION, *PRM_REQUEST_ACTION;
-
-// CCX administration control
-typedef	union	_CCX_CONTROL	{
-	struct	{
-		UINT32		Enable:1;			// Enable CCX2
-		UINT32		LeapEnable:1;		// Enable LEAP at CCX2
-		UINT32		RMEnable:1;			// Radio Measurement Enable
-		UINT32		DCRMEnable:1;		// Non serving channel Radio Measurement enable
-		UINT32		QOSEnable:1;		// Enable QOS for CCX 2.0 support
-		UINT32		FastRoamEnable:1;	// Enable fast roaming
-		UINT32		Rsvd:2;				// Not used
-		UINT32		dBmToRoam:8;		// the condition to roam when receiving Rssi less than this value. It's negative value.
-		UINT32		TuLimit:16;			// Limit for different channel scan
-	}	field;
-	UINT32			word;
-}	CCX_CONTROL, *PCCX_CONTROL;
-
-#endif	// __AIRONET_H__
diff --git a/drivers/staging/rt2860/ap.h b/drivers/staging/rt2860/ap.h
index fcdb358..6c58ce8 100644
--- a/drivers/staging/rt2860/ap.h
+++ b/drivers/staging/rt2860/ap.h
@@ -40,22 +40,24 @@ 
 #ifndef __AP_H__
 #define __AP_H__
 
-// ap_mlme.c
+// ap_wpa.c
+VOID WpaStateMachineInit(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  STATE_MACHINE *Sm,
+    OUT STATE_MACHINE_FUNC Trans[]);
 
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 VOID BeaconUpdateExec(
     IN PVOID SystemSpecific1,
     IN PVOID FunctionContext,
     IN PVOID SystemSpecific2,
     IN PVOID SystemSpecific3);
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
 
 VOID RTMPSetPiggyBack(
 	IN PRTMP_ADAPTER	pAd,
 	IN BOOLEAN			bPiggyBack);
 
-// ap.c
-
 VOID MacTableReset(
     IN  PRTMP_ADAPTER   pAd);
 
diff --git a/drivers/staging/rt2860/chip/mac_pci.h b/drivers/staging/rt2860/chip/mac_pci.h
new file mode 100644
index 0000000..9ca9c36
--- /dev/null
+++ b/drivers/staging/rt2860/chip/mac_pci.h
@@ -0,0 +1,365 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	mac_pci.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __MAC_PCI_H__
+#define __MAC_PCI_H__
+
+#include "../rtmp_type.h"
+#include "rtmp_mac.h"
+#include "rtmp_phy.h"
+#include "../rtmp_iface.h"
+#include "../rtmp_dot11.h"
+
+
+//
+// Device ID & Vendor ID related definitions,
+// NOTE: you should not add the new VendorID/DeviceID here unless you not sure it belongs to what chip.
+//
+#define NIC_PCI_VENDOR_ID		0x1814
+#define PCIBUS_INTEL_VENDOR	0x8086
+
+#if !defined(PCI_CAP_ID_EXP)
+#define PCI_CAP_ID_EXP			    0x10
+#endif
+#if !defined(PCI_EXP_LNKCTL)
+#define PCI_EXP_LNKCTL			    0x10
+#endif
+#if !defined(PCI_CLASS_BRIDGE_PCI)
+#define PCI_CLASS_BRIDGE_PCI		0x0604
+#endif
+
+
+
+
+
+#define TXINFO_SIZE						0
+#define RTMP_PKT_TAIL_PADDING			0
+#define fRTMP_ADAPTER_NEED_STOP_TX	0
+
+#define AUX_CTRL           0x10c
+
+//
+// TX descriptor format, Tx	ring, Mgmt Ring
+//
+typedef	struct	PACKED _TXD_STRUC {
+	// Word	0
+	UINT32		SDPtr0;
+	// Word	1
+	UINT32		SDLen1:14;
+	UINT32		LastSec1:1;
+	UINT32		Burst:1;
+	UINT32		SDLen0:14;
+	UINT32		LastSec0:1;
+	UINT32		DMADONE:1;
+	//Word2
+	UINT32		SDPtr1;
+	//Word3
+	UINT32		rsv2:24;
+	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
+	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+	UINT32		rsv:2;
+	UINT32		TCO:1;	//
+	UINT32		UCO:1;	//
+	UINT32		ICO:1;	//
+}	TXD_STRUC, *PTXD_STRUC;
+
+
+//
+// Rx descriptor format, Rx Ring
+//
+typedef	struct	PACKED _RXD_STRUC{
+	// Word	0
+	UINT32		SDP0;
+	// Word	1
+	UINT32		SDL1:14;
+	UINT32		Rsv:2;
+	UINT32		SDL0:14;
+	UINT32		LS0:1;
+	UINT32		DDONE:1;
+	// Word	2
+	UINT32		SDP1;
+	// Word	3
+	UINT32		BA:1;
+	UINT32		DATA:1;
+	UINT32		NULLDATA:1;
+	UINT32		FRAG:1;
+	UINT32		U2M:1;              // 1: this RX frame is unicast to me
+	UINT32		Mcast:1;            // 1: this is a multicast frame
+	UINT32		Bcast:1;            // 1: this is a broadcast frame
+	UINT32		MyBss:1;	// 1: this frame belongs to the same BSSID
+	UINT32		Crc:1;              // 1: CRC error
+	UINT32		CipherErr:2;        // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
+	UINT32		AMSDU:1;		// rx with 802.3 header, not 802.11 header.
+	UINT32		HTC:1;
+	UINT32		RSSI:1;
+	UINT32		L2PAD:1;
+	UINT32		AMPDU:1;
+	UINT32		Decrypted:1;	// this frame is being decrypted.
+	UINT32		PlcpSignal:1;		// To be moved
+	UINT32		PlcpRssil:1;// To be moved
+	UINT32		Rsv1:13;
+}	RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+
+
+/* ----------------- EEPROM Related MACRO ----------------- */
+
+// 8051 firmware image for RT2860 - base address = 0x4000
+#define FIRMWARE_IMAGE_BASE     0x2000
+#define MAX_FIRMWARE_IMAGE_SIZE 0x2000    // 8kbyte
+
+
+/* ----------------- Frimware Related MACRO ----------------- */
+#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)			\
+	do{								\
+		ULONG	_i, _firm;					\
+		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000);		\
+									\
+		for(_i=0; _i<_FwLen; _i+=4)				\
+		{							\
+			_firm = _pFwImage[_i] +				\
+			   (_pFwImage[_i+3] << 24) +			\
+			   (_pFwImage[_i+2] << 16) +			\
+			   (_pFwImage[_i+1] << 8);			\
+			RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm);	\
+		}							\
+		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000);		\
+		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001);		\
+									\
+		/* initialize BBP R/W access agent */			\
+		RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0);		\
+		RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0);		\
+	}while(0)
+
+
+/* ----------------- TX Related MACRO ----------------- */
+#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
+#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
+
+
+#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+		((freeNum) >= (ULONG)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */
+#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx)	\
+		do{}while(0)
+
+#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \
+		(((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3))
+		//(((freeNum) != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 1 /*0*/))
+
+
+#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)	\
+			RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)
+
+#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
+		/* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)*/
+
+#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)	\
+			RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
+
+#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
+			RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
+
+#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)	\
+			RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
+
+#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)	\
+			RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)
+
+#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \
+			/*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx)*/
+
+#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx)	\
+			RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
+/*			RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/
+
+#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
+			MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen)
+
+#define GET_TXRING_FREENO(_pAd, _QueIdx) \
+	(_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx)	? \
+			(_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \
+			 :	\
+			(_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);
+
+
+#define GET_MGMTRING_FREENO(_pAd) \
+	(_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx)	? \
+			(_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \
+			 :	\
+			(_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);
+
+
+/* ----------------- RX Related MACRO ----------------- */
+
+
+/* ----------------- ASIC Related MACRO ----------------- */
+// reset MAC of a station entry to 0x000000000000
+#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid)	\
+	AsicDelWcidTab(pAd, Wcid);
+
+// add this entry into ASIC RX WCID search table
+#define RTMP_STA_ENTRY_ADD(pAd, pEntry)		\
+	AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
+
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+// Set MAC register value according operation mode
+#define RTMP_UPDATE_PROTECT(pAd)	\
+	AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
+// end johnli
+
+// remove Pair-wise key material from ASIC
+#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)	\
+	AsicRemovePairwiseKeyEntry(pAd, BssIdx, (UCHAR)Wcid);
+
+// add Client security information into ASIC WCID table and IVEIV table
+#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)		\
+	RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,			\
+							pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry);
+
+#define RTMP_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry)		\
+	{	/* update pairwise key information to ASIC Shared Key Table */	\
+		AsicAddSharedKeyEntry(pAd, apidx, KeyID,					\
+						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
+						  pAd->SharedKey[apidx][KeyID].Key,				\
+						  pAd->SharedKey[apidx][KeyID].TxMic,			\
+						  pAd->SharedKey[apidx][KeyID].RxMic);			\
+		/* update ASIC WCID attribute table and IVEIV table */			\
+		RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,					\
+						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
+						  pEntry); }
+
+
+// Insert the BA bitmap to ASIC for the Wcid entry
+#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)	\
+		do{					\
+			UINT32	_Value = 0, _Offset;					\
+			_Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4;	\
+			RTMP_IO_READ32((_pAd), _Offset, &_Value);\
+			_Value |= (0x10000<<(_TID));	\
+			RTMP_IO_WRITE32((_pAd), _Offset, _Value);\
+		}while(0)
+
+
+// Remove the BA bitmap from ASIC for the Wcid entry
+//		bitmap field starts at 0x10000 in ASIC WCID table
+#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
+		do{								\
+			UINT32	_Value = 0, _Offset;				\
+			_Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4;	\
+			RTMP_IO_READ32((_pAd), _Offset, &_Value);			\
+			_Value &= (~(0x10000 << (_TID)));				\
+			RTMP_IO_WRITE32((_pAd), _Offset, _Value);			\
+		}while(0)
+
+
+/* ----------------- Interface Related MACRO ----------------- */
+
+//
+// Enable & Disable NIC interrupt via writing interrupt mask register
+// Since it use ADAPTER structure, it have to be put after structure definition.
+//
+#define RTMP_ASIC_INTERRUPT_DISABLE(_pAd)		\
+	do{			\
+		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0);     /* 0: disable */	\
+		RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);		\
+	}while(0)
+
+#define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\
+	do{				\
+		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/);     /* 1:enable */	\
+		RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);	\
+	}while(0)
+
+
+#define RTMP_IRQ_INIT(pAd)	\
+	{	pAd->int_enable_reg = ((DELAYINTMASK) |		\
+					(RxINT|TxDataInt|TxMgmtInt)) & ~(0x03);	\
+		pAd->int_disable_mask = 0;						\
+		pAd->int_pending = 0; }
+
+#define RTMP_IRQ_ENABLE(pAd)					\
+	{	/* clear garbage ints */			\
+		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);\
+		RTMP_ASIC_INTERRUPT_ENABLE(pAd); }
+
+
+/* ----------------- MLME Related MACRO ----------------- */
+#define RTMP_MLME_HANDLER(pAd)			MlmeHandler(pAd)
+
+#define RTMP_MLME_PRE_SANITY_CHECK(pAd)
+
+#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
+		RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+
+#define RTMP_MLME_RESET_STATE_MACHINE(pAd)	\
+		MlmeRestartStateMachine(pAd)
+
+#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)\
+		HandleCounterMeasure(_pAd, _pEntry)
+
+/* ----------------- Power Save Related MACRO ----------------- */
+#define RTMP_PS_POLL_ENQUEUE(pAd)				EnqueuePsPoll(pAd)
+
+
+// For RTMPPCIePowerLinkCtrlRestore () function
+#define RESTORE_HALT		1
+#define RESTORE_WAKEUP		2
+#define RESTORE_CLOSE           3
+
+#define PowerSafeCID		1
+#define PowerRadioOffCID	2
+#define PowerWakeCID		3
+#define CID0MASK		0x000000ff
+#define CID1MASK		0x0000ff00
+#define CID2MASK		0x00ff0000
+#define CID3MASK		0xff000000
+
+
+#define RTMP_STA_FORCE_WAKEUP(pAd, bFromTx) \
+    RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
+
+#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
+    RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+
+#define RTMP_SET_PSM_BIT(_pAd, _val) \
+	MlmeSetPsmBit(_pAd, _val);
+
+#define RTMP_MLME_RADIO_ON(pAd) \
+    RT28xxPciMlmeRadioOn(pAd);
+
+#define RTMP_MLME_RADIO_OFF(pAd) \
+    RT28xxPciMlmeRadioOFF(pAd);
+
+#endif //__MAC_PCI_H__ //
diff --git a/drivers/staging/rt2860/chip/mac_usb.h b/drivers/staging/rt2860/chip/mac_usb.h
new file mode 100644
index 0000000..5a85883
--- /dev/null
+++ b/drivers/staging/rt2860/chip/mac_usb.h
@@ -0,0 +1,365 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+        mac_usb.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __MAC_USB_H__
+#define __MAC_USB_H__
+
+#include "../rtmp_type.h"
+#include "rtmp_mac.h"
+#include "rtmp_phy.h"
+#include "../rtmp_iface.h"
+#include "../rtmp_dot11.h"
+
+
+#define USB_CYC_CFG				0x02a4
+
+#define BEACON_RING_SIZE		2
+#define MGMTPIPEIDX				0	// EP6 is highest priority
+
+#define RTMP_PKT_TAIL_PADDING	11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding)
+
+#define fRTMP_ADAPTER_NEED_STOP_TX		\
+		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
+		 fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
+		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
+
+//
+// RXINFO appends at the end of each rx packet.
+//
+#define RXINFO_SIZE				4
+#define RT2870_RXDMALEN_FIELD_SIZE	4
+
+typedef	struct	PACKED _RXINFO_STRUC {
+	UINT32		BA:1;
+	UINT32		DATA:1;
+	UINT32		NULLDATA:1;
+	UINT32		FRAG:1;
+	UINT32		U2M:1;              // 1: this RX frame is unicast to me
+	UINT32		Mcast:1;            // 1: this is a multicast frame
+	UINT32		Bcast:1;            // 1: this is a broadcast frame
+	UINT32		MyBss:1;	// 1: this frame belongs to the same BSSID
+	UINT32		Crc:1;              // 1: CRC error
+	UINT32		CipherErr:2;        // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
+	UINT32		AMSDU:1;		// rx with 802.3 header, not 802.11 header.
+	UINT32		HTC:1;
+	UINT32		RSSI:1;
+	UINT32		L2PAD:1;
+	UINT32		AMPDU:1;		// To be moved
+	UINT32		Decrypted:1;
+	UINT32		PlcpRssil:1;
+	UINT32		CipherAlg:1;
+	UINT32		LastAMSDU:1;
+	UINT32		PlcpSignal:12;
+}	RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+
+
+//
+// TXINFO
+//
+#define TXINFO_SIZE				4
+
+typedef	struct	_TXINFO_STRUC {
+	// Word	0
+	UINT32		USBDMATxPktLen:16;	//used ONLY in USB bulk Aggregation,  Total byte counts of all sub-frame.
+	UINT32		rsv:8;
+	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
+	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+	UINT32		SwUseLastRound:1; // Software use.
+	UINT32		rsv2:2;  // Software use.
+	UINT32		USBDMANextVLD:1;	//used ONLY in USB bulk Aggregation, NextValid
+	UINT32		USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
+}	TXINFO_STRUC, *PTXINFO_STRUC;
+
+
+//
+// Management ring buffer format
+//
+typedef	struct	_MGMT_STRUC	{
+	BOOLEAN		Valid;
+	PUCHAR		pBuffer;
+	ULONG		Length;
+}	MGMT_STRUC, *PMGMT_STRUC;
+
+
+////////////////////////////////////////////////////////////////////////////
+// The TX_BUFFER structure forms the transmitted USB packet to the device
+////////////////////////////////////////////////////////////////////////////
+typedef struct __TX_BUFFER{
+	union{
+		UCHAR			WirelessPacket[TX_BUFFER_NORMSIZE];
+		HEADER_802_11	NullFrame;
+		PSPOLL_FRAME	PsPollPacket;
+		RTS_FRAME		RTSFrame;
+	}field;
+	UCHAR			Aggregation[4];  //Buffer for save Aggregation size.
+} TX_BUFFER, *PTX_BUFFER;
+
+typedef struct __HTTX_BUFFER{
+	union{
+		UCHAR			WirelessPacket[MAX_TXBULK_SIZE];
+		HEADER_802_11	NullFrame;
+		PSPOLL_FRAME	PsPollPacket;
+		RTS_FRAME		RTSFrame;
+	}field;
+	UCHAR			Aggregation[4];  //Buffer for save Aggregation size.
+} HTTX_BUFFER, *PHTTX_BUFFER;
+
+
+// used to track driver-generated write irps
+typedef struct _TX_CONTEXT
+{
+	PVOID			pAd;		//Initialized in MiniportInitialize
+	PURB			pUrb;			//Initialized in MiniportInitialize
+	PIRP			pIrp;			//used to cancel pending bulk out.
+									//Initialized in MiniportInitialize
+	PTX_BUFFER		TransferBuffer;	//Initialized in MiniportInitialize
+	ULONG			BulkOutSize;
+	UCHAR			BulkOutPipeId;
+	UCHAR			SelfIdx;
+	BOOLEAN			InUse;
+	BOOLEAN			bWaitingBulkOut; // at least one packet is in this TxContext, ready for making IRP anytime.
+	BOOLEAN			bFullForBulkOut; // all tx buffer are full , so waiting for tx bulkout.
+	BOOLEAN			IRPPending;
+	BOOLEAN			LastOne;
+	BOOLEAN			bAggregatible;
+	UCHAR			Header_802_3[LENGTH_802_3];
+	UCHAR			Rsv[2];
+	ULONG			DataOffset;
+	UINT			TxRate;
+	dma_addr_t		data_dma;		// urb dma on linux
+
+}	TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT;
+
+
+// used to track driver-generated write irps
+typedef struct _HT_TX_CONTEXT
+{
+	PVOID			pAd;		//Initialized in MiniportInitialize
+	PURB			pUrb;			//Initialized in MiniportInitialize
+	PIRP			pIrp;			//used to cancel pending bulk out.
+									//Initialized in MiniportInitialize
+	PHTTX_BUFFER	TransferBuffer;	//Initialized in MiniportInitialize
+	ULONG			BulkOutSize;	// Indicate the total bulk-out size in bytes in one bulk-transmission
+	UCHAR			BulkOutPipeId;
+	BOOLEAN			IRPPending;
+	BOOLEAN			LastOne;
+	BOOLEAN			bCurWriting;
+	BOOLEAN			bRingEmpty;
+	BOOLEAN			bCopySavePad;
+	UCHAR			SavedPad[8];
+	UCHAR			Header_802_3[LENGTH_802_3];
+	ULONG			CurWritePosition;		// Indicate the buffer offset which packet will be inserted start from.
+	ULONG			CurWriteRealPos;		// Indicate the buffer offset which packet now are writing to.
+	ULONG			NextBulkOutPosition;	// Indicate the buffer start offset of a bulk-transmission
+	ULONG			ENextBulkOutPosition;	// Indicate the buffer end offset of a bulk-transmission
+	UINT			TxRate;
+	dma_addr_t		data_dma;		// urb dma on linux
+}	HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT;
+
+
+//
+// Structure to keep track of receive packets and buffers to indicate
+// receive data to the protocol.
+//
+typedef struct _RX_CONTEXT
+{
+	PUCHAR				TransferBuffer;
+	PVOID				pAd;
+	PIRP				pIrp;//used to cancel pending bulk in.
+	PURB				pUrb;
+	//These 2 Boolean shouldn't both be 1 at the same time.
+	ULONG				BulkInOffset;	// number of packets waiting for reordering .
+//	BOOLEAN				ReorderInUse;	// At least one packet in this buffer are in reordering buffer and wait for receive indication
+	BOOLEAN				bRxHandling;	// Notify this packet is being process now.
+	BOOLEAN				InUse;			// USB Hardware Occupied. Wait for USB HW to put packet.
+	BOOLEAN				Readable;		// Receive Complete back. OK for driver to indicate receiving packet.
+	BOOLEAN				IRPPending;		// TODO: To be removed
+	atomic_t			IrpLock;
+	NDIS_SPIN_LOCK		RxContextLock;
+	dma_addr_t			data_dma;		// urb dma on linux
+}	RX_CONTEXT, *PRX_CONTEXT;
+
+
+
+/******************************************************************************
+
+	USB Frimware Related MACRO
+
+******************************************************************************/
+// 8051 firmware image for usb - use last-half base address = 0x3000
+#define FIRMWARE_IMAGE_BASE			0x3000
+#define MAX_FIRMWARE_IMAGE_SIZE		0x1000    // 4kbyte
+
+#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)		\
+	RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
+
+
+
+/******************************************************************************
+
+	USB TX Related MACRO
+
+******************************************************************************/
+#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags)				\
+			do{													\
+				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
+				if (pAd->DeQueueRunning[QueIdx])						\
+				{														\
+					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+					DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx));		\
+					continue;											\
+				}														\
+				else													\
+				{														\
+					pAd->DeQueueRunning[QueIdx] = TRUE;					\
+					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+				}														\
+			}while(0)
+
+#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags)						\
+			do{															\
+				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
+				pAd->DeQueueRunning[QueIdx] = FALSE;					\
+				RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);	\
+			}while(0)
+
+#define	RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+		(RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
+
+#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx)			\
+		do{}while(0)
+
+#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType)		\
+		((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
+
+#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
+			RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
+
+#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)	\
+			RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)
+
+#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
+			RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
+
+#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)	\
+			RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)
+
+#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)	\
+			RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
+
+#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \
+			/*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/
+
+#define HAL_KickOutTx(pAd, pTxBlk, QueIdx)	\
+			RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
+
+#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)	\
+			RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
+
+#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
+			RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
+
+#define GET_TXRING_FREENO(_pAd, _QueIdx)	(_QueIdx) //(_pAd->TxRing[_QueIdx].TxSwFreeIdx)
+#define GET_MGMTRING_FREENO(_pAd)			(_pAd->MgmtRing.TxSwFreeIdx)
+
+
+/* ----------------- RX Related MACRO ----------------- */
+
+
+/*
+  *	Device Hardware Interface Related MACRO
+  */
+#define RTMP_IRQ_INIT(pAd)				do{}while(0)
+#define RTMP_IRQ_ENABLE(pAd)			do{}while(0)
+
+
+/*
+  *	MLME Related MACRO
+  */
+#define RTMP_MLME_HANDLER(pAd)			RTUSBMlmeUp(pAd)
+
+#define RTMP_MLME_PRE_SANITY_CHECK(pAd)								\
+	{	if ((pAd->CommonCfg.bHardwareRadio == TRUE) &&					\
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&		\
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) {	\
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
+
+#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
+	{	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0);	\
+		RTUSBMlmeUp(pAd); }
+
+#define RTMP_MLME_RESET_STATE_MACHINE(pAd)	\
+		        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL);	\
+		        RTUSBMlmeUp(pAd);
+
+#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)		\
+	{	RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY));	\
+		RTUSBMlmeUp(_pAd);									\
+	}
+
+
+/*
+  *	Power Save Related MACRO
+  */
+#define RTMP_PS_POLL_ENQUEUE(pAd)						\
+	{	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);	\
+		RTUSBKickBulkOut(pAd); }
+
+#define RTMP_STA_FORCE_WAKEUP(_pAd, bFromTx) \
+	RT28xxUsbStaAsicForceWakeup(_pAd, bFromTx);
+
+#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
+    RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+
+#define RTMP_SET_PSM_BIT(_pAd, _val) \
+	{\
+		if ((_pAd)->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP) \
+			MlmeSetPsmBit(_pAd, _val);\
+		else \
+		{ \
+			USHORT _psm_val; \
+			_psm_val = _val; \
+			RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PSM_BIT, &(_psm_val), sizeof(USHORT)); \
+		}\
+	}
+
+#define RTMP_MLME_RADIO_ON(pAd) \
+    RT28xxUsbMlmeRadioOn(pAd);
+
+#define RTMP_MLME_RADIO_OFF(pAd) \
+    RT28xxUsbMlmeRadioOFF(pAd);
+
+#endif //__MAC_USB_H__ //
diff --git a/drivers/staging/rt2860/chip/rt2860.h b/drivers/staging/rt2860/chip/rt2860.h
new file mode 100644
index 0000000..2989d09
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rt2860.h
@@ -0,0 +1,56 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#ifndef __RT2860_H__
+#define __RT2860_H__
+
+#include "mac_pci.h"
+
+#ifndef RTMP_PCI_SUPPORT
+#error "For RT2860, you should define the compile flag -DRTMP_PCI_SUPPORT"
+#endif
+
+#ifndef RTMP_MAC_PCI
+#error "For RT2880, you should define the compile flag -DRTMP_MAC_PCI"
+#endif
+
+//
+// Device ID & Vendor ID, these values should match EEPROM value
+//
+#define NIC2860_PCI_DEVICE_ID	0x0601
+#define NIC2860_PCIe_DEVICE_ID	0x0681
+#define NIC2760_PCI_DEVICE_ID	0x0701		// 1T/2R Cardbus ???
+#define NIC2790_PCIe_DEVICE_ID  0x0781		// 1T/2R miniCard
+
+
+#define VEN_AWT_PCIe_DEVICE_ID	0x1059
+#define VEN_AWT_PCI_VENDOR_ID		0x1A3B
+
+#define EDIMAX_PCI_VENDOR_ID		0x1432
+
+
+#endif //__RT2860_H__ //
diff --git a/drivers/staging/rt2860/chip/rt2870.h b/drivers/staging/rt2860/chip/rt2870.h
new file mode 100644
index 0000000..a930925
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rt2870.h
@@ -0,0 +1,47 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+#ifndef __RT2870_H__
+#define __RT2870_H__
+
+#ifdef RT2870
+
+#ifndef RTMP_USB_SUPPORT
+#error "For RT2870, you should define the compile flag -DRTMP_USB_SUPPORT"
+#endif
+
+#ifndef RTMP_MAC_USB
+#error "For RT2870, you should define the compile flag -DRTMP_MAC_USB"
+#endif
+
+#include "../rtmp_type.h"
+#include "mac_usb.h"
+
+
+//#define RTMP_CHIP_NAME		"RT2870"
+
+#endif // RT2870 //
+#endif //__RT2870_H__ //
diff --git a/drivers/staging/rt2860/chip/rt3070.h b/drivers/staging/rt2860/chip/rt3070.h
new file mode 100644
index 0000000..87df99a
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rt3070.h
@@ -0,0 +1,68 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	rt3070.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT3070_H__
+#define __RT3070_H__
+
+#ifdef RT3070
+
+
+#ifndef RTMP_USB_SUPPORT
+#error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT"
+#endif
+
+#ifndef RTMP_MAC_USB
+#error "For RT3070, you should define the compile flag -DRTMP_MAC_USB"
+#endif
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
+#endif
+
+#ifndef RT30xx
+#error "For RT3070, you should define the compile flag -DRT30xx"
+#endif
+
+#include "mac_usb.h"
+#include "rt30xx.h"
+
+//
+// Device ID & Vendor ID, these values should match EEPROM value
+//
+
+#endif // RT3070 //
+
+#endif //__RT3070_H__ //
diff --git a/drivers/staging/rt2860/chip/rt30xx.h b/drivers/staging/rt2860/chip/rt30xx.h
new file mode 100644
index 0000000..70971a0
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rt30xx.h
@@ -0,0 +1,48 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	rt30xx.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT30XX_H__
+#define __RT30XX_H__
+
+#ifdef RT30xx
+
+
+extern REG_PAIR RT30xx_RFRegTable[];
+extern UCHAR NUM_RF_REG_PARMS;
+
+#endif // RT30xx //
+
+#endif //__RT30XX_H__ //
diff --git a/drivers/staging/rt2860/chip/rtmp_mac.h b/drivers/staging/rt2860/chip/rtmp_mac.h
new file mode 100644
index 0000000..3ddb0bf
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rtmp_mac.h
@@ -0,0 +1,1334 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_mac.h
+
+	Abstract:
+	Ralink Wireless Chip MAC related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+*/
+
+#ifndef __RTMP_MAC_H__
+#define __RTMP_MAC_H__
+
+
+
+// =================================================================================
+// TX / RX ring descriptor format
+// =================================================================================
+
+// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO.
+// MAC block use this TXINFO to control the transmission behavior of this frame.
+#define FIFO_MGMT                 0
+#define FIFO_HCCA                 1
+#define FIFO_EDCA                 2
+
+
+//
+// TXD Wireless Information format for Tx ring and Mgmt Ring
+//
+//txop : for txop mode
+// 0:txop for the MPDU frame will be handles by ASIC by register
+// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS
+typedef	struct	PACKED _TXWI_STRUC {
+	// Word	0
+	// ex: 00 03 00 40 means txop = 3, PHYMODE = 1
+	UINT32		FRAG:1;		// 1 to inform TKIP engine this is a fragment.
+	UINT32		MIMOps:1;	// the remote peer is in dynamic MIMO-PS mode
+	UINT32		CFACK:1;
+	UINT32		TS:1;
+
+	UINT32		AMPDU:1;
+	UINT32		MpduDensity:3;
+	UINT32		txop:2;	//FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
+	UINT32		rsv:6;
+
+	UINT32		MCS:7;
+	UINT32		BW:1;	//channel bandwidth 20MHz or 40 MHz
+	UINT32		ShortGI:1;
+	UINT32		STBC:2;	// 1: STBC support MCS =0-7,   2,3 : RESERVE
+	UINT32		Ifs:1;	//
+//	UINT32		rsv2:2;	//channel bandwidth 20MHz or 40 MHz
+	UINT32		rsv2:1;
+	UINT32		TxBF:1;	// 3*3
+	UINT32		PHYMODE:2;
+	// Word1
+	// ex:  1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCount = 0x38
+	UINT32		ACK:1;
+	UINT32		NSEQ:1;
+	UINT32		BAWinSize:6;
+	UINT32		WirelessCliID:8;
+	UINT32		MPDUtotalByteCount:12;
+	UINT32		PacketId:4;
+	//Word2
+	UINT32		IV;
+	//Word3
+	UINT32		EIV;
+}	TXWI_STRUC, *PTXWI_STRUC;
+
+
+//
+// RXWI wireless information format, in PBF. invisible in driver.
+//
+typedef	struct	PACKED _RXWI_STRUC {
+	// Word	0
+	UINT32		WirelessCliID:8;
+	UINT32		KeyIndex:2;
+	UINT32		BSSID:3;
+	UINT32		UDF:3;
+	UINT32		MPDUtotalByteCount:12;
+	UINT32		TID:4;
+	// Word	1
+	UINT32		FRAG:4;
+	UINT32		SEQUENCE:12;
+	UINT32		MCS:7;
+	UINT32		BW:1;
+	UINT32		ShortGI:1;
+	UINT32		STBC:2;
+	UINT32		rsv:3;
+	UINT32		PHYMODE:2;              // 1: this RX frame is unicast to me
+	//Word2
+	UINT32		RSSI0:8;
+	UINT32		RSSI1:8;
+	UINT32		RSSI2:8;
+	UINT32		rsv1:8;
+	//Word3
+	UINT32		SNR0:8;
+	UINT32		SNR1:8;
+	UINT32		FOFFSET:8;	// RT35xx
+	UINT32		rsv2:8;
+	/*UINT32		rsv2:16;*/
+}	RXWI_STRUC, *PRXWI_STRUC;
+
+
+// =================================================================================
+// Register format
+// =================================================================================
+
+
+//
+// SCH/DMA registers - base address 0x0200
+//
+// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit
+//
+#define DMA_CSR0		0x200
+#define INT_SOURCE_CSR		0x200
+typedef	union	_INT_SOURCE_CSR_STRUC	{
+	struct	{
+		UINT32		RxDelayINT:1;
+		UINT32		TxDelayINT:1;
+		UINT32		RxDone:1;
+		UINT32		Ac0DmaDone:1;//4
+		UINT32		Ac1DmaDone:1;
+		UINT32		Ac2DmaDone:1;
+		UINT32		Ac3DmaDone:1;
+		UINT32		HccaDmaDone:1; // bit7
+		UINT32		MgmtDmaDone:1;
+		UINT32		MCUCommandINT:1;//bit 9
+		UINT32		RxTxCoherent:1;
+		UINT32		TBTTInt:1;
+		UINT32		PreTBTT:1;
+		UINT32		TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
+		UINT32		AutoWakeup:1;//bit14
+		UINT32		GPTimer:1;
+		UINT32		RxCoherent:1;//bit16
+		UINT32		TxCoherent:1;
+		UINT32		:14;
+	}	field;
+	UINT32			word;
+} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
+
+//
+// INT_MASK_CSR:   Interrupt MASK register.   1: the interrupt is mask OFF
+//
+#define INT_MASK_CSR        0x204
+typedef	union	_INT_MASK_CSR_STRUC	{
+	struct	{
+		UINT32		RXDelay_INT_MSK:1;
+		UINT32		TxDelay:1;
+		UINT32		RxDone:1;
+		UINT32		Ac0DmaDone:1;
+		UINT32		Ac1DmaDone:1;
+		UINT32		Ac2DmaDone:1;
+		UINT32		Ac3DmaDone:1;
+		UINT32		HccaDmaDone:1;
+		UINT32		MgmtDmaDone:1;
+		UINT32		MCUCommandINT:1;
+		UINT32		:20;
+		UINT32		RxCoherent:1;
+		UINT32		TxCoherent:1;
+	}	field;
+	UINT32			word;
+} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
+
+#define WPDMA_GLO_CFG	0x208
+typedef	union	_WPDMA_GLO_CFG_STRUC	{
+	struct	{
+		UINT32		EnableTxDMA:1;
+		UINT32		TxDMABusy:1;
+		UINT32		EnableRxDMA:1;
+		UINT32		RxDMABusy:1;
+		UINT32		WPDMABurstSIZE:2;
+		UINT32		EnTXWriteBackDDONE:1;
+		UINT32		BigEndian:1;
+		UINT32		RXHdrScater:8;
+		UINT32		HDR_SEG_LEN:16;
+	}	field;
+	UINT32			word;
+} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
+
+#define WPDMA_RST_IDX	0x20c
+typedef	union	_WPDMA_RST_IDX_STRUC	{
+	struct	{
+		UINT32		RST_DTX_IDX0:1;
+		UINT32		RST_DTX_IDX1:1;
+		UINT32		RST_DTX_IDX2:1;
+		UINT32		RST_DTX_IDX3:1;
+		UINT32		RST_DTX_IDX4:1;
+		UINT32		RST_DTX_IDX5:1;
+		UINT32		rsv:10;
+		UINT32		RST_DRX_IDX0:1;
+		UINT32		:15;
+	}	field;
+	UINT32			word;
+} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
+#define DELAY_INT_CFG  0x0210
+typedef	union	_DELAY_INT_CFG_STRUC	{
+	struct	{
+		UINT32		RXMAX_PTIME:8;
+		UINT32		RXMAX_PINT:7;
+		UINT32		RXDLY_INT_EN:1;
+		UINT32		TXMAX_PTIME:8;
+		UINT32		TXMAX_PINT:7;
+		UINT32		TXDLY_INT_EN:1;
+	}	field;
+	UINT32			word;
+} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
+#define WMM_AIFSN_CFG   0x0214
+typedef	union	_AIFSN_CSR_STRUC	{
+	struct	{
+	    UINT32   Aifsn0:4;       // for AC_BE
+	    UINT32   Aifsn1:4;       // for AC_BK
+	    UINT32   Aifsn2:4;       // for AC_VI
+	    UINT32   Aifsn3:4;       // for AC_VO
+	    UINT32   Rsv:16;
+	}	field;
+	UINT32			word;
+}	AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
+//
+// CWMIN_CSR: CWmin for each EDCA AC
+//
+#define WMM_CWMIN_CFG   0x0218
+typedef	union	_CWMIN_CSR_STRUC	{
+	struct	{
+	    UINT32   Cwmin0:4;       // for AC_BE
+	    UINT32   Cwmin1:4;       // for AC_BK
+	    UINT32   Cwmin2:4;       // for AC_VI
+	    UINT32   Cwmin3:4;       // for AC_VO
+	    UINT32   Rsv:16;
+	}	field;
+	UINT32			word;
+}	CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
+
+//
+// CWMAX_CSR: CWmin for each EDCA AC
+//
+#define WMM_CWMAX_CFG   0x021c
+typedef	union	_CWMAX_CSR_STRUC	{
+	struct	{
+	    UINT32   Cwmax0:4;       // for AC_BE
+	    UINT32   Cwmax1:4;       // for AC_BK
+	    UINT32   Cwmax2:4;       // for AC_VI
+	    UINT32   Cwmax3:4;       // for AC_VO
+	    UINT32   Rsv:16;
+	}	field;
+	UINT32			word;
+}	CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
+
+
+//
+// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register
+//
+#define WMM_TXOP0_CFG    0x0220
+typedef	union	_AC_TXOP_CSR0_STRUC	{
+	struct	{
+	    USHORT  Ac0Txop;        // for AC_BK, in unit of 32us
+	    USHORT  Ac1Txop;        // for AC_BE, in unit of 32us
+	}	field;
+	UINT32			word;
+}	AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
+
+//
+// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register
+//
+#define WMM_TXOP1_CFG    0x0224
+typedef	union	_AC_TXOP_CSR1_STRUC	{
+	struct	{
+	    USHORT  Ac2Txop;        // for AC_VI, in unit of 32us
+	    USHORT  Ac3Txop;        // for AC_VO, in unit of 32us
+	}	field;
+	UINT32			word;
+}	AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
+
+
+#define RINGREG_DIFF			0x10
+#define GPIO_CTRL_CFG    0x0228	//MAC_CSR13
+#define MCU_CMD_CFG    0x022c
+#define TX_BASE_PTR0     0x0230	//AC_BK base address
+#define TX_MAX_CNT0      0x0234
+#define TX_CTX_IDX0       0x0238
+#define TX_DTX_IDX0      0x023c
+#define TX_BASE_PTR1     0x0240		//AC_BE base address
+#define TX_MAX_CNT1      0x0244
+#define TX_CTX_IDX1       0x0248
+#define TX_DTX_IDX1      0x024c
+#define TX_BASE_PTR2     0x0250		//AC_VI base address
+#define TX_MAX_CNT2      0x0254
+#define TX_CTX_IDX2       0x0258
+#define TX_DTX_IDX2      0x025c
+#define TX_BASE_PTR3     0x0260		//AC_VO base address
+#define TX_MAX_CNT3      0x0264
+#define TX_CTX_IDX3       0x0268
+#define TX_DTX_IDX3      0x026c
+#define TX_BASE_PTR4     0x0270		//HCCA base address
+#define TX_MAX_CNT4      0x0274
+#define TX_CTX_IDX4       0x0278
+#define TX_DTX_IDX4      0x027c
+#define TX_BASE_PTR5     0x0280		//MGMT base address
+#define  TX_MAX_CNT5     0x0284
+#define TX_CTX_IDX5       0x0288
+#define TX_DTX_IDX5      0x028c
+#define TX_MGMTMAX_CNT      TX_MAX_CNT5
+#define TX_MGMTCTX_IDX       TX_CTX_IDX5
+#define TX_MGMTDTX_IDX      TX_DTX_IDX5
+#define RX_BASE_PTR     0x0290	//RX base address
+#define RX_MAX_CNT      0x0294
+#define RX_CRX_IDX       0x0298
+#define RX_DRX_IDX      0x029c
+
+
+#define USB_DMA_CFG      0x02a0
+typedef	union	_USB_DMA_CFG_STRUC	{
+	struct	{
+	    UINT32  RxBulkAggTOut:8;        //Rx Bulk Aggregation TimeOut  in unit of 33ns
+	    UINT32  RxBulkAggLmt:8;        //Rx Bulk Aggregation Limit  in unit of 256 bytes
+	    UINT32  phyclear:1;			//phy watch dog enable. write 1
+	    UINT32  rsv:2;
+	    UINT32  TxClear:1;        //Clear USB DMA TX path
+	    UINT32  TxopHalt:1;        //Halt TXOP count down when TX buffer is full.
+	    UINT32  RxBulkAggEn:1;        //Enable Rx Bulk Aggregation
+	    UINT32  RxBulkEn:1;        //Enable USB DMA Rx
+	    UINT32  TxBulkEn:1;        //Enable USB DMA Tx
+	    UINT32  EpoutValid:6;        //OUT endpoint data valid
+	    UINT32  RxBusy:1;        //USB DMA RX FSM busy
+	    UINT32  TxBusy:1;		//USB DMA TX FSM busy
+	}	field;
+	UINT32			word;
+}	USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
+
+
+//
+//  3  PBF  registers
+//
+//
+// Most are for debug. Driver doesn't touch PBF register.
+#define PBF_SYS_CTRL	 0x0400
+#define PBF_CFG                 0x0408
+#define PBF_MAX_PCNT	 0x040C
+#define PBF_CTRL		0x0410
+#define PBF_INT_STA	 0x0414
+#define PBF_INT_ENA	 0x0418
+#define TXRXQ_PCNT	 0x0438
+#define PBF_DBG			 0x043c
+#define PBF_CAP_CTRL     0x0440
+
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+// eFuse registers
+#define EFUSE_CTRL				0x0580
+#define EFUSE_DATA0				0x0590
+#define EFUSE_DATA1				0x0594
+#define EFUSE_DATA2				0x0598
+#define EFUSE_DATA3				0x059c
+#endif // RTMP_EFUSE_SUPPORT //
+#endif // RT30xx //
+
+#define OSC_CTRL		0x5a4
+#define PCIE_PHY_TX_ATTENUATION_CTRL	0x05C8
+#define LDO_CFG0				0x05d4
+#define GPIO_SWITCH				0x05dc
+
+
+//
+//  4  MAC  registers
+//
+//
+//  4.1 MAC SYSTEM  configuration registers (offset:0x1000)
+//
+#define MAC_CSR0            0x1000
+typedef	union	_ASIC_VER_ID_STRUC	{
+	struct	{
+	    USHORT  ASICRev;        // reversion  : 0
+	    USHORT  ASICVer;        // version : 2860
+	}	field;
+	UINT32			word;
+}	ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
+#define MAC_SYS_CTRL            0x1004		//MAC_CSR1
+#define MAC_ADDR_DW0				0x1008		// MAC ADDR DW0
+#define MAC_ADDR_DW1			 0x100c		// MAC ADDR DW1
+//
+// MAC_CSR2: STA MAC register 0
+//
+typedef	union	_MAC_DW0_STRUC	{
+	struct	{
+		UCHAR		Byte0;		// MAC address byte 0
+		UCHAR		Byte1;		// MAC address byte 1
+		UCHAR		Byte2;		// MAC address byte 2
+		UCHAR		Byte3;		// MAC address byte 3
+	}	field;
+	UINT32			word;
+}	MAC_DW0_STRUC, *PMAC_DW0_STRUC;
+
+//
+// MAC_CSR3: STA MAC register 1
+//
+typedef	union	_MAC_DW1_STRUC	{
+	struct	{
+		UCHAR		Byte4;		// MAC address byte 4
+		UCHAR		Byte5;		// MAC address byte 5
+		UCHAR		U2MeMask;
+		UCHAR		Rsvd1;
+	}	field;
+	UINT32			word;
+}	MAC_DW1_STRUC, *PMAC_DW1_STRUC;
+
+#define MAC_BSSID_DW0				0x1010		// MAC BSSID DW0
+#define MAC_BSSID_DW1				0x1014		// MAC BSSID DW1
+
+//
+// MAC_CSR5: BSSID register 1
+//
+typedef	union	_MAC_CSR5_STRUC	{
+	struct	{
+		UCHAR		Byte4;		 // BSSID byte 4
+		UCHAR		Byte5;		 // BSSID byte 5
+		USHORT		BssIdMask:2; // 0: one BSSID, 10: 4 BSSID,  01: 2 BSSID , 11: 8BSSID
+		USHORT		MBssBcnNum:3;
+		USHORT		Rsvd:11;
+	}	field;
+	UINT32			word;
+}	MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
+
+#define MAX_LEN_CFG              0x1018		// rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
+#define BBP_CSR_CFG			0x101c		//
+//
+// BBP_CSR_CFG: BBP serial control register
+//
+typedef	union	_BBP_CSR_CFG_STRUC	{
+	struct	{
+		UINT32		Value:8;			// Register	value to program into BBP
+		UINT32		RegNum:8;			// Selected	BBP	register
+		UINT32		fRead:1;		    // 0: Write	BBP, 1:	Read BBP
+		UINT32		Busy:1;				// 1: ASIC is busy execute BBP programming.
+		UINT32		BBP_PAR_DUR:1;		     // 0: 4 MAC clock cycles  1: 8 MAC clock cycles
+		UINT32		BBP_RW_MODE:1;		// 0: use serial mode  1:parallel
+		UINT32		:12;
+	}	field;
+	UINT32			word;
+}	BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
+#define RF_CSR_CFG0			0x1020
+//
+// RF_CSR_CFG: RF control register
+//
+typedef	union	_RF_CSR_CFG0_STRUC	{
+	struct	{
+		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
+		UINT32		bitwidth:5;			// Selected	BBP	register
+		UINT32		StandbyMode:1;		    // 0: high when stand by 1:	low when standby
+		UINT32		Sel:1;				// 0:RF_LE0 activate  1:RF_LE1 activate
+		UINT32		Busy:1;		    // 0: idle 1: 8busy
+	}	field;
+	UINT32			word;
+}	RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
+#define RF_CSR_CFG1			0x1024
+typedef	union	_RF_CSR_CFG1_STRUC	{
+	struct	{
+		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
+		UINT32		RFGap:5;			// Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
+		UINT32		rsv:7;		    // 0: idle 1: 8busy
+	}	field;
+	UINT32			word;
+}	RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
+#define RF_CSR_CFG2			0x1028		//
+typedef	union	_RF_CSR_CFG2_STRUC	{
+	struct	{
+		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
+		UINT32		rsv:8;		    // 0: idle 1: 8busy
+	}	field;
+	UINT32			word;
+}	RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
+#define LED_CFG				0x102c		//  MAC_CSR14
+typedef	union	_LED_CFG_STRUC	{
+	struct	{
+		UINT32		OnPeriod:8;			// blinking on period unit 1ms
+		UINT32		OffPeriod:8;			// blinking off period unit 1ms
+		UINT32		SlowBlinkPeriod:6;			// slow blinking period. unit:1ms
+		UINT32		rsv:2;
+		UINT32		RLedMode:2;			// red Led Mode    0: off1: blinking upon TX2: periodic slow blinking3: always on
+		UINT32		GLedMode:2;			// green Led Mode
+		UINT32		YLedMode:2;			// yellow Led Mode
+		UINT32		LedPolar:1;			// Led Polarity.  0: active low1: active high
+		UINT32		:1;
+	}	field;
+	UINT32			word;
+}	LED_CFG_STRUC, *PLED_CFG_STRUC;
+//
+//  4.2 MAC TIMING  configuration registers (offset:0x1100)
+//
+#define XIFS_TIME_CFG             0x1100		 // MAC_CSR8  MAC_CSR9
+typedef	union	_IFS_SLOT_CFG_STRUC	{
+	struct	{
+	    UINT32  CckmSifsTime:8;        //  unit 1us. Applied after CCK RX/TX
+	    UINT32  OfdmSifsTime:8;        //  unit 1us. Applied after OFDM RX/TX
+	    UINT32  OfdmXifsTime:4;        //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
+	    UINT32  EIFS:9;        //  unit 1us
+	    UINT32  BBRxendEnable:1;        //  reference RXEND signal to begin XIFS defer
+	    UINT32  rsv:2;
+	}	field;
+	UINT32			word;
+}	IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
+
+#define BKOFF_SLOT_CFG             0x1104		 //  mac_csr9 last 8 bits
+#define NAV_TIME_CFG             0x1108		 // NAV  (MAC_CSR15)
+#define CH_TIME_CFG             0x110C			// Count as channel busy
+#define PBF_LIFE_TIMER             0x1110		 //TX/RX MPDU timestamp timer (free run)Unit: 1us
+#define BCN_TIME_CFG             0x1114		 // TXRX_CSR9
+
+#define BCN_OFFSET0				0x042C
+#define BCN_OFFSET1				0x0430
+
+//
+// BCN_TIME_CFG : Synchronization control register
+//
+typedef	union	_BCN_TIME_CFG_STRUC	{
+	struct	{
+		UINT32       BeaconInterval:16;  // in unit of 1/16 TU
+		UINT32		bTsfTicking:1;		// Enable TSF auto counting
+		UINT32		TsfSyncMode:2;		// Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+        UINT32       bTBTTEnable:1;
+		UINT32		bBeaconGen:1;		// Enable beacon generator
+        UINT32       :3;
+		UINT32		TxTimestampCompensate:8;
+	}	field;
+	UINT32			word;
+}	BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
+#define TBTT_SYNC_CFG            0x1118			// txrx_csr10
+#define TSF_TIMER_DW0             0x111C		// Local TSF timer lsb 32 bits. Read-only
+#define TSF_TIMER_DW1             0x1120		// msb 32 bits. Read-only.
+#define TBTT_TIMER		0x1124			// TImer remains till next TBTT. Read-only.  TXRX_CSR14
+#define INT_TIMER_CFG			0x1128			//
+#define INT_TIMER_EN			0x112c			//  GP-timer and pre-tbtt Int enable
+#define CH_IDLE_STA			0x1130			//  channel idle time
+#define CH_BUSY_STA			0x1134			//  channle busy time
+//
+//  4.2 MAC POWER  configuration registers (offset:0x1200)
+//
+#define MAC_STATUS_CFG             0x1200		 // old MAC_CSR12
+#define PWR_PIN_CFG             0x1204		 // old MAC_CSR12
+#define AUTO_WAKEUP_CFG             0x1208		 // old MAC_CSR10
+//
+// AUTO_WAKEUP_CFG: Manual power control / status register
+//
+typedef	union	_AUTO_WAKEUP_STRUC	{
+	struct	{
+		UINT32       AutoLeadTime:8;
+		UINT32       NumofSleepingTbtt:7;          // ForceWake has high privilege than PutToSleep when both set
+		UINT32		EnableAutoWakeup:1;	// 0:sleep, 1:awake
+		UINT32		:16;
+	}	field;
+	UINT32			word;
+}	AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
+//
+//  4.3 MAC TX  configuration registers (offset:0x1300)
+//
+
+#define EDCA_AC0_CFG	0x1300		//AC_TXOP_CSR0 0x3474
+#define EDCA_AC1_CFG	0x1304
+#define EDCA_AC2_CFG	0x1308
+#define EDCA_AC3_CFG	0x130c
+typedef	union	_EDCA_AC_CFG_STRUC	{
+	struct	{
+	    UINT32  AcTxop:8;        //  in unit of 32us
+	    UINT32  Aifsn:4;        // # of slot time
+	    UINT32  Cwmin:4;        //
+	    UINT32  Cwmax:4;        //unit power of 2
+	    UINT32  :12;       //
+	}	field;
+	UINT32			word;
+}	EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
+
+#define EDCA_TID_AC_MAP	0x1310
+#define TX_PWR_CFG_0	0x1314
+#define TX_PWR_CFG_1	0x1318
+#define TX_PWR_CFG_2	0x131C
+#define TX_PWR_CFG_3	0x1320
+#define TX_PWR_CFG_4	0x1324
+#define TX_PIN_CFG		0x1328
+#define TX_BAND_CFG	0x132c		// 0x1 use upper 20MHz. 0 juse lower 20MHz
+#define TX_SW_CFG0		0x1330
+#define TX_SW_CFG1		0x1334
+#define TX_SW_CFG2		0x1338
+#define TXOP_THRES_CFG		0x133c
+#define TXOP_CTRL_CFG		0x1340
+#define TX_RTS_CFG		0x1344
+
+typedef	union	_TX_RTS_CFG_STRUC	{
+	struct	{
+	    UINT32       AutoRtsRetryLimit:8;
+	    UINT32       RtsThres:16;    // unit:byte
+	    UINT32       RtsFbkEn:1;    // enable rts rate fallback
+	    UINT32       rsv:7;     // 1: HT non-STBC control frame enable
+	}	field;
+	UINT32			word;
+}	TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
+#define TX_TIMEOUT_CFG	0x1348
+typedef	union	_TX_TIMEOUT_CFG_STRUC	{
+	struct	{
+	    UINT32       rsv:4;
+	    UINT32       MpduLifeTime:4;    //  expiration time = 2^(9+MPDU LIFE TIME)  us
+	    UINT32       RxAckTimeout:8;	// unit:slot. Used for TX precedure
+	    UINT32       TxopTimeout:8;	//TXOP timeout value for TXOP truncation.  It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+	    UINT32       rsv2:8;     // 1: HT non-STBC control frame enable
+	}	field;
+	UINT32			word;
+}	TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
+#define TX_RTY_CFG	0x134c
+typedef	union PACKED _TX_RTY_CFG_STRUC	{
+	struct	{
+	    UINT32       ShortRtyLimit:8;	//  short retry limit
+	    UINT32       LongRtyLimit:8;	//long retry limit
+	    UINT32       LongRtyThre:12;	// Long retry threshoold
+	    UINT32       NonAggRtyMode:1;	// Non-Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
+	    UINT32       AggRtyMode:1;	// Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
+	    UINT32       TxautoFBEnable:1;    // Tx retry PHY rate auto fallback enable
+	    UINT32       rsv:1;     // 1: HT non-STBC control frame enable
+	}	field;
+	UINT32			word;
+}	TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
+#define TX_LINK_CFG	0x1350
+typedef	union	PACKED _TX_LINK_CFG_STRUC	{
+	struct PACKED {
+	    UINT32       RemoteMFBLifeTime:8;	//remote MFB life time. unit : 32us
+	    UINT32       MFBEnable:1;	//  TX apply remote MFB 1:enable
+	    UINT32       RemoteUMFSEnable:1;	//  remote unsolicit  MFB enable.  0: not apply remote remote unsolicit (MFS=7)
+	    UINT32       TxMRQEn:1;	//  MCS request TX enable
+	    UINT32       TxRDGEn:1;	// RDG TX enable
+	    UINT32       TxCFAckEn:1;	//   Piggyback CF-ACK enable
+	    UINT32       rsv:3;	//
+	    UINT32       RemotMFB:8;    //  remote MCS feedback
+	    UINT32       RemotMFS:8;	//remote MCS feedback sequence number
+	}	field;
+	UINT32			word;
+}	TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
+#define HT_FBK_CFG0	0x1354
+typedef	union PACKED _HT_FBK_CFG0_STRUC	{
+	struct	{
+	    UINT32       HTMCS0FBK:4;
+	    UINT32       HTMCS1FBK:4;
+	    UINT32       HTMCS2FBK:4;
+	    UINT32       HTMCS3FBK:4;
+	    UINT32       HTMCS4FBK:4;
+	    UINT32       HTMCS5FBK:4;
+	    UINT32       HTMCS6FBK:4;
+	    UINT32       HTMCS7FBK:4;
+	}	field;
+	UINT32			word;
+}	HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
+#define HT_FBK_CFG1	0x1358
+typedef	union	_HT_FBK_CFG1_STRUC	{
+	struct	{
+	    UINT32       HTMCS8FBK:4;
+	    UINT32       HTMCS9FBK:4;
+	    UINT32       HTMCS10FBK:4;
+	    UINT32       HTMCS11FBK:4;
+	    UINT32       HTMCS12FBK:4;
+	    UINT32       HTMCS13FBK:4;
+	    UINT32       HTMCS14FBK:4;
+	    UINT32       HTMCS15FBK:4;
+	}	field;
+	UINT32			word;
+}	HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
+#define LG_FBK_CFG0	0x135c
+typedef	union	_LG_FBK_CFG0_STRUC	{
+	struct	{
+	    UINT32       OFDMMCS0FBK:4;	//initial value is 0
+	    UINT32       OFDMMCS1FBK:4;	//initial value is 0
+	    UINT32       OFDMMCS2FBK:4;	//initial value is 1
+	    UINT32       OFDMMCS3FBK:4;	//initial value is 2
+	    UINT32       OFDMMCS4FBK:4;	//initial value is 3
+	    UINT32       OFDMMCS5FBK:4;	//initial value is 4
+	    UINT32       OFDMMCS6FBK:4;	//initial value is 5
+	    UINT32       OFDMMCS7FBK:4;	//initial value is 6
+	}	field;
+	UINT32			word;
+}	LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
+#define LG_FBK_CFG1		0x1360
+typedef	union	_LG_FBK_CFG1_STRUC	{
+	struct	{
+	    UINT32       CCKMCS0FBK:4;	//initial value is 0
+	    UINT32       CCKMCS1FBK:4;	//initial value is 0
+	    UINT32       CCKMCS2FBK:4;	//initial value is 1
+	    UINT32       CCKMCS3FBK:4;	//initial value is 2
+	    UINT32       rsv:16;
+	}	field;
+	UINT32			word;
+}	LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
+
+
+//=======================================================
+//================ Protection Paramater================================
+//=======================================================
+#define CCK_PROT_CFG	0x1364		//CCK Protection
+#define ASIC_SHORTNAV		1
+#define ASIC_LONGNAV		2
+#define ASIC_RTS		1
+#define ASIC_CTS		2
+typedef	union	_PROT_CFG_STRUC	{
+	struct	{
+	    UINT32       ProtectRate:16;	//Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
+	    UINT32       ProtectCtrl:2;	//Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
+	    UINT32       ProtectNav:2;	//TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect,  2:LongNAVProtect, 3:rsv
+	    UINT32       TxopAllowCck:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowOfdm:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowMM20:1;	//CCK TXOP allowance. 0:disallow.
+	    UINT32       TxopAllowMM40:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowGF20:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowGF40:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       RTSThEn:1;	//RTS threshold enable on CCK TX
+	    UINT32       rsv:5;
+	}	field;
+	UINT32			word;
+}	PROT_CFG_STRUC, *PPROT_CFG_STRUC;
+
+#define OFDM_PROT_CFG	0x1368		//OFDM Protection
+#define MM20_PROT_CFG	0x136C		//MM20 Protection
+#define MM40_PROT_CFG	0x1370		//MM40 Protection
+#define GF20_PROT_CFG	0x1374		//GF20 Protection
+#define GF40_PROT_CFG	0x1378		//GR40 Protection
+#define EXP_CTS_TIME	0x137C		//
+#define EXP_ACK_TIME	0x1380		//
+
+//
+//  4.4 MAC RX configuration registers (offset:0x1400)
+//
+#define RX_FILTR_CFG	0x1400			//TXRX_CSR0
+#define AUTO_RSP_CFG	0x1404			//TXRX_CSR4
+//
+// TXRX_CSR4: Auto-Responder/
+//
+typedef union _AUTO_RSP_CFG_STRUC {
+ struct {
+     UINT32       AutoResponderEnable:1;
+     UINT32       BACAckPolicyEnable:1;    // 0:long, 1:short preamble
+     UINT32       CTS40MMode:1;  // Response CTS 40MHz duplicate mode
+     UINT32       CTS40MRef:1;  // Response CTS 40MHz duplicate mode
+     UINT32       AutoResponderPreamble:1;    // 0:long, 1:short preamble
+     UINT32       rsv:1;   // Power bit value in conrtrol frame
+     UINT32       DualCTSEn:1;   // Power bit value in conrtrol frame
+     UINT32       AckCtsPsmBit:1;   // Power bit value in conrtrol frame
+     UINT32        :24;
+ } field;
+ UINT32   word;
+} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
+
+#define LEGACY_BASIC_RATE	0x1408	//  TXRX_CSR5           0x3054
+#define HT_BASIC_RATE		0x140c
+#define HT_CTRL_CFG		0x1410
+#define SIFS_COST_CFG		0x1414
+#define RX_PARSER_CFG		0x1418	//Set NAV for all received frames
+
+//
+//  4.5 MAC Security configuration (offset:0x1500)
+//
+#define TX_SEC_CNT0		0x1500		//
+#define RX_SEC_CNT0		0x1504		//
+#define CCMP_FC_MUTE		0x1508		//
+//
+//  4.6 HCCA/PSMP (offset:0x1600)
+//
+#define TXOP_HLDR_ADDR0		0x1600
+#define TXOP_HLDR_ADDR1		0x1604
+#define TXOP_HLDR_ET		0x1608
+#define QOS_CFPOLL_RA_DW0		0x160c
+#define QOS_CFPOLL_A1_DW1		0x1610
+#define QOS_CFPOLL_QC		0x1614
+//
+//  4.7 MAC Statistis registers (offset:0x1700)
+//
+#define RX_STA_CNT0		0x1700		//
+#define RX_STA_CNT1		0x1704		//
+#define RX_STA_CNT2		0x1708		//
+
+//
+// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count
+//
+typedef	union	_RX_STA_CNT0_STRUC	{
+	struct	{
+	    USHORT  CrcErr;
+	    USHORT  PhyErr;
+	}	field;
+	UINT32			word;
+}	RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
+
+//
+// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count
+//
+typedef	union	_RX_STA_CNT1_STRUC	{
+	struct	{
+	    USHORT  FalseCca;
+	    USHORT  PlcpErr;
+	}	field;
+	UINT32			word;
+}	RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
+
+//
+// RX_STA_CNT2_STRUC:
+//
+typedef	union	_RX_STA_CNT2_STRUC	{
+	struct	{
+	    USHORT  RxDupliCount;
+	    USHORT  RxFifoOverflowCount;
+	}	field;
+	UINT32			word;
+}	RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
+#define TX_STA_CNT0		0x170C		//
+//
+// STA_CSR3: TX Beacon count
+//
+typedef	union	_TX_STA_CNT0_STRUC	{
+	struct	{
+	    USHORT  TxFailCount;
+	    USHORT  TxBeaconCount;
+	}	field;
+	UINT32			word;
+}	TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
+#define TX_STA_CNT1		0x1710		//
+//
+// TX_STA_CNT1: TX tx count
+//
+typedef	union	_TX_STA_CNT1_STRUC	{
+	struct	{
+	    USHORT  TxSuccess;
+	    USHORT  TxRetransmit;
+	}	field;
+	UINT32			word;
+}	TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
+#define TX_STA_CNT2		0x1714		//
+//
+// TX_STA_CNT2: TX tx count
+//
+typedef	union	_TX_STA_CNT2_STRUC	{
+	struct	{
+	    USHORT  TxZeroLenCount;
+	    USHORT  TxUnderFlowCount;
+	}	field;
+	UINT32			word;
+}	TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
+#define TX_STA_FIFO		0x1718		//
+//
+// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register
+//
+typedef	union PACKED _TX_STA_FIFO_STRUC	{
+	struct	{
+		UINT32		bValid:1;   // 1:This register contains a valid TX result
+		UINT32		PidType:4;
+		UINT32		TxSuccess:1;   // Tx No retry success
+		UINT32		TxAggre:1;    // Tx Retry Success
+		UINT32		TxAckRequired:1;    // Tx fail
+		UINT32		wcid:8;		//wireless client index
+//		UINT32		SuccessRate:16;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+		UINT32		SuccessRate:13;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+		UINT32		TxBF:1;
+		UINT32		Reserve:2;
+	}	field;
+	UINT32			word;
+}	TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
+// Debug counter
+#define TX_AGG_CNT	0x171c
+typedef	union	_TX_AGG_CNT_STRUC	{
+	struct	{
+	    USHORT  NonAggTxCount;
+	    USHORT  AggTxCount;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
+// Debug counter
+#define TX_AGG_CNT0	0x1720
+typedef	union	_TX_AGG_CNT0_STRUC	{
+	struct	{
+	    USHORT  AggSize1Count;
+	    USHORT  AggSize2Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
+// Debug counter
+#define TX_AGG_CNT1	0x1724
+typedef	union	_TX_AGG_CNT1_STRUC	{
+	struct	{
+	    USHORT  AggSize3Count;
+	    USHORT  AggSize4Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
+#define TX_AGG_CNT2	0x1728
+typedef	union	_TX_AGG_CNT2_STRUC	{
+	struct	{
+	    USHORT  AggSize5Count;
+	    USHORT  AggSize6Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
+// Debug counter
+#define TX_AGG_CNT3	0x172c
+typedef	union	_TX_AGG_CNT3_STRUC	{
+	struct	{
+	    USHORT  AggSize7Count;
+	    USHORT  AggSize8Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
+// Debug counter
+#define TX_AGG_CNT4	0x1730
+typedef	union	_TX_AGG_CNT4_STRUC	{
+	struct	{
+	    USHORT  AggSize9Count;
+	    USHORT  AggSize10Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
+#define TX_AGG_CNT5	0x1734
+typedef	union	_TX_AGG_CNT5_STRUC	{
+	struct	{
+	    USHORT  AggSize11Count;
+	    USHORT  AggSize12Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
+#define TX_AGG_CNT6		0x1738
+typedef	union	_TX_AGG_CNT6_STRUC	{
+	struct	{
+	    USHORT  AggSize13Count;
+	    USHORT  AggSize14Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
+#define TX_AGG_CNT7		0x173c
+typedef	union	_TX_AGG_CNT7_STRUC	{
+	struct	{
+	    USHORT  AggSize15Count;
+	    USHORT  AggSize16Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
+#define MPDU_DENSITY_CNT		0x1740
+typedef	union	_MPDU_DEN_CNT_STRUC	{
+	struct	{
+	    USHORT  TXZeroDelCount;	//TX zero length delimiter count
+	    USHORT  RXZeroDelCount;	//RX zero length delimiter count
+	}	field;
+	UINT32			word;
+}	MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
+//
+// TXRX control registers - base address 0x3000
+//
+// rt2860b  UNKNOWN reg use R/O Reg Addr 0x77d0 first..
+#define TXRX_CSR1           0x77d0
+
+//
+// Security key table memory, base address = 0x1000
+//
+#define MAC_WCID_BASE		0x1800 //8-bytes(use only 6-bytes) * 256 entry =
+#define HW_WCID_ENTRY_SIZE   8
+#define PAIRWISE_KEY_TABLE_BASE     0x4000      // 32-byte * 256-entry =  -byte
+#define HW_KEY_ENTRY_SIZE           0x20
+#define PAIRWISE_IVEIV_TABLE_BASE     0x6000      // 8-byte * 256-entry =  -byte
+#define MAC_IVEIV_TABLE_BASE     0x6000      // 8-byte * 256-entry =  -byte
+#define HW_IVEIV_ENTRY_SIZE   8
+#define MAC_WCID_ATTRIBUTE_BASE     0x6800      // 4-byte * 256-entry =  -byte
+#define HW_WCID_ATTRI_SIZE   4
+#define WCID_RESERVED			0x6bfc
+#define SHARED_KEY_TABLE_BASE       0x6c00      // 32-byte * 16-entry = 512-byte
+#define SHARED_KEY_MODE_BASE       0x7000      // 32-byte * 16-entry = 512-byte
+#define HW_SHARED_KEY_MODE_SIZE   4
+#define SHAREDKEYTABLE			0
+#define PAIRWISEKEYTABLE			1
+
+
+typedef	union	_SHAREDKEY_MODE_STRUC	{
+	struct	{
+		UINT32       Bss0Key0CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key1CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key2CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key3CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key0CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key1CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key2CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key3CipherAlg:3;
+		UINT32       :1;
+	}	field;
+	UINT32			word;
+}	SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
+// 64-entry for pairwise key table
+typedef struct _HW_WCID_ENTRY {  // 8-byte per entry
+    UCHAR   Address[6];
+    UCHAR   Rsv[2];
+} HW_WCID_ENTRY, PHW_WCID_ENTRY;
+
+
+// =================================================================================
+// WCID  format
+// =================================================================================
+//7.1	WCID  ENTRY  format  : 8bytes
+typedef	struct	_WCID_ENTRY_STRUC {
+	UCHAR		RXBABitmap7;    // bit0 for TID8, bit7 for TID 15
+	UCHAR		RXBABitmap0;    // bit0 for TID0, bit7 for TID 7
+	UCHAR		MAC[6];	// 0 for shared key table.  1 for pairwise key table
+}	WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC;
+
+//8.1.1	SECURITY  KEY  format  : 8DW
+// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table
+typedef struct _HW_KEY_ENTRY {          // 32-byte per entry
+    UCHAR   Key[16];
+    UCHAR   TxMic[8];
+    UCHAR   RxMic[8];
+} HW_KEY_ENTRY, *PHW_KEY_ENTRY;
+
+//8.1.2	IV/EIV  format  : 2DW
+
+//8.1.3	RX attribute entry format  : 1DW
+typedef	struct	_MAC_ATTRIBUTE_STRUC {
+	UINT32		KeyTab:1;	// 0 for shared key table.  1 for pairwise key table
+	UINT32		PairKeyMode:3;
+	UINT32		BSSIDIdx:3; //multipleBSS index for the WCID
+	UINT32		RXWIUDF:3;
+	UINT32		rsv:22;
+}	MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
+
+
+// =================================================================================
+// HOST-MCU communication data structure
+// =================================================================================
+
+//
+// H2M_MAILBOX_CSR: Host-to-MCU Mailbox
+//
+typedef union  _H2M_MAILBOX_STRUC {
+    struct {
+        UINT32       LowByte:8;
+        UINT32       HighByte:8;
+        UINT32       CmdToken:8;
+        UINT32       Owner:8;
+    }   field;
+    UINT32           word;
+} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
+
+//
+// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication
+//
+typedef union _M2H_CMD_DONE_STRUC {
+    struct  {
+        UINT32       CmdToken0;
+        UINT32       CmdToken1;
+        UINT32       CmdToken2;
+        UINT32       CmdToken3;
+    } field;
+    UINT32           word;
+} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
+
+
+//NAV_TIME_CFG :NAV
+typedef	union	_NAV_TIME_CFG_STRUC	{
+	struct	{
+		UCHAR		Sifs;               // in unit of 1-us
+		UCHAR       SlotTime;    // in unit of 1-us
+		USHORT		Eifs:9;               // in unit of 1-us
+		USHORT		ZeroSifs:1;               // Applied zero SIFS timer after OFDM RX 0: disable
+		USHORT		rsv:6;
+	}	field;
+	UINT32			word;
+}	NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
+
+
+//
+// RX_FILTR_CFG:  /RX configuration register
+//
+typedef	union	_RX_FILTR_CFG_STRUC	{
+	struct	{
+		UINT32		DropCRCErr:1;		// Drop CRC error
+		UINT32		DropPhyErr:1;		// Drop physical error
+		UINT32		DropNotToMe:1;		// Drop not to me unicast frame
+		UINT32		DropNotMyBSSID:1;			// Drop fram ToDs bit is true
+
+		UINT32		DropVerErr:1;	    // Drop version error frame
+		UINT32		DropMcast:1;		// Drop multicast frames
+		UINT32		DropBcast:1;		// Drop broadcast frames
+		UINT32		DropDuplicate:1;		// Drop duplicate frame
+
+		UINT32		DropCFEndAck:1;		// Drop Ps-Poll
+		UINT32		DropCFEnd:1;		// Drop Ps-Poll
+		UINT32		DropAck:1;		// Drop Ps-Poll
+		UINT32		DropCts:1;		// Drop Ps-Poll
+
+		UINT32		DropRts:1;		// Drop Ps-Poll
+		UINT32		DropPsPoll:1;		// Drop Ps-Poll
+		UINT32		DropBA:1;		//
+		UINT32		DropBAR:1;       //
+
+		UINT32		DropRsvCntlType:1;
+		UINT32		:15;
+	}	field;
+	UINT32			word;
+}	RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
+
+
+
+
+//
+// PHY_CSR4: RF serial control register
+//
+typedef	union	_PHY_CSR4_STRUC	{
+	struct	{
+		UINT32		RFRegValue:24;		// Register	value (include register	id)	serial out to RF/IF	chip.
+		UINT32		NumberOfBits:5;		// Number of bits used in RFRegValue (I:20,	RFMD:22)
+		UINT32		IFSelect:1;			// 1: select IF	to program,	0: select RF to	program
+		UINT32		PLL_LD:1;			// RF PLL_LD status
+		UINT32		Busy:1;				// 1: ASIC is busy execute RF programming.
+	}	field;
+	UINT32			word;
+}	PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
+
+
+//
+// SEC_CSR5: shared key table security mode register
+//
+typedef	union	_SEC_CSR5_STRUC	{
+	struct	{
+        UINT32       Bss2Key0CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key1CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key2CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key3CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key0CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key1CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key2CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key3CipherAlg:3;
+        UINT32       :1;
+	}	field;
+	UINT32			word;
+}	SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
+
+
+//
+// HOST_CMD_CSR: For HOST to interrupt embedded processor
+//
+typedef	union	_HOST_CMD_CSR_STRUC	{
+	struct	{
+	    UINT32   HostCommand:8;
+	    UINT32   Rsv:24;
+	}	field;
+	UINT32			word;
+}	HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
+
+
+//
+// AIFSN_CSR: AIFSN for each EDCA AC
+//
+
+
+
+//
+// E2PROM_CSR: EEPROM control register
+//
+typedef	union	_E2PROM_CSR_STRUC	{
+	struct	{
+		UINT32		Reload:1;		// Reload EEPROM content, write one to reload, self-cleared.
+		UINT32		EepromSK:1;
+		UINT32		EepromCS:1;
+		UINT32		EepromDI:1;
+		UINT32		EepromDO:1;
+		UINT32		Type:1;			// 1: 93C46, 0:93C66
+		UINT32       LoadStatus:1;   // 1:loading, 0:done
+		UINT32		Rsvd:25;
+	}	field;
+	UINT32			word;
+}	E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
+
+//
+// QOS_CSR0: TXOP holder address0 register
+//
+typedef	union	_QOS_CSR0_STRUC	{
+	struct	{
+		UCHAR		Byte0;		// MAC address byte 0
+		UCHAR		Byte1;		// MAC address byte 1
+		UCHAR		Byte2;		// MAC address byte 2
+		UCHAR		Byte3;		// MAC address byte 3
+	}	field;
+	UINT32			word;
+}	QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
+
+//
+// QOS_CSR1: TXOP holder address1 register
+//
+typedef	union	_QOS_CSR1_STRUC	{
+	struct	{
+		UCHAR		Byte4;		// MAC address byte 4
+		UCHAR		Byte5;		// MAC address byte 5
+		UCHAR		Rsvd0;
+		UCHAR		Rsvd1;
+	}	field;
+	UINT32			word;
+}	QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
+
+#define	RF_CSR_CFG	0x500
+typedef	union	_RF_CSR_CFG_STRUC	{
+	struct	{
+		UINT	RF_CSR_DATA:8;			// DATA
+		UINT	TESTCSR_RFACC_REGNUM:5;	// RF register ID
+		UINT	Rsvd2:3;				// Reserved
+		UINT	RF_CSR_WR:1;			// 0: read  1: write
+		UINT	RF_CSR_KICK:1;			// kick RF register read/write
+		UINT	Rsvd1:14;				// Reserved
+	}	field;
+	UINT	word;
+}	RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
+
+
+//
+// Other on-chip shared memory space, base = 0x2000
+//
+
+// CIS space - base address = 0x2000
+#define HW_CIS_BASE             0x2000
+
+// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function.
+#define HW_CS_CTS_BASE			0x7700
+// DFS CTS frame base address. It's where mac stores CTS frame for DFS.
+#define HW_DFS_CTS_BASE			0x7780
+#define HW_CTS_FRAME_SIZE		0x80
+
+// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes
+// to save debugging settings
+#define HW_DEBUG_SETTING_BASE   0x77f0  // 0x77f0~0x77ff total 16 bytes
+#define HW_DEBUG_SETTING_BASE2   0x7770  // 0x77f0~0x77ff total 16 bytes
+
+// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon
+// Three section discontinue memory segments will be used.
+// 1. The original region for BCN 0~3
+// 2. Extract memory from FCE table for BCN 4~5
+// 3. Extract memory from Pair-wise key table for BCN 6~7
+//	  It occupied those memory of wcid 238~253 for BCN 6
+//						      and wcid 222~237 for BCN 7
+#define HW_BEACON_MAX_SIZE      0x1000 /* unit: byte */
+#define HW_BEACON_BASE0         0x7800
+#define HW_BEACON_BASE1         0x7A00
+#define HW_BEACON_BASE2         0x7C00
+#define HW_BEACON_BASE3         0x7E00
+#define HW_BEACON_BASE4         0x7200
+#define HW_BEACON_BASE5         0x7400
+#define HW_BEACON_BASE6         0x5DC0
+#define HW_BEACON_BASE7         0x5BC0
+
+#define HW_BEACON_MAX_COUNT     8
+#define HW_BEACON_OFFSET		0x0200
+#define HW_BEACON_CONTENT_LEN	(HW_BEACON_OFFSET - TXWI_SIZE)
+
+// HOST-MCU shared memory - base address = 0x2100
+#define HOST_CMD_CSR		0x404
+#define H2M_MAILBOX_CSR         0x7010
+#define H2M_MAILBOX_CID         0x7014
+#define H2M_MAILBOX_STATUS      0x701c
+#define H2M_INT_SRC             0x7024
+#define H2M_BBP_AGENT           0x7028
+#define M2H_CMD_DONE_CSR        0x000c
+#define MCU_TXOP_ARRAY_BASE     0x000c   // TODO: to be provided by Albert
+#define MCU_TXOP_ENTRY_SIZE     32       // TODO: to be provided by Albert
+#define MAX_NUM_OF_TXOP_ENTRY   16       // TODO: must be same with 8051 firmware
+#define MCU_MBOX_VERSION        0x01     // TODO: to be confirmed by Albert
+#define MCU_MBOX_VERSION_OFFSET 5        // TODO: to be provided by Albert
+
+//
+// Host DMA registers - base address 0x200 .  TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT,
+//
+//
+//  DMA RING DESCRIPTOR
+//
+#define E2PROM_CSR          0x0004
+#define IO_CNTL_CSR         0x77d0
+
+
+
+// ================================================================
+// Tx /	Rx / Mgmt ring descriptor definition
+// ================================================================
+
+// the following PID values are used to mark outgoing frame type in TXD->PID so that
+// proper TX statistics can be collected based on these categories
+// b3-2 of PID field -
+#define PID_MGMT			0x05
+#define PID_BEACON			0x0c
+#define PID_DATA_NORMALUCAST		0x02
+#define PID_DATA_AMPDU		0x04
+#define PID_DATA_NO_ACK		0x08
+#define PID_DATA_NOT_NORM_ACK		0x03
+// value domain of pTxD->HostQId (4-bit: 0~15)
+#define QID_AC_BK               1   // meet ACI definition in 802.11e
+#define QID_AC_BE               0   // meet ACI definition in 802.11e
+#define QID_AC_VI               2
+#define QID_AC_VO               3
+#define QID_HCCA                4
+#define NUM_OF_TX_RING          4
+#define QID_MGMT                13
+#define QID_RX                  14
+#define QID_OTHER               15
+
+#endif // __RTMP_MAC_H__ //
diff --git a/drivers/staging/rt2860/chip/rtmp_phy.h b/drivers/staging/rt2860/chip/rtmp_phy.h
new file mode 100644
index 0000000..b3326c6
--- /dev/null
+++ b/drivers/staging/rt2860/chip/rtmp_phy.h
@@ -0,0 +1,405 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_phy.h
+
+	Abstract:
+	Ralink Wireless Chip PHY(BBP/RF) related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+*/
+
+#ifndef __RTMP_PHY_H__
+#define __RTMP_PHY_H__
+
+
+/*
+	RF sections
+*/
+#define RF_R00			0
+#define RF_R01			1
+#define RF_R02			2
+#define RF_R03			3
+#define RF_R04			4
+#define RF_R05			5
+#define RF_R06			6
+#define RF_R07			7
+#define RF_R08			8
+#define RF_R09			9
+#define RF_R10			10
+#define RF_R11			11
+#define RF_R12			12
+#define RF_R13			13
+#define RF_R14			14
+#define RF_R15			15
+#define RF_R16			16
+#define RF_R17			17
+#define RF_R18			18
+#define RF_R19			19
+#define RF_R20			20
+#define RF_R21			21
+#define RF_R22			22
+#define RF_R23			23
+#define RF_R24			24
+#define RF_R25			25
+#define RF_R26			26
+#define RF_R27			27
+#define RF_R28			28
+#define RF_R29			29
+#define RF_R30			30
+#define RF_R31			31
+
+
+// value domain of pAd->RfIcType
+#define RFIC_2820                   1       // 2.4G 2T3R
+#define RFIC_2850                   2       // 2.4G/5G 2T3R
+#define RFIC_2720                   3       // 2.4G 1T2R
+#define RFIC_2750                   4       // 2.4G/5G 1T2R
+#define RFIC_3020                   5       // 2.4G 1T1R
+#define RFIC_2020                   6       // 2.4G B/G
+#define RFIC_3021                   7       // 2.4G 1T2R
+#define RFIC_3022                   8       // 2.4G 2T2R
+#define RFIC_3052                   9       // 2.4G/5G 2T2R
+
+/*
+	BBP sections
+*/
+#define BBP_R0			0  // version
+#define BBP_R1			1  // TSSI
+#define BBP_R2			2  // TX configure
+#define BBP_R3			3
+#define BBP_R4			4
+#define BBP_R5			5
+#define BBP_R6			6
+#define BBP_R14			14 // RX configure
+#define BBP_R16			16
+#define BBP_R17			17 // RX sensibility
+#define BBP_R18			18
+#define BBP_R21			21
+#define BBP_R22			22
+#define BBP_R24			24
+#define BBP_R25			25
+#define BBP_R26			26
+#define BBP_R27			27
+#define BBP_R31			31
+#define BBP_R49			49 //TSSI
+#define BBP_R50			50
+#define BBP_R51			51
+#define BBP_R52			52
+#define BBP_R55			55
+#define BBP_R62			62 // Rx SQ0 Threshold HIGH
+#define BBP_R63			63
+#define BBP_R64			64
+#define BBP_R65			65
+#define BBP_R66			66
+#define BBP_R67			67
+#define BBP_R68			68
+#define BBP_R69			69
+#define BBP_R70			70 // Rx AGC SQ CCK Xcorr threshold
+#define BBP_R73			73
+#define BBP_R75			75
+#define BBP_R77			77
+#define BBP_R78			78
+#define BBP_R79			79
+#define BBP_R80			80
+#define BBP_R81			81
+#define BBP_R82			82
+#define BBP_R83			83
+#define BBP_R84			84
+#define BBP_R86			86
+#define BBP_R91			91
+#define BBP_R92			92
+#define BBP_R94			94 // Tx Gain Control
+#define BBP_R103		103
+#define BBP_R105		105
+#define BBP_R106		106
+#define BBP_R113		113
+#define BBP_R114		114
+#define BBP_R115		115
+#define BBP_R116		116
+#define BBP_R117		117
+#define BBP_R118		118
+#define BBP_R119		119
+#define BBP_R120		120
+#define BBP_R121		121
+#define BBP_R122		122
+#define BBP_R123		123
+#ifdef RT30xx
+#define BBP_R138		138 // add by johnli, RF power sequence setup, ADC dynamic on/off control
+#endif // RT30xx //
+
+#define BBPR94_DEFAULT	0x06 // Add 1 value will gain 1db
+
+//
+// BBP & RF are using indirect access. Before write any value into it.
+// We have to make sure there is no outstanding command pending via checking busy bit.
+//
+#define MAX_BUSY_COUNT  100         // Number of retry before failing access BBP & RF indirect register
+
+//#define PHY_TR_SWITCH_TIME          5  // usec
+
+//#define BBP_R17_LOW_SENSIBILITY     0x50
+//#define BBP_R17_MID_SENSIBILITY     0x41
+//#define BBP_R17_DYNAMIC_UP_BOUND    0x40
+
+#define RSSI_FOR_VERY_LOW_SENSIBILITY   -35
+#define RSSI_FOR_LOW_SENSIBILITY		-58
+#define RSSI_FOR_MID_LOW_SENSIBILITY	-80
+#define RSSI_FOR_MID_SENSIBILITY		-90
+
+/*****************************************************************************
+	RF register Read/Write marco definition
+ *****************************************************************************/
+#ifdef RTMP_MAC_PCI
+#define RTMP_RF_IO_WRITE32(_A, _V)                  \
+{											\
+	if ((_A)->bPCIclkOff == FALSE)	                \
+	{												\
+		PHY_CSR4_STRUC  _value;                          \
+		ULONG           _busyCnt = 0;                    \
+											\
+		do {                                            \
+			RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word);  \
+			if (_value.field.Busy == IDLE)               \
+				break;                                  \
+			_busyCnt++;                                  \
+		}while (_busyCnt < MAX_BUSY_COUNT);			\
+		if(_busyCnt < MAX_BUSY_COUNT)                   \
+		{                                               \
+			RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V));          \
+		}                                               \
+	}								\
+}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+#define RTMP_RF_IO_WRITE32(_A, _V)                 RTUSBWriteRFRegister(_A, _V)
+#endif // RTMP_MAC_USB //
+
+#ifdef RT30xx
+#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)    RT30xxReadRFRegister(_A, _I, _pV)
+#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)    RT30xxWriteRFRegister(_A, _I, _V)
+#endif // RT30xx //
+
+/*****************************************************************************
+	BBP register Read/Write marco definitions.
+	we read/write the bbp value by register's ID.
+	Generate PER to test BA
+ *****************************************************************************/
+#ifdef RTMP_MAC_PCI
+/*
+	basic marco for BBP read operation.
+	_pAd: the data structure pointer of RTMP_ADAPTER
+	_bbpID : the bbp register ID
+	_pV: data pointer used to save the value of queried bbp register.
+	_bViaMCU: if we need access the bbp via the MCU.
+*/
+#define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU)			\
+	do{															\
+		BBP_CSR_CFG_STRUC  BbpCsr;								\
+		int   _busyCnt, _secCnt, _regID;						\
+																\
+		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
+		for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++)      \
+		{													\
+			RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);		\
+			if (BbpCsr.field.Busy == BUSY)                  \
+				continue;                                               \
+			BbpCsr.word = 0;                                \
+			BbpCsr.field.fRead = 1;                         \
+			BbpCsr.field.BBP_RW_MODE = 1;                         \
+			BbpCsr.field.Busy = 1;                          \
+			BbpCsr.field.RegNum = _bbpID;                       \
+			RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);     \
+			if ((_bViaMCU) == TRUE)							\
+			{													\
+				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
+				RTMPusecDelay(1000);	\
+			}							\
+			for (_secCnt=0; _secCnt<MAX_BUSY_COUNT; _secCnt++)       \
+			{                                               \
+				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
+				if (BbpCsr.field.Busy == IDLE)              \
+					break;                                  \
+			}                                               \
+			if ((BbpCsr.field.Busy == IDLE) &&              \
+				(BbpCsr.field.RegNum == _bbpID))                \
+			{                                               \
+				*(_pV) = (UCHAR)BbpCsr.field.Value;         \
+				break;                                      \
+			}                                               \
+		}                                                   \
+		if (BbpCsr.field.Busy == BUSY)                      \
+		{                                                   \
+			DBGPRINT_ERR(("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID));      \
+			*(_pV) = (_pAd)->BbpWriteLatch[_bbpID];               \
+			if ((_bViaMCU) == TRUE)				\
+			{									\
+				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);				\
+				BbpCsr.field.Busy = 0;                          \
+				RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);				\
+			}				\
+		}													\
+	}while(0)
+
+/*
+	This marco used for the BBP read operation which didn't need via MCU.
+*/
+#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)			\
+	RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
+
+/*
+	This marco used for the BBP read operation which need via MCU.
+	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
+	will use this function too and didn't access the bbp register via the MCU.
+*/
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)			\
+	do{														\
+		if ((_A)->bPCIclkOff == FALSE)							\
+		{													\
+			if ((_A)->infType == RTMP_DEV_INF_RBUS)			\
+				RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE);	\
+			else												\
+				RTMP_BBP_IO_READ8((_A), (_I), (_pV), TRUE);	\
+		}													\
+	}while(0)
+
+
+/*
+	basic marco for BBP write operation.
+	_pAd: the data structure pointer of RTMP_ADAPTER
+	_bbpID : the bbp register ID
+	_pV: data used to save the value of queried bbp register.
+	_bViaMCU: if we need access the bbp via the MCU.
+*/
+#define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU)			\
+	do{															\
+		BBP_CSR_CFG_STRUC  BbpCsr;                             \
+		int             _busyCnt, _regID;							\
+																\
+		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
+		for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++)  \
+		{                                                   \
+			RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &BbpCsr.word);     \
+			if (BbpCsr.field.Busy == BUSY)                  \
+				continue;                                   \
+			BbpCsr.word = 0;                                \
+			BbpCsr.field.fRead = 0;                         \
+			BbpCsr.field.BBP_RW_MODE = 1;                         \
+			BbpCsr.field.Busy = 1;                          \
+			BbpCsr.field.Value = _pV;                        \
+			BbpCsr.field.RegNum = _bbpID;                       \
+			RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word);     \
+			if ((_bViaMCU) == TRUE)									\
+			{														\
+				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0);		\
+				if ((_pAd)->OpMode == OPMODE_AP)						\
+					RTMPusecDelay(1000);							\
+			}														\
+			(_pAd)->BbpWriteLatch[_bbpID] = _pV;					\
+			break;													\
+		}														\
+		if (_busyCnt == MAX_BUSY_COUNT)								\
+		{														\
+			DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID));				\
+			if((_bViaMCU) == TRUE)									\
+			{														\
+				RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word);	\
+				BbpCsr.field.Busy = 0;									\
+				RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word);	\
+			}														\
+		}														\
+	}while(0)
+
+
+/*
+	This marco used for the BBP write operation which didn't need via MCU.
+*/
+#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV)			\
+	RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
+
+/*
+	This marco used for the BBP write operation which need via MCU.
+	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
+	will use this function too and didn't access the bbp register via the MCU.
+*/
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV)			\
+	do{														\
+		if ((_A)->bPCIclkOff == FALSE)							\
+		{													\
+			if ((_A)->infType == RTMP_DEV_INF_RBUS)			\
+				RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE);	\
+			else												\
+				RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), TRUE);	\
+		}													\
+	}while(0)
+
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)   RTUSBReadBBPRegister(_A, _I, _pV)
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)   RTUSBWriteBBPRegister(_A, _I, _V)
+
+#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)			RTUSBWriteBBPRegister(_A, _I, _V)
+#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)		RTUSBReadBBPRegister(_A, _I, _pV)
+#endif // RTMP_MAC_USB //
+
+#ifdef RT30xx
+#define RTMP_ASIC_MMPS_DISABLE(_pAd)							\
+	do{															\
+		UCHAR _bbpData;											\
+		UINT32 _macData;											\
+		/* disable MMPS BBP control register */						\
+		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
+		_bbpData &= ~(0x04);	/*bit 2*/								\
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
+																\
+		/* disable MMPS MAC control register */						\
+		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
+		_macData &= ~(0x09);	/*bit 0, 3*/							\
+		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
+	}while(0)
+
+
+#define RTMP_ASIC_MMPS_ENABLE(_pAd)							\
+	do{															\
+		UCHAR _bbpData;											\
+		UINT32 _macData;											\
+		/* enable MMPS BBP control register */						\
+		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
+		_bbpData |= (0x04);	/*bit 2*/								\
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
+																\
+		/* enable MMPS MAC control register */						\
+		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
+		_macData |= (0x09);	/*bit 0, 3*/							\
+		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
+	}while(0)
+
+#endif // RT30xx //
+
+#endif // __RTMP_PHY_H__ //
diff --git a/drivers/staging/rt2860/chips/rt3070.c b/drivers/staging/rt2860/chips/rt3070.c
new file mode 100644
index 0000000..5a3e668
--- /dev/null
+++ b/drivers/staging/rt2860/chips/rt3070.c
@@ -0,0 +1,185 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rt3070.c
+
+	Abstract:
+	Specific funcitons and variables for RT3070
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifdef RT3070
+
+#include "../rt_config.h"
+
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif // RTMP_RF_RW_SUPPORT //
+
+
+VOID NICInitRT3070RFRegisters(IN PRTMP_ADAPTER pAd)
+{
+	INT i;
+	UCHAR RFValue;
+
+	// Driver must read EEPROM to get RfIcType before initial RF registers
+	// Initialize RF register to default value
+	if (IS_RT3070(pAd) || IS_RT3071(pAd))
+	{
+		// Init RF calibration
+		// Driver should toggle RF R30 bit7 before init RF registers
+		UINT32 RfReg = 0;
+		UINT32 data;
+
+		RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
+		RfReg |= 0x80;
+		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
+		RTMPusecDelay(1000);
+		RfReg &= 0x7F;
+		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
+
+		// Initialize RF register to default value
+		for (i = 0; i < NUM_RF_REG_PARMS; i++)
+		{
+			RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
+		}
+
+		// add by johnli
+		if (IS_RT3070(pAd))
+		{
+			//
+			// The DAC issue(LDO_CFG0) has been fixed in RT3070(F).
+			// The voltage raising patch is no longer needed for RT3070(F)
+			//
+			if ((pAd->MACVersion & 0xffff) < 0x0201)
+			{
+				//  Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate
+				RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+				data = ((data & 0xF0FFFFFF) | 0x0D000000);
+				RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+			}
+		}
+		else if (IS_RT3071(pAd))
+		{
+			// Driver should set RF R6 bit6 on before init RF registers
+			RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
+			RfReg |= 0x40;
+			RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
+
+			// init R31
+			RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
+
+			// RT3071 version E has fixed this issue
+			if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
+			{
+				// patch tx EVM issue temporarily
+				RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+				data = ((data & 0xE0FFFFFF) | 0x0D000000);
+				RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+			}
+			else
+			{
+				RTMP_IO_READ32(pAd, LDO_CFG0, &data);
+				data = ((data & 0xE0FFFFFF) | 0x01000000);
+				RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
+			}
+
+			// patch LNA_PE_G1 failed issue
+			RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
+			data &= ~(0x20);
+			RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
+		}
+
+                //For RF filter Calibration
+		RTMPFilterCalibration(pAd);
+
+		// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
+		//
+		// TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F).
+		// Raising RF voltage is no longer needed for RT3070(F)
+		//
+		if ((IS_RT3070(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0201))
+		{
+			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
+		}
+		else if ((IS_RT3071(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0211))
+		{
+			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
+		}
+
+		// set led open drain enable
+		RTUSBReadMACRegister(pAd, OPT_14, &data);
+		data |= 0x01;
+		RTUSBWriteMACRegister(pAd, OPT_14, data);
+
+		// move from RT30xxLoadRFNormalModeSetup because it's needed for both RT3070 and RT3071
+		// TX_LO1_en, RF R17 register Bit 3 to 0
+		RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
+		RFValue &= (~0x08);
+		// to fix rx long range issue
+		if (pAd->NicConfig2.field.ExternalLNAForG == 0)
+		{
+			if ((IS_RT3071(pAd) && ((pAd->MACVersion & 0xffff) >= 0x0211)) || IS_RT3070(pAd))
+			{
+				RFValue |= 0x20;
+			}
+		}
+		// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
+		if (pAd->TxMixerGain24G >= 1)
+		{
+			RFValue &= (~0x7);  // clean bit [2:0]
+			RFValue |= pAd->TxMixerGain24G;
+		}
+		RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
+
+		if (IS_RT3071(pAd))
+		{
+			// add by johnli, RF power sequence setup, load RF normal operation-mode setup
+			RT30xxLoadRFNormalModeSetup(pAd);
+		}
+		else if (IS_RT3070(pAd))
+		{
+			/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/
+			// LDORF_VC, RF R27 register Bit 2 to 0
+			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+			// TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F).
+			// Raising RF voltage is no longer needed for RT3070(F)
+			if ((pAd->MACVersion & 0xffff) < 0x0201)
+				RFValue = (RFValue & (~0x77)) | 0x3;
+			else
+				RFValue = (RFValue & (~0x77));
+			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+			/* end johnli */
+		}
+	}
+
+}
+#endif // RT3070 //
diff --git a/drivers/staging/rt2860/chips/rt30xx.c b/drivers/staging/rt2860/chips/rt30xx.c
new file mode 100644
index 0000000..fe7d8ec
--- /dev/null
+++ b/drivers/staging/rt2860/chips/rt30xx.c
@@ -0,0 +1,525 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rt30xx.c
+
+	Abstract:
+	Specific funcitons and variables for RT30xx.
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+
+#ifdef RT30xx
+
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif // RTMP_RF_RW_SUPPORT //
+
+#include "../rt_config.h"
+
+
+//
+// RF register initialization set
+//
+REG_PAIR   RT30xx_RFRegTable[] = {
+        {RF_R04,          0x40},
+        {RF_R05,          0x03},
+        {RF_R06,          0x02},
+        {RF_R07,          0x70},
+        {RF_R09,          0x0F},
+        {RF_R10,          0x41},
+        {RF_R11,          0x21},
+        {RF_R12,          0x7B},
+        {RF_R14,          0x90},
+        {RF_R15,          0x58},
+        {RF_R16,          0xB3},
+        {RF_R17,          0x92},
+        {RF_R18,          0x2C},
+        {RF_R19,          0x02},
+        {RF_R20,          0xBA},
+        {RF_R21,          0xDB},
+        {RF_R24,          0x16},
+        {RF_R25,          0x01},
+        {RF_R29,          0x1F},
+};
+
+UCHAR NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR));
+
+
+
+// Antenna divesity use GPIO3 and EESK pin for control
+// Antenna and EEPROM access are both using EESK pin,
+// Therefor we should avoid accessing EESK at the same time
+// Then restore antenna after EEPROM access
+// The original name of this function is AsicSetRxAnt(), now change to
+//VOID AsicSetRxAnt(
+VOID RT30xxSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant)
+{
+	UINT32	Value;
+	UINT32	x;
+
+	if ((pAd->EepromAccess) ||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))	||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))	||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+	{
+		return;
+	}
+
+	// the antenna selection is through firmware and MAC register(GPIO3)
+	if (Ant == 0)
+	{
+		// Main antenna
+		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0);
+
+		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+		Value &= ~(0x0808);
+		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
+	}
+	else
+	{
+		// Aux antenna
+		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0);
+		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+		Value &= ~(0x0808);
+		Value |= 0x08;
+		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
+	}
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		For RF filter calibration purpose
+
+	Arguments:
+		pAd                          Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+VOID RTMPFilterCalibration(
+	IN PRTMP_ADAPTER pAd)
+{
+	UCHAR	R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
+	UINT	loop = 0, count = 0, loopcnt = 0, ReTry = 0;
+	UCHAR	RF_R24_Value = 0;
+
+	// Give bbp filter initial value
+	pAd->Mlme.CaliBW20RfR24 = 0x1F;
+	pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
+
+	do
+	{
+		if (loop == 1)	//BandWidth = 40 MHz
+		{
+			// Write 0x27 to RF_R24 to program filter
+			RF_R24_Value = 0x27;
+			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+			if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
+				FilterTarget = 0x15;
+			else
+				FilterTarget = 0x19;
+
+			// when calibrate BW40, BBP mask must set to BW40.
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+			BBPValue&= (~0x18);
+			BBPValue|= (0x10);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+			// set to BW40
+			RT30xxReadRFRegister(pAd, RF_R31, &value);
+			value |= 0x20;
+			RT30xxWriteRFRegister(pAd, RF_R31, value);
+		}
+		else			//BandWidth = 20 MHz
+		{
+			// Write 0x07 to RF_R24 to program filter
+			RF_R24_Value = 0x07;
+			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+			if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd))
+				FilterTarget = 0x13;
+			else
+				FilterTarget = 0x16;
+
+			// set to BW20
+			RT30xxReadRFRegister(pAd, RF_R31, &value);
+			value &= (~0x20);
+			RT30xxWriteRFRegister(pAd, RF_R31, value);
+		}
+
+		// Write 0x01 to RF_R22 to enable baseband loopback mode
+		RT30xxReadRFRegister(pAd, RF_R22, &value);
+		value |= 0x01;
+		RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+		// Write 0x00 to BBP_R24 to set power & frequency of passband test tone
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+		do
+		{
+			// Write 0x90 to BBP_R25 to transmit test tone
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+			RTMPusecDelay(1000);
+			// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+			R55x = value & 0xFF;
+
+		} while ((ReTry++ < 100) && (R55x == 0));
+
+		// Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
+
+		while(TRUE)
+		{
+			// Write 0x90 to BBP_R25 to transmit test tone
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+			//We need to wait for calibration
+			RTMPusecDelay(1000);
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+			value &= 0xFF;
+			if ((R55x - value) < FilterTarget)
+			{
+				RF_R24_Value ++;
+			}
+			else if ((R55x - value) == FilterTarget)
+			{
+				RF_R24_Value ++;
+				count ++;
+			}
+			else
+			{
+				break;
+			}
+
+			// prevent infinite loop cause driver hang.
+			if (loopcnt++ > 100)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
+				break;
+			}
+
+			// Write RF_R24 to program filter
+			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+		}
+
+		if (count > 0)
+		{
+			RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
+		}
+
+		// Store for future usage
+		if (loopcnt < 100)
+		{
+			if (loop++ == 0)
+			{
+				//BandWidth = 20 MHz
+				pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
+			}
+			else
+			{
+				//BandWidth = 40 MHz
+				pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
+				break;
+			}
+		}
+		else
+			break;
+
+		RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+
+		// reset count
+		count = 0;
+	} while(TRUE);
+
+	//
+	// Set back to initial state
+	//
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+	RT30xxReadRFRegister(pAd, RF_R22, &value);
+	value &= ~(0x01);
+	RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+	// set BBP back to BW20
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+	BBPValue&= (~0x18);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
+}
+
+
+// add by johnli, RF power sequence setup
+/*
+	==========================================================================
+	Description:
+
+	Load RF normal operation-mode setup
+
+	==========================================================================
+ */
+VOID RT30xxLoadRFNormalModeSetup(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UCHAR RFValue;
+
+	// RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
+	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+	RFValue = (RFValue & (~0x0C)) | 0x31;
+	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+	// TX_LO2_en, RF R15 register Bit 3 to 0
+	RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
+	RFValue &= (~0x08);
+	RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
+
+	/* move to NICInitRT30xxRFRegisters
+	// TX_LO1_en, RF R17 register Bit 3 to 0
+	RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
+	RFValue &= (~0x08);
+	// to fix rx long range issue
+	if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
+	{
+		RFValue |= 0x20;
+	}
+	// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
+	if (pAd->TxMixerGain24G >= 2)
+	{
+		RFValue &= (~0x7);  // clean bit [2:0]
+		RFValue |= pAd->TxMixerGain24G;
+	}
+	RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
+	*/
+
+	// RX_LO1_en, RF R20 register Bit 3 to 0
+	RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
+	RFValue &= (~0x08);
+	RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
+
+	// RX_LO2_en, RF R21 register Bit 3 to 0
+	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+	RFValue &= (~0x08);
+	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+	/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/
+	// LDORF_VC, RF R27 register Bit 2 to 0
+	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+	// TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F).
+	// Raising RF voltage is no longer needed for RT3070(F)
+	if (IS_RT3090(pAd))	// RT309x and RT3071/72
+	{
+		if ((pAd->MACVersion & 0xffff) < 0x0211)
+			RFValue = (RFValue & (~0x77)) | 0x3;
+		else
+			RFValue = (RFValue & (~0x77));
+		RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+	}
+	/* end johnli */
+}
+
+/*
+	==========================================================================
+	Description:
+
+	Load RF sleep-mode setup
+
+	==========================================================================
+ */
+VOID RT30xxLoadRFSleepModeSetup(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UCHAR RFValue;
+	UINT32 MACValue;
+
+
+#ifdef RTMP_MAC_USB
+	if(!IS_RT3572(pAd))
+#endif // RTMP_MAC_USB //
+	{
+		// RF_BLOCK_en. RF R1 register Bit 0 to 0
+		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+		RFValue &= (~0x01);
+		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+		// VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
+		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+		RFValue &= (~0x30);
+		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+		// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
+		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+		RFValue &= (~0x0E);
+		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+		// RX_CTB_en, RF R21 register Bit 7 to 0
+		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+		RFValue &= (~0x80);
+		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+	}
+
+	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
+		IS_RT3572(pAd) ||
+		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
+	{
+#ifdef RTMP_MAC_USB
+		if (!IS_RT3572(pAd))
+#endif // RTMP_MAC_USB //
+		{
+			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+			RFValue |= 0x77;
+			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+		}
+
+		RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+		MACValue |= 0x1D000000;
+		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	Reverse RF sleep-mode setup
+
+	==========================================================================
+ */
+VOID RT30xxReverseRFSleepModeSetup(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UCHAR RFValue;
+	UINT32 MACValue;
+
+#ifdef RTMP_MAC_USB
+	if(!IS_RT3572(pAd))
+#endif // RTMP_MAC_USB //
+	{
+		// RF_BLOCK_en, RF R1 register Bit 0 to 1
+		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+		RFValue |= 0x01;
+		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+		// VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
+		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+		RFValue |= 0x30;
+		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+		// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
+		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+		RFValue |= 0x0E;
+		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+		// RX_CTB_en, RF R21 register Bit 7 to 1
+		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+		RFValue |= 0x80;
+		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+	}
+
+	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
+		IS_RT3572(pAd) ||
+		IS_RT3390(pAd) ||
+		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
+	{
+#ifdef RTMP_MAC_USB
+		if (!IS_RT3572(pAd))
+#endif // RTMP_MAC_USB //
+		{
+			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+			if ((pAd->MACVersion & 0xffff) < 0x0211)
+				RFValue = (RFValue & (~0x77)) | 0x3;
+			else
+				RFValue = (RFValue & (~0x77));
+			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+		}
+
+		// RT3071 version E has fixed this issue
+		if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
+		{
+			// patch tx EVM issue temporarily
+			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+			MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
+			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+		}
+		else
+		{
+			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+			MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
+			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+		}
+	}
+
+	if(IS_RT3572(pAd))
+		RT30xxWriteRFRegister(pAd, RF_R08, 0x80);
+}
+// end johnli
+
+VOID RT30xxHaltAction(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UINT32		TxPinCfg = 0x00050F0F;
+
+	//
+	// Turn off LNA_PE or TRSW_POL
+	//
+	if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd))
+	{
+		if ((IS_RT3071(pAd) || IS_RT3572(pAd))
+#ifdef RTMP_EFUSE_SUPPORT
+			&& (pAd->bUseEfuse)
+#endif // RTMP_EFUSE_SUPPORT //
+			)
+		{
+			TxPinCfg &= 0xFFFBF0F0; // bit18 off
+		}
+		else
+		{
+			TxPinCfg &= 0xFFFFF0F0;
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+	}
+}
+
+#endif // RT30xx //
diff --git a/drivers/staging/rt2860/chlist.h b/drivers/staging/rt2860/chlist.h
index f49a35c..9ce9154 100644
--- a/drivers/staging/rt2860/chlist.h
+++ b/drivers/staging/rt2860/chlist.h
@@ -64,1182 +64,65 @@  typedef struct _CH_REGION {
 	CH_DESP ChDesp[10];
 } CH_REGION, *PCH_REGION;
 
-static CH_REGION ChRegion[] =
-{
-		{	// Antigua and Berbuda
-			"AG",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Argentina
-			"AR",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Aruba
-			"AW",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Australia
-			"AU",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Austria
-			"AT",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, TRUE},		// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Bahamas
-			"BS",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Barbados
-			"BB",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Bermuda
-			"BM",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Brazil
-			"BR",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 24, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Belgium
-			"BE",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  18, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  18, IDOR, FALSE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Bulgaria
-			"BG",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11, 30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Canada
-			"CA",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Cayman IsLands
-			"KY",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Chile
-			"CL",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  20, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 5,  20, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// China
-			"CN",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149, 4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Colombia
-			"CO",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Costa Rica
-			"CR",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149, 4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Cyprus
-			"CY",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  24, IDOR, TRUE},		// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Czech_Republic
-			"CZ",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Denmark
-			"DK",
-			CE,
-			{
-				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
-				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Dominican Republic
-			"DO",
-			CE,
-			{
-				{ 1,   0,  20, BOTH, FALSE},	// 2.4 G, ch 0
-				{ 149, 4,  20, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Equador
-			"EC",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 100, 11,  27, BOTH, FALSE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// El Salvador
-			"SV",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   30, BOTH, TRUE},	// 5G, ch 52~64
-				{ 149, 4,   36, BOTH, TRUE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Finland
-			"FI",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// France
-			"FR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Germany
-			"DE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Greece
-			"GR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Guam
-			"GU",
-			CE,
-			{
-				{ 1,   11,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149,  5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Guatemala
-			"GT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Haiti
-			"HT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Honduras
-			"HN",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Hong Kong
-			"HK",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Hungary
-			"HU",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Iceland
-			"IS",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// India
-			"IN",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149, 	4,  24, IDOR, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Indonesia
-			"ID",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149, 	4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Ireland
-			"IE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Israel
-			"IL",
-			CE,
-			{
-				{ 1,    3,  20, IDOR, FALSE},	// 2.4 G, ch 1~3
-				{ 4, 	6,  20, BOTH, FALSE},	// 2.4 G, ch 4~9
-				{ 10, 	4,  20, IDOR, FALSE},	// 2.4 G, ch 10~13
-				{ 0},							// end
-			}
-		},
-
-		{	// Italy
-			"IT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Japan
-			"JP",
-			JAP,
-			{
-				{ 1,   14,  20, BOTH, FALSE},	// 2.4 G, ch 1~14
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 0},							// end
-			}
-		},
-
-		{	// Jordan
-			"JO",
-			CE,
-			{
-				{ 1,   13,  20, IDOR, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 149, 	4,  23, IDOR, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Latvia
-			"LV",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Liechtenstein
-			"LI",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Lithuania
-			"LT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Luxemburg
-			"LU",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Malaysia
-			"MY",
-			CE,
-			{
-				{ 36, 	4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  5,  20, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Malta
-			"MT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Marocco
-			"MA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  24, IDOR, FALSE},	// 5G, ch 36~48
-				{ 0},							// end
-			}
-		},
-
-		{	// Mexico
-			"MX",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  5,  30, IDOR, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Netherlands
-			"NL",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  24, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// New Zealand
-			"NZ",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  24, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  24, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Norway
-			"NO",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36, 	4,  24, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52, 	4,  24, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Peru
-			"PE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Portugal
-			"PT",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Poland
-			"PL",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Romania
-			"RO",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Russia
-			"RU",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 149,  4,  20, IDOR, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Saudi Arabia
-			"SA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  23, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Serbia_and_Montenegro
-			"CS",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 0},							// end
-			}
-		},
-
-		{	// Singapore
-			"SG",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 149,  4,  20, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Slovakia
-			"SK",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Slovenia
-			"SI",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// South Africa
-			"ZA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// South Korea
-			"KR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  20, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100,  8,  20, BOTH, FALSE},	// 5G, ch 100~128
-				{ 149,  4,  20, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Spain
-			"ES",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  17, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Sweden
-			"SE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Switzerland
-			"CH",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
-				{ 36,   4,  23, IDOR, TRUE},	// 5G, ch 36~48
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Taiwan
-			"TW",
-			CE,
-			{
-				{ 1,   11,  30, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// Turkey
-			"TR",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
-				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
-				{ 0},							// end
-			}
-		},
-
-		{	// UK
-			"GB",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
-				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 0},							// end
-			}
-		},
-
-		{	// Ukraine
-			"UA",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 0},							// end
-			}
-		},
-
-		{	// United_Arab_Emirates
-			"AE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 0},							// end
-			}
-		},
-
-		{	// United_States
-			"US",
-			CE,
-			{
-				{ 1,   11,  30, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  17, IDOR, FALSE},	// 5G, ch 52~64
-				{ 52,   4,  24, BOTH, TRUE},	// 5G, ch 52~64
-				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
-				{ 149,  5,  30, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-
-		{	// Venezuela
-			"VE",
-			CE,
-			{
-				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
-				{ 0},							// end
-			}
-		},
-
-		{	// Default
-			"",
-			CE,
-			{
-				{ 1,   11,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
-				{ 36,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 52,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
-				{ 100, 11,  20, BOTH, FALSE},	// 5G, ch 100~140
-				{ 149,  5,  20, BOTH, FALSE},	// 5G, ch 149~165
-				{ 0},							// end
-			}
-		},
-};
-
-static inline PCH_REGION GetChRegion(
-	IN PUCHAR CntryCode)
-{
-	INT loop = 0;
-	PCH_REGION pChRegion = NULL;
-
-	while (strcmp(ChRegion[loop].CountReg, "") != 0)
-	{
-		if (strncmp(ChRegion[loop].CountReg, CntryCode, 2) == 0)
-		{
-			pChRegion = &ChRegion[loop];
-			break;
-		}
-		loop++;
-	}
-
-	if (pChRegion == NULL)
-		pChRegion = &ChRegion[loop];
-	return pChRegion;
-}
-
-static inline VOID ChBandCheck(
-	IN UCHAR PhyMode,
-	OUT PUCHAR pChType)
-{
-	switch(PhyMode)
-	{
-		case PHY_11A:
-		case PHY_11AN_MIXED:
-			*pChType = BAND_5G;
-			break;
-		case PHY_11ABG_MIXED:
-		case PHY_11AGN_MIXED:
-		case PHY_11ABGN_MIXED:
-			*pChType = BAND_BOTH;
-			break;
-
-		default:
-			*pChType = BAND_24G;
-			break;
-	}
-}
-
-static inline UCHAR FillChList(
-	IN PRTMP_ADAPTER pAd,
-	IN PCH_DESP pChDesp,
-	IN UCHAR Offset,
-	IN UCHAR increment)
-{
-	INT i, j, l;
-	UCHAR channel;
-
-	j = Offset;
-	for (i = 0; i < pChDesp->NumOfCh; i++)
-	{
-		channel = pChDesp->FirstChannel + i * increment;
-		for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
-		{
-			if (channel == pAd->TxPower[l].Channel)
-			{
-				pAd->ChannelList[j].Power = pAd->TxPower[l].Power;
-				pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2;
-				break;
-			}
-		}
-		if (l == MAX_NUM_OF_CHANNELS)
-			continue;
-
-		pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment;
-		pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
-		pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
-		j++;
-	}
-	pAd->ChannelListNum = j;
-
-	return j;
-}
-
-static inline VOID CreateChList(
-	IN PRTMP_ADAPTER pAd,
-	IN PCH_REGION pChRegion,
-	IN UCHAR Geography)
-{
-	INT i;
-	UCHAR offset = 0;
-	PCH_DESP pChDesp;
-	UCHAR ChType;
-	UCHAR increment;
-
-	if (pChRegion == NULL)
-		return;
-
-	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
-
-	for (i=0; i<10; i++)
-	{
-		pChDesp = &pChRegion->ChDesp[i];
-		if (pChDesp->FirstChannel == 0)
-			break;
-
-		if (ChType == BAND_5G)
-		{
-			if (pChDesp->FirstChannel <= 14)
-				continue;
-		}
-		else if (ChType == BAND_24G)
-		{
-			if (pChDesp->FirstChannel > 14)
-				continue;
-		}
-
-		if ((pChDesp->Geography == BOTH)
-			|| (pChDesp->Geography == Geography))
-        {
-			if (pChDesp->FirstChannel > 14)
-                increment = 4;
-            else
-                increment = 1;
-			offset = FillChList(pAd, pChDesp, offset, increment);
-        }
-	}
-}
-
-static inline VOID BuildChannelListEx(
-	IN PRTMP_ADAPTER pAd)
-{
-	PCH_REGION pChReg;
-
-	pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
-	CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
-}
-
-static inline VOID BuildBeaconChList(
+extern CH_REGION ChRegion[];
+
+typedef struct _CH_FREQ_MAP_{
+	UINT16		channel;
+	UINT16		freqKHz;
+}CH_FREQ_MAP;
+
+extern CH_FREQ_MAP CH_HZ_ID_MAP[];
+extern int CH_HZ_ID_MAP_NUM;
+
+
+#define     MAP_CHANNEL_ID_TO_KHZ(_ch, _khz)					\
+		do{													\
+			int _chIdx;											\
+			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
+			{													\
+				if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel)			\
+				{												\
+					(_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000;	\
+					break;										\
+				}												\
+			}													\
+			if (_chIdx == CH_HZ_ID_MAP_NUM)					\
+				(_khz) = 2412000;									\
+            }while(0)
+
+#define     MAP_KHZ_TO_CHANNEL_ID(_khz, _ch)                 \
+		do{													\
+			int _chIdx;											\
+			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
+			{													\
+				if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz)			\
+				{												\
+					(_ch) = CH_HZ_ID_MAP[_chIdx].channel;			\
+					break;										\
+				}												\
+			}													\
+			if (_chIdx == CH_HZ_ID_MAP_NUM)					\
+				(_ch) = 1;											\
+		}while(0)
+
+
+VOID BuildChannelListEx(
+	IN PRTMP_ADAPTER pAd);
+
+VOID BuildBeaconChList(
 	IN PRTMP_ADAPTER pAd,
 	OUT PUCHAR pBuf,
-	OUT	PULONG pBufLen)
-{
-	INT i;
-	ULONG TmpLen;
-	PCH_REGION pChRegion;
-	PCH_DESP pChDesp;
-	UCHAR ChType;
-
-	pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
-
-	if (pChRegion == NULL)
-		return;
-
-	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
-	*pBufLen = 0;
-
-	for (i=0; i<10; i++)
-	{
-		pChDesp = &pChRegion->ChDesp[i];
-		if (pChDesp->FirstChannel == 0)
-			break;
-
-		if (ChType == BAND_5G)
-		{
-			if (pChDesp->FirstChannel <= 14)
-				continue;
-		}
-		else if (ChType == BAND_24G)
-		{
-			if (pChDesp->FirstChannel > 14)
-				continue;
-		}
-
-		if ((pChDesp->Geography == BOTH)
-			|| (pChDesp->Geography == pAd->CommonCfg.Geography))
-		{
-			MakeOutgoingFrame(pBuf + *pBufLen,		&TmpLen,
-								1,                 	&pChDesp->FirstChannel,
-								1,                 	&pChDesp->NumOfCh,
-								1,                 	&pChDesp->MaxTxPwr,
-								END_OF_ARGS);
-			*pBufLen += TmpLen;
-		}
-	}
-}
-
-static inline BOOLEAN IsValidChannel(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR channel)
-
-{
-	INT i;
-
-	for (i = 0; i < pAd->ChannelListNum; i++)
-	{
-		if (pAd->ChannelList[i].Channel == channel)
-			break;
-	}
-
-	if (i == pAd->ChannelListNum)
-		return FALSE;
-	else
-		return TRUE;
-}
-
-
-static inline UCHAR GetExtCh(
-	IN UCHAR Channel,
-	IN UCHAR Direction)
-{
-	CHAR ExtCh;
-
-	if (Direction == EXTCHA_ABOVE)
-		ExtCh = Channel + 4;
-	else
-		ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
-
-	return ExtCh;
-}
-
-
-static inline VOID N_ChannelCheck(
-	IN PRTMP_ADAPTER pAd)
-{
-	//UCHAR ChannelNum = pAd->ChannelListNum;
-	UCHAR Channel = pAd->CommonCfg.Channel;
-
-	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW  == BW_40))
-	{
-		if (Channel > 14)
-		{
-			if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
-			    (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
-			}
-			else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
-					(Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
-			}
-			else
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-			}
-		}
-		else
-		{
-			do
-			{
-				UCHAR ExtCh;
-				UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
-				ExtCh = GetExtCh(Channel, Dir);
-				if (IsValidChannel(pAd, ExtCh))
-					break;
-
-				Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE;
-				ExtCh = GetExtCh(Channel, Dir);
-				if (IsValidChannel(pAd, ExtCh))
-				{
-					pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir;
-					break;
-				}
-				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-			} while(FALSE);
-
-			if (Channel == 14)
-			{
-				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-				//pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE;	// We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()
-			}
-		}
-	}
-
-
-}
+	OUT	PULONG pBufLen);
 
+VOID N_ChannelCheck(
+	IN PRTMP_ADAPTER pAd);
 
-static inline VOID N_SetCenCh(
-	IN PRTMP_ADAPTER pAd)
-{
-	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
-	{
-		if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
-		{
-			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
-		}
-		else
-		{
-			if (pAd->CommonCfg.Channel == 14)
-				pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
-			else
-				pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
-		}
-	}
-	else
-	{
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-	}
-}
+VOID N_SetCenCh(
+	IN PRTMP_ADAPTER pAd);
 
-static inline UINT8 GetCuntryMaxTxPwr(
+UINT8 GetCuntryMaxTxPwr(
 	IN PRTMP_ADAPTER pAd,
-	IN UINT8 channel)
-{
-	int i;
-	for (i = 0; i < pAd->ChannelListNum; i++)
-	{
-		if (pAd->ChannelList[i].Channel == channel)
-			break;
-	}
+	IN UINT8 channel);
 
-	if (i == pAd->ChannelListNum)
-		return 0xff;
-	else
-		return pAd->ChannelList[i].MaxTxPwr;
-}
 #endif // __CHLIST_H__
 
diff --git a/drivers/staging/rt2860/common/2860_rtmp_init.c b/drivers/staging/rt2860/common/2860_rtmp_init.c
deleted file mode 100644
index 0bc0fb9..0000000
--- a/drivers/staging/rt2860/common/2860_rtmp_init.c
+++ /dev/null
@@ -1,897 +0,0 @@ 
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * 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.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	2860_rtmp_init.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-	Paul Lin    2002-08-01    created
-    John Chang  2004-08-20    RT2561/2661 use scatter-gather scheme
-    Jan Lee  2006-09-15    RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
-*/
-#include "../rt_config.h"
-
-
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Allocate DMA memory blocks for send, receive
-
-	Arguments:
-		Adapter		Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_RESOURCES
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-NDIS_STATUS	RTMPAllocTxRxRingMemory(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
-	ULONG			RingBasePaHigh;
-	ULONG			RingBasePaLow;
-	PVOID			RingBaseVa;
-	INT				index, num;
-	PTXD_STRUC		pTxD;
-	PRXD_STRUC		pRxD;
-	ULONG			ErrorValue = 0;
-	PRTMP_TX_RING	pTxRing;
-	PRTMP_DMABUF	pDmaBuf;
-	PNDIS_PACKET	pPacket;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
-	do
-	{
-		//
-		// Allocate all ring descriptors, include TxD, RxD, MgmtD.
-		// Although each size is different, to prevent cacheline and alignment
-		// issue, I intentional set them all to 64 bytes.
-		//
-		for (num=0; num<NUM_OF_TX_RING; num++)
-		{
-			ULONG  BufBasePaHigh;
-			ULONG  BufBasePaLow;
-			PVOID  BufBaseVa;
-
-			//
-			// Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
-			//
-			pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
-			RTMP_AllocateTxDescMemory(
-				pAd,
-				num,
-				pAd->TxDescRing[num].AllocSize,
-				FALSE,
-				&pAd->TxDescRing[num].AllocVa,
-				&pAd->TxDescRing[num].AllocPa);
-
-			if (pAd->TxDescRing[num].AllocVa == NULL)
-			{
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-
-			// Zero init this memory block
-			NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);
-
-			// Save PA & VA for further operation
-			RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
-			RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
-			RingBaseVa     = pAd->TxDescRing[num].AllocVa;
-
-			//
-			// Allocate all 1st TXBuf's memory for this TxRing
-			//
-			pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
-			RTMP_AllocateFirstTxBuffer(
-				pAd,
-				num,
-				pAd->TxBufSpace[num].AllocSize,
-				FALSE,
-				&pAd->TxBufSpace[num].AllocVa,
-				&pAd->TxBufSpace[num].AllocPa);
-
-			if (pAd->TxBufSpace[num].AllocVa == NULL)
-			{
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-
-			// Zero init this memory block
-			NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);
-
-			// Save PA & VA for further operation
-			BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
-			BufBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
-			BufBaseVa     = pAd->TxBufSpace[num].AllocVa;
-
-			//
-			// Initialize Tx Ring Descriptor and associated buffer memory
-			//
-			pTxRing = &pAd->TxRing[num];
-			for (index = 0; index < TX_RING_SIZE; index++)
-			{
-				pTxRing->Cell[index].pNdisPacket = NULL;
-				pTxRing->Cell[index].pNextNdisPacket = NULL;
-				// Init Tx Ring Size, Va, Pa variables
-				pTxRing->Cell[index].AllocSize = TXD_SIZE;
-				pTxRing->Cell[index].AllocVa = RingBaseVa;
-				RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
-				RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);
-
-				// Setup Tx Buffer size & address. only 802.11 header will store in this space
-				pDmaBuf = &pTxRing->Cell[index].DmaBuf;
-				pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
-				pDmaBuf->AllocVa = BufBaseVa;
-				RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
-				RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);
-
-				// link the pre-allocated TxBuf to TXD
-				pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
-				pTxD->SDPtr0 = BufBasePaLow;
-				// advance to next ring descriptor address
-				pTxD->DMADONE = 1;
-				RingBasePaLow += TXD_SIZE;
-				RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
-
-				// advance to next TxBuf address
-				BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
-				BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
-		}
-		if (Status == NDIS_STATUS_RESOURCES)
-			break;
-
-		//
-		// Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler
-		//
-		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
-		RTMP_AllocateMgmtDescMemory(
-			pAd,
-			pAd->MgmtDescRing.AllocSize,
-			FALSE,
-			&pAd->MgmtDescRing.AllocVa,
-			&pAd->MgmtDescRing.AllocPa);
-
-		if (pAd->MgmtDescRing.AllocVa == NULL)
-		{
-			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-			Status = NDIS_STATUS_RESOURCES;
-			break;
-		}
-
-		// Zero init this memory block
-		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
-
-		// Save PA & VA for further operation
-		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
-		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
-		RingBaseVa     = pAd->MgmtDescRing.AllocVa;
-
-		//
-		// Initialize MGMT Ring and associated buffer memory
-		//
-		for (index = 0; index < MGMT_RING_SIZE; index++)
-		{
-			pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
-			pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
-			// Init MGMT Ring Size, Va, Pa variables
-			pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
-			pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
-			RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
-			RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);
-
-			// Offset to next ring descriptor address
-			RingBasePaLow += TXD_SIZE;
-			RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
-
-			// link the pre-allocated TxBuf to TXD
-			pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
-			pTxD->DMADONE = 1;
-
-			// no pre-allocated buffer required in MgmtRing for scatter-gather case
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));
-
-		//
-		// Allocate RX ring descriptor's memory except Tx ring which allocated eariler
-		//
-		pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
-		RTMP_AllocateRxDescMemory(
-			pAd,
-			pAd->RxDescRing.AllocSize,
-			FALSE,
-			&pAd->RxDescRing.AllocVa,
-			&pAd->RxDescRing.AllocPa);
-
-		if (pAd->RxDescRing.AllocVa == NULL)
-		{
-			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
-			Status = NDIS_STATUS_RESOURCES;
-			break;
-		}
-
-		// Zero init this memory block
-		NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);
-
-
-		printk("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa,
-					pAd->RxDescRing.AllocSize);
-
-		// Save PA & VA for further operation
-		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
-		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
-		RingBaseVa     = pAd->RxDescRing.AllocVa;
-
-		//
-		// Initialize Rx Ring and associated buffer memory
-		//
-		for (index = 0; index < RX_RING_SIZE; index++)
-		{
-			// Init RX Ring Size, Va, Pa variables
-			pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
-			pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
-			RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
-			RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);
-
-			// Offset to next ring descriptor address
-			RingBasePaLow += RXD_SIZE;
-			RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;
-
-			// Setup Rx associated Buffer size & allocate share memory
-			pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
-			pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
-			pPacket = RTMP_AllocateRxPacketBuffer(
-				pAd,
-				pDmaBuf->AllocSize,
-				FALSE,
-				&pDmaBuf->AllocVa,
-				&pDmaBuf->AllocPa);
-
-			/* keep allocated rx packet */
-			pAd->RxRing.Cell[index].pNdisPacket = pPacket;
-
-			// Error handling
-			if (pDmaBuf->AllocVa == NULL)
-			{
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-
-			// Zero init this memory block
-			NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
-
-			// Write RxD buffer address & allocated buffer length
-			pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
-			pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
-			pRxD->DDONE = 0;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));
-
-	}	while (FALSE);
-
-
-	NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
-	pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
-
-	if (pAd->FragFrame.pFragPacket == NULL)
-	{
-		Status = NDIS_STATUS_RESOURCES;
-	}
-
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		// Log error inforamtion
-		NdisWriteErrorLogEntry(
-			pAd->AdapterHandle,
-			NDIS_ERROR_CODE_OUT_OF_RESOURCES,
-			1,
-			ErrorValue);
-	}
-
-	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
-	return Status;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Initialize transmit data structures
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-		Initialize all transmit releated private buffer, include those define
-		in RTMP_ADAPTER structure and all private data structures.
-
-	========================================================================
-*/
-VOID	NICInitTxRxRingAndBacklogQueue(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	//WPDMA_GLO_CFG_STRUC	GloCfg;
-	int i;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<--> NICInitTxRxRingAndBacklogQueue\n"));
-
-	// Initialize all transmit related software queues
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BE]);
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BK]);
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VI]);
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VO]);
-	InitializeQueueHeader(&pAd->TxSwQueue[QID_HCCA]);
-
-	// Init RX Ring index pointer
-	pAd->RxRing.RxSwReadIdx = 0;
-	pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
-
-	// Init TX rings index pointer
-		for (i=0; i<NUM_OF_TX_RING; i++)
-		{
-			pAd->TxRing[i].TxSwFreeIdx = 0;
-			pAd->TxRing[i].TxCpuIdx = 0;
-		}
-
-	// init MGMT ring index pointer
-	pAd->MgmtRing.TxSwFreeIdx = 0;
-	pAd->MgmtRing.TxCpuIdx = 0;
-
-	pAd->PrivateInfo.TxRingFullCnt       = 0;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		Reset NIC to initial state AS IS system boot up time.
-
-	========================================================================
-*/
-VOID	RTMPRingCleanUp(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			RingType)
-{
-	PTXD_STRUC		pTxD;
-	PRXD_STRUC		pRxD;
-	PQUEUE_ENTRY	pEntry;
-	PNDIS_PACKET	pPacket;
-	int				i;
-	PRTMP_TX_RING	pTxRing;
-	unsigned long	IrqFlags;
-
-	DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount));
-	switch (RingType)
-	{
-		case QID_AC_BK:
-		case QID_AC_BE:
-		case QID_AC_VI:
-		case QID_AC_VO:
-		case QID_HCCA:
-			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-			pTxRing = &pAd->TxRing[RingType];
-
-			// We have to clean all descriptors in case some error happened with reset
-			for (i=0; i<TX_RING_SIZE; i++) // We have to scan all TX ring
-			{
-				pTxD  = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
-
-				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket;
-				// release scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-					pTxRing->Cell[i].pNdisPacket = NULL;
-				}
-
-				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket;
-				// release scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-					pTxRing->Cell[i].pNextNdisPacket = NULL;
-				}
-			}
-
-			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx);
-			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
-			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
-			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx);
-
-			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-			while (pAd->TxSwQueue[RingType].Head != NULL)
-			{
-				pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
-				pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n"));
-			}
-			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-			break;
-
-		case QID_MGMT:
-			// We have to clean all descriptors in case some error happened with reset
-			NdisAcquireSpinLock(&pAd->MgmtRingLock);
-
-			for (i=0; i<MGMT_RING_SIZE; i++)
-			{
-				pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa;
-
-				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket;
-				// rlease scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				}
-				pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
-
-				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket;
-				// release scatter-and-gather NDIS_PACKET
-				if (pPacket)
-				{
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-				}
-				pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
-
-			}
-
-			RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
-			pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
-			pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
-			RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
-
-			NdisReleaseSpinLock(&pAd->MgmtRingLock);
-			pAd->RalinkCounters.MgmtRingFullCount = 0;
-			break;
-
-		case QID_RX:
-			// We have to clean all descriptors in case some error happened with reset
-			NdisAcquireSpinLock(&pAd->RxRingLock);
-
-			for (i=0; i<RX_RING_SIZE; i++)
-			{
-				pRxD  = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa;
-				pRxD->DDONE = 0 ;
-			}
-
-			RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
-			pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
-			pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1));
-			RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-			NdisReleaseSpinLock(&pAd->RxRingLock);
-			break;
-
-		default:
-			break;
-	}
-}
-
-
-NDIS_STATUS AdapterBlockAllocateMemory(
-	IN PVOID	handle,
-	OUT	PVOID	*ppAd)
-{
-	PPCI_DEV pci_dev;
-	dma_addr_t	*phy_addr;
-	POS_COOKIE pObj = (POS_COOKIE) handle;
-
-	pci_dev = pObj->pci_dev;
-	phy_addr = &pObj->pAd_pa;
-
-	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr);
-
-	if (*ppAd)
-	{
-		NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
-		((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
-		return (NDIS_STATUS_SUCCESS);
-	} else {
-		return (NDIS_STATUS_FAILURE);
-	}
-}
-
-
-void RTMP_AllocateTxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-
-}
-
-void RTMP_AllocateMgmtDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-
-}
-
-void RTMP_AllocateRxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-
-}
-
-void RTMP_FreeRxDescMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	PVOID	VirtualAddress,
-	IN	NDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	PCI_FREE_CONSISTENT(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
-}
-
-
-void RTMP_AllocateFirstTxBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	UINT	Index,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-}
-
-/*
- * FUNCTION: Allocate a common buffer for DMA
- * ARGUMENTS:
- *     AdapterHandle:  AdapterHandle
- *     Length:  Number of bytes to allocate
- *     Cached:  Whether or not the memory can be cached
- *     VirtualAddress:  Pointer to memory is returned here
- *     PhysicalAddress:  Physical address corresponding to virtual address
- */
-
-void RTMP_AllocateSharedMemory(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	*VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
-}
-
-VOID RTMPFreeTxRxRingMemory(
-    IN  PRTMP_ADAPTER   pAd)
-{
-	int index, num , j;
-	PRTMP_TX_RING pTxRing;
-	PTXD_STRUC	  pTxD;
-	PNDIS_PACKET  pPacket;
-	unsigned int  IrqFlags;
-
-	POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
-
-	// Free TxSwQueue Packet
-	for (index=0; index <NUM_OF_TX_RING; index++)
-	{
-		PQUEUE_ENTRY pEntry;
-		PNDIS_PACKET pPacket;
-		PQUEUE_HEADER   pQueue;
-
-		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-		pQueue = &pAd->TxSwQueue[index];
-		while (pQueue->Head)
-		{
-			pEntry = RemoveHeadQueue(pQueue);
-			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		}
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-	}
-
-	// Free Tx Ring Packet
-	for (index=0;index< NUM_OF_TX_RING;index++)
-	{
-		pTxRing = &pAd->TxRing[index];
-
-		for (j=0; j< TX_RING_SIZE; j++)
-		{
-			pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa);
-			pPacket = pTxRing->Cell[j].pNdisPacket;
-
-			if (pPacket)
-			{
-            	PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNdisPacket as NULL after clear
-			pTxRing->Cell[j].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[j].pNextNdisPacket;
-
-			if (pPacket)
-			{
-            	PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNextNdisPacket as NULL after clear
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-
-		}
-	}
-
-	for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
-	{
-		if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket))
-		{
-			PCI_UNMAP_SINGLE(pObj->pci_dev, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
-			RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS);
-		}
-	}
-	NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
-
-	if (pAd->RxDescRing.AllocVa)
-    {
-    	PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa);
-    }
-    NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF));
-
-	if (pAd->MgmtDescRing.AllocVa)
-	{
-		PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->MgmtDescRing.AllocSize,	pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa);
-	}
-	NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF));
-
-	for (num = 0; num < NUM_OF_TX_RING; num++)
-	{
-    	if (pAd->TxBufSpace[num].AllocVa)
-	    {
-	    	PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxBufSpace[num].AllocSize, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa);
-	    }
-	    NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF));
-
-    	if (pAd->TxDescRing[num].AllocVa)
-	    {
-	    	PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa);
-	    }
-	    NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF));
-	}
-
-	if (pAd->FragFrame.pFragPacket)
-		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
-}
-
-
-/*
- * FUNCTION: Allocate a packet buffer for DMA
- * ARGUMENTS:
- *     AdapterHandle:  AdapterHandle
- *     Length:  Number of bytes to allocate
- *     Cached:  Whether or not the memory can be cached
- *     VirtualAddress:  Pointer to memory is returned here
- *     PhysicalAddress:  Physical address corresponding to virtual address
- * Notes:
- *     Cached is ignored: always cached memory
- */
-PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
-	IN	PRTMP_ADAPTER pAd,
-	IN	ULONG	Length,
-	IN	BOOLEAN	Cached,
-	OUT	PVOID	*VirtualAddress,
-	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
-{
-	PNDIS_PACKET pkt;
-
-	pkt = RTPKT_TO_OSPKT(DEV_ALLOC_SKB(Length));
-
-	if (pkt == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
-	}
-
-	if (pkt) {
-		RTMP_SET_PACKET_SOURCE(pkt, PKTSRC_NDIS);
-		*VirtualAddress = (PVOID) RTPKT_TO_OSPKT(pkt)->data;
-		*PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE);
-	} else {
-		*VirtualAddress = (PVOID) NULL;
-		*PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL;
-	}
-
-	return (PNDIS_PACKET) pkt;
-}
-
-
-VOID Invalid_Remaining_Packet(
-	IN	PRTMP_ADAPTER pAd,
-	IN	 ULONG VirtualAddress)
-{
-	NDIS_PHYSICAL_ADDRESS PhysicalAddress;
-
-	PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE);
-}
-
-PNDIS_PACKET GetPacketFromRxRing(
-	IN		PRTMP_ADAPTER	pAd,
-	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
-	OUT		BOOLEAN			*pbReschedule,
-	IN OUT	UINT32			*pRxPending)
-{
-	PRXD_STRUC				pRxD;
-	PNDIS_PACKET			pRxPacket = NULL;
-	PNDIS_PACKET			pNewPacket;
-	PVOID					AllocVa;
-	NDIS_PHYSICAL_ADDRESS	AllocPa;
-	BOOLEAN					bReschedule = FALSE;
-
-	RTMP_SEM_LOCK(&pAd->RxRingLock);
-
-	if (*pRxPending == 0)
-	{
-		// Get how may packets had been received
-		RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
-
-		if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
-		{
-			// no more rx packets
-			bReschedule = FALSE;
-			goto done;
-		}
-
-		// get rx pending count
-		if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
-			*pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
-		else
-			*pRxPending	= pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
-
-	}
-
-	// Point to Rx indexed rx ring descriptor
-	pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
-
-	if (pRxD->DDONE == 0)
-	{
-		*pRxPending = 0;
-		// DMAIndx had done but DDONE bit not ready
-		bReschedule = TRUE;
-		goto done;
-	}
-
-
-	// return rx descriptor
-	NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
-
-	pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
-
-	if (pNewPacket)
-	{
-		// unmap the rx buffer
-		PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa,
-					 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
-		pRxPacket = pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket;
-
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize	= RX_BUFFER_AGGRESIZE;
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket		= (PNDIS_PACKET) pNewPacket;
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocVa	= AllocVa;
-		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa	= AllocPa;
-		/* update SDP0 to new buffer of rx packet */
-		pRxD->SDP0 = AllocPa;
-	}
-	else
-	{
-		//printk("No Rx Buffer\n");
-		pRxPacket = NULL;
-		bReschedule = TRUE;
-	}
-
-	pRxD->DDONE = 0;
-
-	// had handled one rx packet
-	*pRxPending = *pRxPending - 1;
-
-	// update rx descriptor and kick rx
-	INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
-
-	pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
-	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-done:
-	RTMP_SEM_UNLOCK(&pAd->RxRingLock);
-	*pbReschedule = bReschedule;
-	return pRxPacket;
-}
-/* End of 2860_rtmp_init.c */
-
diff --git a/drivers/staging/rt2860/common/action.c b/drivers/staging/rt2860/common/action.c
index 256cb67..5593966 100644
--- a/drivers/staging/rt2860/common/action.c
+++ b/drivers/staging/rt2860/common/action.c
@@ -150,7 +150,9 @@  VOID MlmeADDBAAction(
 		MakeOutgoingFrame(pOutBuffer,		   &FrameLen,
 		              sizeof(FRAME_ADDBA_REQ), &Frame,
 		              END_OF_ARGS);
-		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+
+		MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[pInfo->TID]), pOutBuffer, FrameLen);
+
 		MlmeFreeMemory(pAd, pOutBuffer);
 
 		DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x,  FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
@@ -527,9 +529,13 @@  VOID SendRefreshBAR(
 			MakeOutgoingFrame(pOutBuffer,				&FrameLen,
 							  sizeof(FRAME_BAR),	  &FrameBar,
 							  END_OF_ARGS);
+			//if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
+			if (1)	// Now we always send BAR.
+			{
+				//MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
+				MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[TID]), pOutBuffer, FrameLen);
 
-			MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-
+			}
 			MlmeFreeMemory(pAd, pOutBuffer);
 		}
 	}
diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c
index b7bbe99..ff4dce6 100644
--- a/drivers/staging/rt2860/common/ba_action.c
+++ b/drivers/staging/rt2860/common/ba_action.c
@@ -35,8 +35,8 @@ 
 #define ORI_BA_SESSION_TIMEOUT	(2000)	// ms
 #define REC_BA_SESSION_IDLE_TIMEOUT	(1000)	// ms
 
-#define REORDERING_PACKET_TIMEOUT		((100 * HZ)/1000)	// system ticks -- 100 ms
-#define MAX_REORDERING_PACKET_TIMEOUT	((3000 * HZ)/1000)	// system ticks -- 100 ms
+#define REORDERING_PACKET_TIMEOUT		((100 * OS_HZ)/1000)	// system ticks -- 100 ms
+#define MAX_REORDERING_PACKET_TIMEOUT	((3000 * OS_HZ)/1000)	// system ticks -- 100 ms
 
 #define RESET_RCV_SEQ		(0xFFFF)
 
@@ -460,6 +460,8 @@  void ba_flush_reordering_timeout_mpdus(
     			pBAEntry->LastIndSeq = Sequence;
     		}
 
+		DBGPRINT(RT_DEBUG_OFF, ("%x, flush one!\n", pBAEntry->LastIndSeq));
+
 	}
 }
 
@@ -493,7 +495,7 @@  VOID BAOriSessionSetUp(
 	{
 		// try again after 3 secs
 		DelayTime = 3000;
-//		printk("DeCline BA from Peer\n");
+//		DBGPRINT(RT_DEBUG_TRACE, ("DeCline BA from Peer\n"));
 //		return;
 	}
 
@@ -531,11 +533,6 @@  VOID BAOriSessionSetUp(
 	pBAEntry->TimeOutValue = TimeOut;
 	pBAEntry->pAdapter = pAd;
 
-	DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n"
-		,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
-		,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
-		,TID,isForced,pEntry->Aid));
-
 	if (!(pEntry->TXBAbitmap & (1<<TID)))
 	{
 		RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
@@ -573,6 +570,8 @@  VOID BAOriSessionAdd(
 
 		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
 		pBAEntry->ORI_BA_Status = Originator_Done;
+		pAd->BATable.numDoneOriginator ++;
+
 		// reset sequence number
 		pBAEntry->Sequence = BA_ORI_INIT_SEQ;
 		// Set Bitmap flag.
@@ -668,7 +667,7 @@  BOOLEAN BARecSessionAdd(
 		// initial sequence number
 		pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
 
-		printk("Start Seq = %08x\n",  pFrame->BaStartSeq.field.StartSeq);
+		DBGPRINT(RT_DEBUG_OFF, ("Start Seq = %08x\n",  pFrame->BaStartSeq.field.StartSeq));
 
 		if (pEntry->RXBAbitmap & (1<<TID))
 		{
@@ -686,7 +685,7 @@  BOOLEAN BARecSessionAdd(
 		pEntry->BADeclineBitmap &= ~(1<<TID);
 
 		// Set BA session mask in WCID table.
-		RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
+		RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
 
 		DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
 				pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
@@ -713,8 +712,8 @@  BA_REC_ENTRY *BATableAllocRecEntry(
 
 	if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
 	{
-		printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient,
-			MAX_BARECI_SESSION);
+		DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n",
+							pAd->BATable.numAsRecipient, MAX_BARECI_SESSION));
 		goto done;
 	}
 
@@ -794,6 +793,7 @@  VOID BATableFreeOriEntry(
 		NdisAcquireSpinLock(&pAd->BATabLock);
 		if (pBAEntry->ORI_BA_Status == Originator_Done)
 		{
+			pAd->BATable.numDoneOriginator -= 1;
 		 	pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
 			DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
 			// Erase Bitmap flag.
@@ -867,9 +867,8 @@  VOID BAOriSessionTearDown(
 			// force send specified TID DelBA
 			MLME_DELBA_REQ_STRUCT   DelbaReq;
 			MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-			if (Elem == NULL)
-				return;
-
+			if (Elem != NULL)
+			{
 			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
 			NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
 
@@ -877,15 +876,15 @@  VOID BAOriSessionTearDown(
 			DelbaReq.Wcid = Wcid;
 			DelbaReq.TID = TID;
 			DelbaReq.Initiator = ORIGINATOR;
-#if 1
 			Elem->MsgLen  = sizeof(DelbaReq);
 			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
 			MlmeDELBAAction(pAd, Elem);
 			kfree(Elem);
-#else
-			MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
-			RT28XX_MLME_HANDLER(pAd);
-#endif
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("%s(bForceSend):alloc memory failed!\n", __func__));
+			}
 		}
 
 		return;
@@ -902,9 +901,8 @@  VOID BAOriSessionTearDown(
 	{
 		MLME_DELBA_REQ_STRUCT   DelbaReq;
 		MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-		if (Elem == NULL)
-			return;
-
+		if (Elem != NULL)
+		{
 		NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
 		NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
 
@@ -912,15 +910,16 @@  VOID BAOriSessionTearDown(
 		DelbaReq.Wcid = Wcid;
 		DelbaReq.TID = pBAEntry->TID;
 		DelbaReq.Initiator = ORIGINATOR;
-#if 1
 		Elem->MsgLen  = sizeof(DelbaReq);
 		NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
 		MlmeDELBAAction(pAd, Elem);
 		kfree(Elem);
-#else
-		MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
-		RT28XX_MLME_HANDLER(pAd);
-#endif
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __func__));
+			return;
+		}
 	}
 	RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
 	BATableFreeOriEntry(pAd, Idx);
@@ -964,7 +963,6 @@  VOID BARecSessionTearDown(
 	{
 		MLME_DELBA_REQ_STRUCT   DelbaReq;
 		BOOLEAN 				Cancelled;
-		MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
 		//ULONG   offset;
 		//UINT32  VALUE;
 
@@ -975,6 +973,9 @@  VOID BARecSessionTearDown(
 		//
 		if (bPassive == FALSE)
 		{
+			MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+			if (Elem != NULL)
+			{
 			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
 			NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
 
@@ -982,15 +983,16 @@  VOID BARecSessionTearDown(
 			DelbaReq.Wcid = Wcid;
 			DelbaReq.TID = TID;
 			DelbaReq.Initiator = RECIPIENT;
-#if 1
 			Elem->MsgLen  = sizeof(DelbaReq);
 			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
 			MlmeDELBAAction(pAd, Elem);
 			kfree(Elem);
-#else
-			MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
-			RT28XX_MLME_HANDLER(pAd);
-#endif
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __func__));
+				return;
+			}
 		}
 
 
@@ -1009,7 +1011,7 @@  VOID BARecSessionTearDown(
 		pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
 		pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
 
-		RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
+		RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
 
 		NdisReleaseSpinLock(&pAd->BATabLock);
 
@@ -1061,9 +1063,12 @@  VOID BAOriSessionSetupTimeout(
 
 	pAd = pBAEntry->pAdapter;
 
+	{
 	// Do nothing if monitor mode is on
 	if (MONITOR_ON(pAd))
 		return;
+	}
+
 
 	pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
 
@@ -1079,12 +1084,9 @@  VOID BAOriSessionSetupTimeout(
 		AddbaReq.TimeOutValue = 0;
 		AddbaReq.Token = pBAEntry->Token;
 		MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
-		RT28XX_MLME_HANDLER(pAd);
-		DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n"
-		,pBAEntry->Token
-		,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
-		,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
-		,pBAEntry->TID,pEntry->Aid));
+		RTMP_MLME_HANDLER(pAd);
+		DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
+
 		pBAEntry->Token++;
 		RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
 	}
@@ -1131,7 +1133,7 @@  VOID BARecSessionIdleTimeout(
 			pAd = pBAEntry->pAdapter;
 			// flush all pending reordering mpdus
 			ba_refresh_reordering_mpdus(pAd, pBAEntry);
-			printk("%ld: REC BA session Timeout\n", Now32);
+			DBGPRINT(RT_DEBUG_OFF, ("%ld: REC BA session Timeout\n", Now32));
 		}
 	}
 }
@@ -1174,7 +1176,7 @@  VOID PeerAddBAReqAction(
 		if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
 		{
 			pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
-			printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
+			DBGPRINT(RT_DEBUG_OFF, ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid));
 			if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
 				Status = 0;
 			else
@@ -1367,7 +1369,7 @@  BOOLEAN CntlEnqueueForRecv(
 
 	if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
 	{
-		//printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
+		//DBGPRINT(RT_DEBUG_TRACE, ("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq));
 		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
 		pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
 	}
@@ -1388,8 +1390,6 @@  VOID SendPSMPAction(
 	//ULONG           Idx;
 	FRAME_PSMP_ACTION   Frame;
 	ULONG           FrameLen;
-	UCHAR			bbpdata=0;
-	UINT32			macdata;
 
 	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
 	if (NStatus != NDIS_STATUS_SUCCESS)
@@ -1405,48 +1405,26 @@  VOID SendPSMPAction(
 	switch (Psmp)
 	{
 		case MMPS_ENABLE:
-			if (IS_RT3090(pAd))
+#ifdef RT30xx
+			if (IS_RT30xx(pAd)
+				&&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
 			{
-				// disable MMPS BBP control register
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
-				bbpdata &= ~(0x04);	//bit 2
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
-
-				// disable MMPS MAC control register
-				RTMP_IO_READ32(pAd, 0x1210, &macdata);
-				macdata &= ~(0x09);	//bit 0, 3
-				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+				RTMP_ASIC_MMPS_DISABLE(pAd);
 			}
+#endif // RT30xx //
 			Frame.Psmp = 0;
 			break;
 		case MMPS_DYNAMIC:
-			if (IS_RT3090(pAd))
-			{
-				// enable MMPS BBP control register
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
-				bbpdata |= 0x04;	//bit 2
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
-
-				// enable MMPS MAC control register
-				RTMP_IO_READ32(pAd, 0x1210, &macdata);
-				macdata |= 0x09;	//bit 0, 3
-				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
-			}
 			Frame.Psmp = 3;
 			break;
 		case MMPS_STATIC:
-			if (IS_RT3090(pAd))
+#ifdef RT30xx
+			if (IS_RT30xx(pAd)
+				&&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
 			{
-				// enable MMPS BBP control register
-				RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
-				bbpdata |= 0x04;	//bit 2
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
-
-				// enable MMPS MAC control register
-				RTMP_IO_READ32(pAd, 0x1210, &macdata);
-				macdata |= 0x09;	//bit 0, 3
-				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+				RTMP_ASIC_MMPS_ENABLE(pAd);
 			}
+#endif // RT30xx //
 			Frame.Psmp = 1;
 			break;
 	}
@@ -1504,20 +1482,22 @@  void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
 	ASSERT(pRxBlk->pRxPacket);
 	pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
 
-	RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-	RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
-	RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
-	RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
+	SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID));
+	SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData);
+	SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize);
+	SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize);
 
 	//
 	// copy 802.3 header, if necessary
 	//
 	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
 	{
+		{
 #ifdef LINUX
 		NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
 #endif
 	}
+	}
 }
 
 
@@ -1550,7 +1530,8 @@  static VOID ba_enqueue_reordering_packet(
 	UINT16	Sequence = (UINT16) pRxBlk->pHeader->Sequence;
 
 	mpdu_blk = ba_mpdu_blk_alloc(pAd);
-	if (mpdu_blk != NULL)
+	if ((mpdu_blk != NULL) &&
+		(!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP)))
 	{
 		// Write RxD buffer address & allocated buffer length
 		NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
diff --git a/drivers/staging/rt2860/common/cmm_aes.c b/drivers/staging/rt2860/common/cmm_aes.c
new file mode 100644
index 0000000..2c311b1
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_aes.c
@@ -0,0 +1,1404 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	cmm_aes.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Paul Wu		02-25-02		Initial
+*/
+
+#include	"../rt_config.h"
+
+
+typedef	struct
+{
+    UINT32 erk[64];     /* encryption round keys */
+    UINT32 drk[64];     /* decryption round keys */
+    int nr;             /* number of rounds */
+}
+aes_context;
+
+/*****************************/
+/******** SBOX Table *********/
+/*****************************/
+
+UCHAR SboxTable[256] =
+{
+	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+VOID xor_32(
+	IN  PUCHAR  a,
+	IN  PUCHAR  b,
+	OUT PUCHAR  out)
+{
+	INT i;
+
+	for (i=0;i<4; i++)
+	{
+		out[i] = a[i] ^ b[i];
+	}
+}
+
+VOID xor_128(
+	IN  PUCHAR  a,
+	IN  PUCHAR  b,
+	OUT PUCHAR  out)
+{
+	INT i;
+
+	for (i=0;i<16; i++)
+	{
+		out[i] = a[i] ^ b[i];
+	}
+}
+
+UCHAR RTMPCkipSbox(
+	IN  UCHAR   a)
+{
+	return SboxTable[(int)a];
+}
+
+VOID next_key(
+	IN  PUCHAR  key,
+	IN  INT     round)
+{
+	UCHAR       rcon;
+	UCHAR       sbox_key[4];
+	UCHAR       rcon_table[12] =
+	{
+		0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+		0x1b, 0x36, 0x36, 0x36
+	};
+
+	sbox_key[0] = RTMPCkipSbox(key[13]);
+	sbox_key[1] = RTMPCkipSbox(key[14]);
+	sbox_key[2] = RTMPCkipSbox(key[15]);
+	sbox_key[3] = RTMPCkipSbox(key[12]);
+
+	rcon = rcon_table[round];
+
+	xor_32(&key[0], sbox_key, &key[0]);
+	key[0] = key[0] ^ rcon;
+
+	xor_32(&key[4], &key[0], &key[4]);
+	xor_32(&key[8], &key[4], &key[8]);
+	xor_32(&key[12], &key[8], &key[12]);
+}
+
+VOID byte_sub(
+	IN  PUCHAR  in,
+	OUT PUCHAR  out)
+{
+	INT i;
+
+	for (i=0; i< 16; i++)
+	{
+		out[i] = RTMPCkipSbox(in[i]);
+	}
+}
+
+/************************************/
+/* bitwise_xor()                    */
+/* A 128 bit, bitwise exclusive or  */
+/************************************/
+
+void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
+{
+	int i;
+	for (i=0; i<16; i++)
+	{
+		out[i] = ina[i] ^ inb[i];
+	}
+}
+
+VOID shift_row(
+	IN  PUCHAR  in,
+	OUT PUCHAR  out)
+{
+	out[0] =  in[0];
+	out[1] =  in[5];
+	out[2] =  in[10];
+	out[3] =  in[15];
+	out[4] =  in[4];
+	out[5] =  in[9];
+	out[6] =  in[14];
+	out[7] =  in[3];
+	out[8] =  in[8];
+	out[9] =  in[13];
+	out[10] = in[2];
+	out[11] = in[7];
+	out[12] = in[12];
+	out[13] = in[1];
+	out[14] = in[6];
+	out[15] = in[11];
+}
+
+VOID mix_column(
+	IN  PUCHAR  in,
+	OUT PUCHAR  out)
+{
+	INT         i;
+	UCHAR       add1b[4];
+	UCHAR       add1bf7[4];
+	UCHAR       rotl[4];
+	UCHAR       swap_halfs[4];
+	UCHAR       andf7[4];
+	UCHAR       rotr[4];
+	UCHAR       temp[4];
+	UCHAR       tempb[4];
+
+	for (i=0 ; i<4; i++)
+	{
+		if ((in[i] & 0x80)== 0x80)
+			add1b[i] = 0x1b;
+		else
+			add1b[i] = 0x00;
+	}
+
+	swap_halfs[0] = in[2];    /* Swap halfs */
+	swap_halfs[1] = in[3];
+	swap_halfs[2] = in[0];
+	swap_halfs[3] = in[1];
+
+	rotl[0] = in[3];        /* Rotate left 8 bits */
+	rotl[1] = in[0];
+	rotl[2] = in[1];
+	rotl[3] = in[2];
+
+	andf7[0] = in[0] & 0x7f;
+	andf7[1] = in[1] & 0x7f;
+	andf7[2] = in[2] & 0x7f;
+	andf7[3] = in[3] & 0x7f;
+
+	for (i = 3; i>0; i--)    /* logical shift left 1 bit */
+	{
+		andf7[i] = andf7[i] << 1;
+		if ((andf7[i-1] & 0x80) == 0x80)
+		{
+			andf7[i] = (andf7[i] | 0x01);
+		}
+	}
+	andf7[0] = andf7[0] << 1;
+	andf7[0] = andf7[0] & 0xfe;
+
+	xor_32(add1b, andf7, add1bf7);
+
+	xor_32(in, add1bf7, rotr);
+
+	temp[0] = rotr[0];         /* Rotate right 8 bits */
+	rotr[0] = rotr[1];
+	rotr[1] = rotr[2];
+	rotr[2] = rotr[3];
+	rotr[3] = temp[0];
+
+	xor_32(add1bf7, rotr, temp);
+	xor_32(swap_halfs, rotl,tempb);
+	xor_32(temp, tempb, out);
+}
+
+
+/************************************************/
+/* construct_mic_header1()                      */
+/* Builds the first MIC header block from       */
+/* header fields.                               */
+/************************************************/
+
+void construct_mic_header1(
+	unsigned char *mic_header1,
+	int header_length,
+	unsigned char *mpdu)
+{
+	mic_header1[0] = (unsigned char)((header_length - 2) / 256);
+	mic_header1[1] = (unsigned char)((header_length - 2) % 256);
+	mic_header1[2] = mpdu[0] & 0xcf;    /* Mute CF poll & CF ack bits */
+	mic_header1[3] = mpdu[1] & 0xc7;    /* Mute retry, more data and pwr mgt bits */
+	mic_header1[4] = mpdu[4];       /* A1 */
+	mic_header1[5] = mpdu[5];
+	mic_header1[6] = mpdu[6];
+	mic_header1[7] = mpdu[7];
+	mic_header1[8] = mpdu[8];
+	mic_header1[9] = mpdu[9];
+	mic_header1[10] = mpdu[10];     /* A2 */
+	mic_header1[11] = mpdu[11];
+	mic_header1[12] = mpdu[12];
+	mic_header1[13] = mpdu[13];
+	mic_header1[14] = mpdu[14];
+	mic_header1[15] = mpdu[15];
+}
+
+/************************************************/
+/* construct_mic_header2()                      */
+/* Builds the last MIC header block from        */
+/* header fields.                               */
+/************************************************/
+
+void construct_mic_header2(
+	unsigned char *mic_header2,
+	unsigned char *mpdu,
+	int a4_exists,
+	int qc_exists)
+{
+	int i;
+
+	for (i = 0; i<16; i++) mic_header2[i]=0x00;
+
+	mic_header2[0] = mpdu[16];    /* A3 */
+	mic_header2[1] = mpdu[17];
+	mic_header2[2] = mpdu[18];
+	mic_header2[3] = mpdu[19];
+	mic_header2[4] = mpdu[20];
+	mic_header2[5] = mpdu[21];
+
+	// In Sequence Control field, mute sequence numer bits (12-bit)
+	mic_header2[6] = mpdu[22] & 0x0f;   /* SC */
+	mic_header2[7] = 0x00; /* mpdu[23]; */
+
+	if ((!qc_exists) & a4_exists)
+	{
+		for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i];   /* A4 */
+
+	}
+
+	if (qc_exists && (!a4_exists))
+	{
+		mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
+		mic_header2[9] = mpdu[25] & 0x00;
+	}
+
+	if (qc_exists && a4_exists)
+	{
+		for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i];   /* A4 */
+
+		mic_header2[14] = mpdu[30] & 0x0f;
+		mic_header2[15] = mpdu[31] & 0x00;
+	}
+}
+
+
+/************************************************/
+/* construct_mic_iv()                           */
+/* Builds the MIC IV from header fields and PN  */
+/************************************************/
+
+void construct_mic_iv(
+	unsigned char *mic_iv,
+	int qc_exists,
+	int a4_exists,
+	unsigned char *mpdu,
+	unsigned int payload_length,
+	unsigned char *pn_vector)
+{
+	int i;
+
+	mic_iv[0] = 0x59;
+	if (qc_exists && a4_exists)
+		mic_iv[1] = mpdu[30] & 0x0f;    /* QoS_TC           */
+	if (qc_exists && !a4_exists)
+		mic_iv[1] = mpdu[24] & 0x0f;   /* mute bits 7-4    */
+	if (!qc_exists)
+		mic_iv[1] = 0x00;
+	for (i = 2; i < 8; i++)
+		mic_iv[i] = mpdu[i + 8];                    /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+		for (i = 8; i < 14; i++)
+			mic_iv[i] = pn_vector[i - 8];           /* mic_iv[8:13] = PN[0:5] */
+#else
+		for (i = 8; i < 14; i++)
+			mic_iv[i] = pn_vector[13 - i];          /* mic_iv[8:13] = PN[5:0] */
+#endif
+	i = (payload_length / 256);
+	i = (payload_length % 256);
+	mic_iv[14] = (unsigned char) (payload_length / 256);
+	mic_iv[15] = (unsigned char) (payload_length % 256);
+
+}
+
+/****************************************/
+/* aes128k128d()                        */
+/* Performs a 128 bit AES encrypt with  */
+/* 128 bit data.                        */
+/****************************************/
+void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
+{
+	int round;
+	int i;
+	unsigned char intermediatea[16];
+	unsigned char intermediateb[16];
+	unsigned char round_key[16];
+
+	for(i=0; i<16; i++) round_key[i] = key[i];
+
+	for (round = 0; round < 11; round++)
+	{
+		if (round == 0)
+		{
+			xor_128(round_key, data, ciphertext);
+			next_key(round_key, round);
+		}
+		else if (round == 10)
+		{
+			byte_sub(ciphertext, intermediatea);
+			shift_row(intermediatea, intermediateb);
+			xor_128(intermediateb, round_key, ciphertext);
+		}
+		else    /* 1 - 9 */
+		{
+			byte_sub(ciphertext, intermediatea);
+			shift_row(intermediatea, intermediateb);
+			mix_column(&intermediateb[0], &intermediatea[0]);
+			mix_column(&intermediateb[4], &intermediatea[4]);
+			mix_column(&intermediateb[8], &intermediatea[8]);
+			mix_column(&intermediateb[12], &intermediatea[12]);
+			xor_128(intermediatea, round_key, ciphertext);
+			next_key(round_key, round);
+		}
+	}
+
+}
+
+void construct_ctr_preload(
+	unsigned char *ctr_preload,
+	int a4_exists,
+	int qc_exists,
+	unsigned char *mpdu,
+	unsigned char *pn_vector,
+	int c)
+{
+
+	int i = 0;
+	for (i=0; i<16; i++) ctr_preload[i] = 0x00;
+	i = 0;
+
+	ctr_preload[0] = 0x01;                                  /* flag */
+	if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f;   /* QoC_Control  */
+	if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
+
+	for (i = 2; i < 8; i++)
+		ctr_preload[i] = mpdu[i + 8];                       /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+	  for (i = 8; i < 14; i++)
+			ctr_preload[i] =    pn_vector[i - 8];           /* ctr_preload[8:13] = PN[0:5] */
+#else
+	  for (i = 8; i < 14; i++)
+			ctr_preload[i] =    pn_vector[13 - i];          /* ctr_preload[8:13] = PN[5:0] */
+#endif
+	ctr_preload[14] =  (unsigned char) (c / 256); // Ctr
+	ctr_preload[15] =  (unsigned char) (c % 256);
+
+}
+
+BOOLEAN RTMPSoftDecryptAES(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR	pData,
+	IN ULONG	DataByteCnt,
+	IN PCIPHER_KEY	pWpaKey)
+{
+	UCHAR			KeyID;
+	UINT			HeaderLen;
+	UCHAR			PN[6];
+	UINT			payload_len;
+	UINT			num_blocks;
+	UINT			payload_remainder;
+	USHORT			fc;
+	UCHAR			fc0;
+	UCHAR			fc1;
+	UINT			frame_type;
+	UINT			frame_subtype;
+	UINT			from_ds;
+	UINT			to_ds;
+	INT				a4_exists;
+	INT				qc_exists;
+	UCHAR			aes_out[16];
+	int			payload_index;
+	UINT			i;
+	UCHAR			ctr_preload[16];
+	UCHAR			chain_buffer[16];
+	UCHAR			padded_buffer[16];
+	UCHAR			mic_iv[16];
+	UCHAR			mic_header1[16];
+	UCHAR			mic_header2[16];
+	UCHAR			MIC[8];
+	UCHAR			TrailMIC[8];
+
+
+	fc0 = *pData;
+	fc1 = *(pData + 1);
+
+	fc = *((PUSHORT)pData);
+
+	frame_type = ((fc0 >> 2) & 0x03);
+	frame_subtype = ((fc0 >> 4) & 0x0f);
+
+	from_ds = (fc1 & 0x2) >> 1;
+	to_ds = (fc1 & 0x1);
+
+	a4_exists = (from_ds & to_ds);
+	qc_exists = ((frame_subtype == 0x08) ||    /* Assumed QoS subtypes */
+				  (frame_subtype == 0x09) ||   /* Likely to change.    */
+				  (frame_subtype == 0x0a) ||
+				  (frame_subtype == 0x0b)
+				 );
+
+	HeaderLen = 24;
+	if (a4_exists)
+		HeaderLen += 6;
+
+	KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
+	KeyID = KeyID >> 6;
+
+	if (pWpaKey[KeyID].KeyLen == 0)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
+		return FALSE;
+	}
+
+	PN[0] = *(pData+ HeaderLen);
+	PN[1] = *(pData+ HeaderLen + 1);
+	PN[2] = *(pData+ HeaderLen + 4);
+	PN[3] = *(pData+ HeaderLen + 5);
+	PN[4] = *(pData+ HeaderLen + 6);
+	PN[5] = *(pData+ HeaderLen + 7);
+
+	payload_len = DataByteCnt - HeaderLen - 8 - 8;	// 8 bytes for CCMP header , 8 bytes for MIC
+	payload_remainder = (payload_len) % 16;
+	num_blocks = (payload_len) / 16;
+
+
+
+	// Find start of payload
+	payload_index = HeaderLen + 8; //IV+EIV
+
+	for (i=0; i< num_blocks; i++)
+	{
+		construct_ctr_preload(ctr_preload,
+								a4_exists,
+								qc_exists,
+								pData,
+								PN,
+								i+1 );
+
+		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+		NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
+		payload_index += 16;
+	}
+
+	//
+	// If there is a short final block, then pad it
+	// encrypt it and copy the unpadded part back
+	//
+	if (payload_remainder > 0)
+	{
+		construct_ctr_preload(ctr_preload,
+								a4_exists,
+								qc_exists,
+								pData,
+								PN,
+								num_blocks + 1);
+
+		NdisZeroMemory(padded_buffer, 16);
+		NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+		bitwise_xor(aes_out, padded_buffer, chain_buffer);
+		NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
+		payload_index += payload_remainder;
+	}
+
+	//
+	// Descrypt the MIC
+	//
+	construct_ctr_preload(ctr_preload,
+							a4_exists,
+							qc_exists,
+							pData,
+							PN,
+							0);
+	NdisZeroMemory(padded_buffer, 16);
+	NdisMoveMemory(padded_buffer, pData + payload_index, 8);
+
+	aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+	bitwise_xor(aes_out, padded_buffer, chain_buffer);
+
+	NdisMoveMemory(TrailMIC, chain_buffer, 8);
+
+
+	//
+	// Calculate MIC
+	//
+
+	//Force the protected frame bit on
+	*(pData + 1) = *(pData + 1) | 0x40;
+
+	// Find start of payload
+	// Because the CCMP header has been removed
+	payload_index = HeaderLen;
+
+	construct_mic_iv(
+					mic_iv,
+					qc_exists,
+					a4_exists,
+					pData,
+					payload_len,
+					PN);
+
+	construct_mic_header1(
+						mic_header1,
+						HeaderLen,
+						pData);
+
+	construct_mic_header2(
+						mic_header2,
+						pData,
+						a4_exists,
+						qc_exists);
+
+	aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
+	bitwise_xor(aes_out, mic_header1, chain_buffer);
+	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+	bitwise_xor(aes_out, mic_header2, chain_buffer);
+	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+
+	// iterate through each 16 byte payload block
+	for (i = 0; i < num_blocks; i++)
+	{
+		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+		payload_index += 16;
+		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+	}
+
+	// Add on the final payload block if it needs padding
+	if (payload_remainder > 0)
+	{
+		NdisZeroMemory(padded_buffer, 16);
+		NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+		bitwise_xor(aes_out, padded_buffer, chain_buffer);
+		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+	}
+
+	// aes_out contains padded mic, discard most significant
+	// 8 bytes to generate 64 bit MIC
+	for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
+
+	if (!NdisEqualMemory(MIC, TrailMIC, 8))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n"));	 //MIC error.
+		return FALSE;
+	}
+
+
+	return TRUE;
+}
+
+/* =========================  AES En/Decryption ========================== */
+#ifndef	uint8
+#define	uint8  unsigned	char
+#endif
+
+#ifndef	uint32
+#define	uint32 unsigned	int
+#endif
+
+/* forward S-box */
+static uint32 FSb[256] =
+{
+	0x63, 0x7C,	0x77, 0x7B,	0xF2, 0x6B,	0x6F, 0xC5,
+	0x30, 0x01,	0x67, 0x2B,	0xFE, 0xD7,	0xAB, 0x76,
+	0xCA, 0x82,	0xC9, 0x7D,	0xFA, 0x59,	0x47, 0xF0,
+	0xAD, 0xD4,	0xA2, 0xAF,	0x9C, 0xA4,	0x72, 0xC0,
+	0xB7, 0xFD,	0x93, 0x26,	0x36, 0x3F,	0xF7, 0xCC,
+	0x34, 0xA5,	0xE5, 0xF1,	0x71, 0xD8,	0x31, 0x15,
+	0x04, 0xC7,	0x23, 0xC3,	0x18, 0x96,	0x05, 0x9A,
+	0x07, 0x12,	0x80, 0xE2,	0xEB, 0x27,	0xB2, 0x75,
+	0x09, 0x83,	0x2C, 0x1A,	0x1B, 0x6E,	0x5A, 0xA0,
+	0x52, 0x3B,	0xD6, 0xB3,	0x29, 0xE3,	0x2F, 0x84,
+	0x53, 0xD1,	0x00, 0xED,	0x20, 0xFC,	0xB1, 0x5B,
+	0x6A, 0xCB,	0xBE, 0x39,	0x4A, 0x4C,	0x58, 0xCF,
+	0xD0, 0xEF,	0xAA, 0xFB,	0x43, 0x4D,	0x33, 0x85,
+	0x45, 0xF9,	0x02, 0x7F,	0x50, 0x3C,	0x9F, 0xA8,
+	0x51, 0xA3,	0x40, 0x8F,	0x92, 0x9D,	0x38, 0xF5,
+	0xBC, 0xB6,	0xDA, 0x21,	0x10, 0xFF,	0xF3, 0xD2,
+	0xCD, 0x0C,	0x13, 0xEC,	0x5F, 0x97,	0x44, 0x17,
+	0xC4, 0xA7,	0x7E, 0x3D,	0x64, 0x5D,	0x19, 0x73,
+	0x60, 0x81,	0x4F, 0xDC,	0x22, 0x2A,	0x90, 0x88,
+	0x46, 0xEE,	0xB8, 0x14,	0xDE, 0x5E,	0x0B, 0xDB,
+	0xE0, 0x32,	0x3A, 0x0A,	0x49, 0x06,	0x24, 0x5C,
+	0xC2, 0xD3,	0xAC, 0x62,	0x91, 0x95,	0xE4, 0x79,
+	0xE7, 0xC8,	0x37, 0x6D,	0x8D, 0xD5,	0x4E, 0xA9,
+	0x6C, 0x56,	0xF4, 0xEA,	0x65, 0x7A,	0xAE, 0x08,
+	0xBA, 0x78,	0x25, 0x2E,	0x1C, 0xA6,	0xB4, 0xC6,
+	0xE8, 0xDD,	0x74, 0x1F,	0x4B, 0xBD,	0x8B, 0x8A,
+	0x70, 0x3E,	0xB5, 0x66,	0x48, 0x03,	0xF6, 0x0E,
+	0x61, 0x35,	0x57, 0xB9,	0x86, 0xC1,	0x1D, 0x9E,
+	0xE1, 0xF8,	0x98, 0x11,	0x69, 0xD9,	0x8E, 0x94,
+	0x9B, 0x1E,	0x87, 0xE9,	0xCE, 0x55,	0x28, 0xDF,
+	0x8C, 0xA1,	0x89, 0x0D,	0xBF, 0xE6,	0x42, 0x68,
+	0x41, 0x99,	0x2D, 0x0F,	0xB0, 0x54,	0xBB, 0x16
+};
+
+/* forward table */
+#define	FT \
+\
+	V(C6,63,63,A5),	V(F8,7C,7C,84),	V(EE,77,77,99),	V(F6,7B,7B,8D),	\
+	V(FF,F2,F2,0D),	V(D6,6B,6B,BD),	V(DE,6F,6F,B1),	V(91,C5,C5,54),	\
+	V(60,30,30,50),	V(02,01,01,03),	V(CE,67,67,A9),	V(56,2B,2B,7D),	\
+	V(E7,FE,FE,19),	V(B5,D7,D7,62),	V(4D,AB,AB,E6),	V(EC,76,76,9A),	\
+	V(8F,CA,CA,45),	V(1F,82,82,9D),	V(89,C9,C9,40),	V(FA,7D,7D,87),	\
+	V(EF,FA,FA,15),	V(B2,59,59,EB),	V(8E,47,47,C9),	V(FB,F0,F0,0B),	\
+	V(41,AD,AD,EC),	V(B3,D4,D4,67),	V(5F,A2,A2,FD),	V(45,AF,AF,EA),	\
+	V(23,9C,9C,BF),	V(53,A4,A4,F7),	V(E4,72,72,96),	V(9B,C0,C0,5B),	\
+	V(75,B7,B7,C2),	V(E1,FD,FD,1C),	V(3D,93,93,AE),	V(4C,26,26,6A),	\
+	V(6C,36,36,5A),	V(7E,3F,3F,41),	V(F5,F7,F7,02),	V(83,CC,CC,4F),	\
+	V(68,34,34,5C),	V(51,A5,A5,F4),	V(D1,E5,E5,34),	V(F9,F1,F1,08),	\
+	V(E2,71,71,93),	V(AB,D8,D8,73),	V(62,31,31,53),	V(2A,15,15,3F),	\
+	V(08,04,04,0C),	V(95,C7,C7,52),	V(46,23,23,65),	V(9D,C3,C3,5E),	\
+	V(30,18,18,28),	V(37,96,96,A1),	V(0A,05,05,0F),	V(2F,9A,9A,B5),	\
+	V(0E,07,07,09),	V(24,12,12,36),	V(1B,80,80,9B),	V(DF,E2,E2,3D),	\
+	V(CD,EB,EB,26),	V(4E,27,27,69),	V(7F,B2,B2,CD),	V(EA,75,75,9F),	\
+	V(12,09,09,1B),	V(1D,83,83,9E),	V(58,2C,2C,74),	V(34,1A,1A,2E),	\
+	V(36,1B,1B,2D),	V(DC,6E,6E,B2),	V(B4,5A,5A,EE),	V(5B,A0,A0,FB),	\
+	V(A4,52,52,F6),	V(76,3B,3B,4D),	V(B7,D6,D6,61),	V(7D,B3,B3,CE),	\
+	V(52,29,29,7B),	V(DD,E3,E3,3E),	V(5E,2F,2F,71),	V(13,84,84,97),	\
+	V(A6,53,53,F5),	V(B9,D1,D1,68),	V(00,00,00,00),	V(C1,ED,ED,2C),	\
+	V(40,20,20,60),	V(E3,FC,FC,1F),	V(79,B1,B1,C8),	V(B6,5B,5B,ED),	\
+	V(D4,6A,6A,BE),	V(8D,CB,CB,46),	V(67,BE,BE,D9),	V(72,39,39,4B),	\
+	V(94,4A,4A,DE),	V(98,4C,4C,D4),	V(B0,58,58,E8),	V(85,CF,CF,4A),	\
+	V(BB,D0,D0,6B),	V(C5,EF,EF,2A),	V(4F,AA,AA,E5),	V(ED,FB,FB,16),	\
+	V(86,43,43,C5),	V(9A,4D,4D,D7),	V(66,33,33,55),	V(11,85,85,94),	\
+	V(8A,45,45,CF),	V(E9,F9,F9,10),	V(04,02,02,06),	V(FE,7F,7F,81),	\
+	V(A0,50,50,F0),	V(78,3C,3C,44),	V(25,9F,9F,BA),	V(4B,A8,A8,E3),	\
+	V(A2,51,51,F3),	V(5D,A3,A3,FE),	V(80,40,40,C0),	V(05,8F,8F,8A),	\
+	V(3F,92,92,AD),	V(21,9D,9D,BC),	V(70,38,38,48),	V(F1,F5,F5,04),	\
+	V(63,BC,BC,DF),	V(77,B6,B6,C1),	V(AF,DA,DA,75),	V(42,21,21,63),	\
+	V(20,10,10,30),	V(E5,FF,FF,1A),	V(FD,F3,F3,0E),	V(BF,D2,D2,6D),	\
+	V(81,CD,CD,4C),	V(18,0C,0C,14),	V(26,13,13,35),	V(C3,EC,EC,2F),	\
+	V(BE,5F,5F,E1),	V(35,97,97,A2),	V(88,44,44,CC),	V(2E,17,17,39),	\
+	V(93,C4,C4,57),	V(55,A7,A7,F2),	V(FC,7E,7E,82),	V(7A,3D,3D,47),	\
+	V(C8,64,64,AC),	V(BA,5D,5D,E7),	V(32,19,19,2B),	V(E6,73,73,95),	\
+	V(C0,60,60,A0),	V(19,81,81,98),	V(9E,4F,4F,D1),	V(A3,DC,DC,7F),	\
+	V(44,22,22,66),	V(54,2A,2A,7E),	V(3B,90,90,AB),	V(0B,88,88,83),	\
+	V(8C,46,46,CA),	V(C7,EE,EE,29),	V(6B,B8,B8,D3),	V(28,14,14,3C),	\
+	V(A7,DE,DE,79),	V(BC,5E,5E,E2),	V(16,0B,0B,1D),	V(AD,DB,DB,76),	\
+	V(DB,E0,E0,3B),	V(64,32,32,56),	V(74,3A,3A,4E),	V(14,0A,0A,1E),	\
+	V(92,49,49,DB),	V(0C,06,06,0A),	V(48,24,24,6C),	V(B8,5C,5C,E4),	\
+	V(9F,C2,C2,5D),	V(BD,D3,D3,6E),	V(43,AC,AC,EF),	V(C4,62,62,A6),	\
+	V(39,91,91,A8),	V(31,95,95,A4),	V(D3,E4,E4,37),	V(F2,79,79,8B),	\
+	V(D5,E7,E7,32),	V(8B,C8,C8,43),	V(6E,37,37,59),	V(DA,6D,6D,B7),	\
+	V(01,8D,8D,8C),	V(B1,D5,D5,64),	V(9C,4E,4E,D2),	V(49,A9,A9,E0),	\
+	V(D8,6C,6C,B4),	V(AC,56,56,FA),	V(F3,F4,F4,07),	V(CF,EA,EA,25),	\
+	V(CA,65,65,AF),	V(F4,7A,7A,8E),	V(47,AE,AE,E9),	V(10,08,08,18),	\
+	V(6F,BA,BA,D5),	V(F0,78,78,88),	V(4A,25,25,6F),	V(5C,2E,2E,72),	\
+	V(38,1C,1C,24),	V(57,A6,A6,F1),	V(73,B4,B4,C7),	V(97,C6,C6,51),	\
+	V(CB,E8,E8,23),	V(A1,DD,DD,7C),	V(E8,74,74,9C),	V(3E,1F,1F,21),	\
+	V(96,4B,4B,DD),	V(61,BD,BD,DC),	V(0D,8B,8B,86),	V(0F,8A,8A,85),	\
+	V(E0,70,70,90),	V(7C,3E,3E,42),	V(71,B5,B5,C4),	V(CC,66,66,AA),	\
+	V(90,48,48,D8),	V(06,03,03,05),	V(F7,F6,F6,01),	V(1C,0E,0E,12),	\
+	V(C2,61,61,A3),	V(6A,35,35,5F),	V(AE,57,57,F9),	V(69,B9,B9,D0),	\
+	V(17,86,86,91),	V(99,C1,C1,58),	V(3A,1D,1D,27),	V(27,9E,9E,B9),	\
+	V(D9,E1,E1,38),	V(EB,F8,F8,13),	V(2B,98,98,B3),	V(22,11,11,33),	\
+	V(D2,69,69,BB),	V(A9,D9,D9,70),	V(07,8E,8E,89),	V(33,94,94,A7),	\
+	V(2D,9B,9B,B6),	V(3C,1E,1E,22),	V(15,87,87,92),	V(C9,E9,E9,20),	\
+	V(87,CE,CE,49),	V(AA,55,55,FF),	V(50,28,28,78),	V(A5,DF,DF,7A),	\
+	V(03,8C,8C,8F),	V(59,A1,A1,F8),	V(09,89,89,80),	V(1A,0D,0D,17),	\
+	V(65,BF,BF,DA),	V(D7,E6,E6,31),	V(84,42,42,C6),	V(D0,68,68,B8),	\
+	V(82,41,41,C3),	V(29,99,99,B0),	V(5A,2D,2D,77),	V(1E,0F,0F,11),	\
+	V(7B,B0,B0,CB),	V(A8,54,54,FC),	V(6D,BB,BB,D6),	V(2C,16,16,3A)
+
+#define	V(a,b,c,d) 0x##a##b##c##d
+static uint32 FT0[256] = { FT };
+#undef V
+
+#define	V(a,b,c,d) 0x##d##a##b##c
+static uint32 FT1[256] = { FT };
+#undef V
+
+#define	V(a,b,c,d) 0x##c##d##a##b
+static uint32 FT2[256] = { FT };
+#undef V
+
+#define	V(a,b,c,d) 0x##b##c##d##a
+static uint32 FT3[256] = { FT };
+#undef V
+
+#undef FT
+
+/* reverse S-box */
+
+static uint32 RSb[256] =
+{
+	0x52, 0x09,	0x6A, 0xD5,	0x30, 0x36,	0xA5, 0x38,
+	0xBF, 0x40,	0xA3, 0x9E,	0x81, 0xF3,	0xD7, 0xFB,
+	0x7C, 0xE3,	0x39, 0x82,	0x9B, 0x2F,	0xFF, 0x87,
+	0x34, 0x8E,	0x43, 0x44,	0xC4, 0xDE,	0xE9, 0xCB,
+	0x54, 0x7B,	0x94, 0x32,	0xA6, 0xC2,	0x23, 0x3D,
+	0xEE, 0x4C,	0x95, 0x0B,	0x42, 0xFA,	0xC3, 0x4E,
+	0x08, 0x2E,	0xA1, 0x66,	0x28, 0xD9,	0x24, 0xB2,
+	0x76, 0x5B,	0xA2, 0x49,	0x6D, 0x8B,	0xD1, 0x25,
+	0x72, 0xF8,	0xF6, 0x64,	0x86, 0x68,	0x98, 0x16,
+	0xD4, 0xA4,	0x5C, 0xCC,	0x5D, 0x65,	0xB6, 0x92,
+	0x6C, 0x70,	0x48, 0x50,	0xFD, 0xED,	0xB9, 0xDA,
+	0x5E, 0x15,	0x46, 0x57,	0xA7, 0x8D,	0x9D, 0x84,
+	0x90, 0xD8,	0xAB, 0x00,	0x8C, 0xBC,	0xD3, 0x0A,
+	0xF7, 0xE4,	0x58, 0x05,	0xB8, 0xB3,	0x45, 0x06,
+	0xD0, 0x2C,	0x1E, 0x8F,	0xCA, 0x3F,	0x0F, 0x02,
+	0xC1, 0xAF,	0xBD, 0x03,	0x01, 0x13,	0x8A, 0x6B,
+	0x3A, 0x91,	0x11, 0x41,	0x4F, 0x67,	0xDC, 0xEA,
+	0x97, 0xF2,	0xCF, 0xCE,	0xF0, 0xB4,	0xE6, 0x73,
+	0x96, 0xAC,	0x74, 0x22,	0xE7, 0xAD,	0x35, 0x85,
+	0xE2, 0xF9,	0x37, 0xE8,	0x1C, 0x75,	0xDF, 0x6E,
+	0x47, 0xF1,	0x1A, 0x71,	0x1D, 0x29,	0xC5, 0x89,
+	0x6F, 0xB7,	0x62, 0x0E,	0xAA, 0x18,	0xBE, 0x1B,
+	0xFC, 0x56,	0x3E, 0x4B,	0xC6, 0xD2,	0x79, 0x20,
+	0x9A, 0xDB,	0xC0, 0xFE,	0x78, 0xCD,	0x5A, 0xF4,
+	0x1F, 0xDD,	0xA8, 0x33,	0x88, 0x07,	0xC7, 0x31,
+	0xB1, 0x12,	0x10, 0x59,	0x27, 0x80,	0xEC, 0x5F,
+	0x60, 0x51,	0x7F, 0xA9,	0x19, 0xB5,	0x4A, 0x0D,
+	0x2D, 0xE5,	0x7A, 0x9F,	0x93, 0xC9,	0x9C, 0xEF,
+	0xA0, 0xE0,	0x3B, 0x4D,	0xAE, 0x2A,	0xF5, 0xB0,
+	0xC8, 0xEB,	0xBB, 0x3C,	0x83, 0x53,	0x99, 0x61,
+	0x17, 0x2B,	0x04, 0x7E,	0xBA, 0x77,	0xD6, 0x26,
+	0xE1, 0x69,	0x14, 0x63,	0x55, 0x21,	0x0C, 0x7D
+};
+
+/* reverse table */
+
+#define	RT \
+\
+	V(51,F4,A7,50),	V(7E,41,65,53),	V(1A,17,A4,C3),	V(3A,27,5E,96),	\
+	V(3B,AB,6B,CB),	V(1F,9D,45,F1),	V(AC,FA,58,AB),	V(4B,E3,03,93),	\
+	V(20,30,FA,55),	V(AD,76,6D,F6),	V(88,CC,76,91),	V(F5,02,4C,25),	\
+	V(4F,E5,D7,FC),	V(C5,2A,CB,D7),	V(26,35,44,80),	V(B5,62,A3,8F),	\
+	V(DE,B1,5A,49),	V(25,BA,1B,67),	V(45,EA,0E,98),	V(5D,FE,C0,E1),	\
+	V(C3,2F,75,02),	V(81,4C,F0,12),	V(8D,46,97,A3),	V(6B,D3,F9,C6),	\
+	V(03,8F,5F,E7),	V(15,92,9C,95),	V(BF,6D,7A,EB),	V(95,52,59,DA),	\
+	V(D4,BE,83,2D),	V(58,74,21,D3),	V(49,E0,69,29),	V(8E,C9,C8,44),	\
+	V(75,C2,89,6A),	V(F4,8E,79,78),	V(99,58,3E,6B),	V(27,B9,71,DD),	\
+	V(BE,E1,4F,B6),	V(F0,88,AD,17),	V(C9,20,AC,66),	V(7D,CE,3A,B4),	\
+	V(63,DF,4A,18),	V(E5,1A,31,82),	V(97,51,33,60),	V(62,53,7F,45),	\
+	V(B1,64,77,E0),	V(BB,6B,AE,84),	V(FE,81,A0,1C),	V(F9,08,2B,94),	\
+	V(70,48,68,58),	V(8F,45,FD,19),	V(94,DE,6C,87),	V(52,7B,F8,B7),	\
+	V(AB,73,D3,23),	V(72,4B,02,E2),	V(E3,1F,8F,57),	V(66,55,AB,2A),	\
+	V(B2,EB,28,07),	V(2F,B5,C2,03),	V(86,C5,7B,9A),	V(D3,37,08,A5),	\
+	V(30,28,87,F2),	V(23,BF,A5,B2),	V(02,03,6A,BA),	V(ED,16,82,5C),	\
+	V(8A,CF,1C,2B),	V(A7,79,B4,92),	V(F3,07,F2,F0),	V(4E,69,E2,A1),	\
+	V(65,DA,F4,CD),	V(06,05,BE,D5),	V(D1,34,62,1F),	V(C4,A6,FE,8A),	\
+	V(34,2E,53,9D),	V(A2,F3,55,A0),	V(05,8A,E1,32),	V(A4,F6,EB,75),	\
+	V(0B,83,EC,39),	V(40,60,EF,AA),	V(5E,71,9F,06),	V(BD,6E,10,51),	\
+	V(3E,21,8A,F9),	V(96,DD,06,3D),	V(DD,3E,05,AE),	V(4D,E6,BD,46),	\
+	V(91,54,8D,B5),	V(71,C4,5D,05),	V(04,06,D4,6F),	V(60,50,15,FF),	\
+	V(19,98,FB,24),	V(D6,BD,E9,97),	V(89,40,43,CC),	V(67,D9,9E,77),	\
+	V(B0,E8,42,BD),	V(07,89,8B,88),	V(E7,19,5B,38),	V(79,C8,EE,DB),	\
+	V(A1,7C,0A,47),	V(7C,42,0F,E9),	V(F8,84,1E,C9),	V(00,00,00,00),	\
+	V(09,80,86,83),	V(32,2B,ED,48),	V(1E,11,70,AC),	V(6C,5A,72,4E),	\
+	V(FD,0E,FF,FB),	V(0F,85,38,56),	V(3D,AE,D5,1E),	V(36,2D,39,27),	\
+	V(0A,0F,D9,64),	V(68,5C,A6,21),	V(9B,5B,54,D1),	V(24,36,2E,3A),	\
+	V(0C,0A,67,B1),	V(93,57,E7,0F),	V(B4,EE,96,D2),	V(1B,9B,91,9E),	\
+	V(80,C0,C5,4F),	V(61,DC,20,A2),	V(5A,77,4B,69),	V(1C,12,1A,16),	\
+	V(E2,93,BA,0A),	V(C0,A0,2A,E5),	V(3C,22,E0,43),	V(12,1B,17,1D),	\
+	V(0E,09,0D,0B),	V(F2,8B,C7,AD),	V(2D,B6,A8,B9),	V(14,1E,A9,C8),	\
+	V(57,F1,19,85),	V(AF,75,07,4C),	V(EE,99,DD,BB),	V(A3,7F,60,FD),	\
+	V(F7,01,26,9F),	V(5C,72,F5,BC),	V(44,66,3B,C5),	V(5B,FB,7E,34),	\
+	V(8B,43,29,76),	V(CB,23,C6,DC),	V(B6,ED,FC,68),	V(B8,E4,F1,63),	\
+	V(D7,31,DC,CA),	V(42,63,85,10),	V(13,97,22,40),	V(84,C6,11,20),	\
+	V(85,4A,24,7D),	V(D2,BB,3D,F8),	V(AE,F9,32,11),	V(C7,29,A1,6D),	\
+	V(1D,9E,2F,4B),	V(DC,B2,30,F3),	V(0D,86,52,EC),	V(77,C1,E3,D0),	\
+	V(2B,B3,16,6C),	V(A9,70,B9,99),	V(11,94,48,FA),	V(47,E9,64,22),	\
+	V(A8,FC,8C,C4),	V(A0,F0,3F,1A),	V(56,7D,2C,D8),	V(22,33,90,EF),	\
+	V(87,49,4E,C7),	V(D9,38,D1,C1),	V(8C,CA,A2,FE),	V(98,D4,0B,36),	\
+	V(A6,F5,81,CF),	V(A5,7A,DE,28),	V(DA,B7,8E,26),	V(3F,AD,BF,A4),	\
+	V(2C,3A,9D,E4),	V(50,78,92,0D),	V(6A,5F,CC,9B),	V(54,7E,46,62),	\
+	V(F6,8D,13,C2),	V(90,D8,B8,E8),	V(2E,39,F7,5E),	V(82,C3,AF,F5),	\
+	V(9F,5D,80,BE),	V(69,D0,93,7C),	V(6F,D5,2D,A9),	V(CF,25,12,B3),	\
+	V(C8,AC,99,3B),	V(10,18,7D,A7),	V(E8,9C,63,6E),	V(DB,3B,BB,7B),	\
+	V(CD,26,78,09),	V(6E,59,18,F4),	V(EC,9A,B7,01),	V(83,4F,9A,A8),	\
+	V(E6,95,6E,65),	V(AA,FF,E6,7E),	V(21,BC,CF,08),	V(EF,15,E8,E6),	\
+	V(BA,E7,9B,D9),	V(4A,6F,36,CE),	V(EA,9F,09,D4),	V(29,B0,7C,D6),	\
+	V(31,A4,B2,AF),	V(2A,3F,23,31),	V(C6,A5,94,30),	V(35,A2,66,C0),	\
+	V(74,4E,BC,37),	V(FC,82,CA,A6),	V(E0,90,D0,B0),	V(33,A7,D8,15),	\
+	V(F1,04,98,4A),	V(41,EC,DA,F7),	V(7F,CD,50,0E),	V(17,91,F6,2F),	\
+	V(76,4D,D6,8D),	V(43,EF,B0,4D),	V(CC,AA,4D,54),	V(E4,96,04,DF),	\
+	V(9E,D1,B5,E3),	V(4C,6A,88,1B),	V(C1,2C,1F,B8),	V(46,65,51,7F),	\
+	V(9D,5E,EA,04),	V(01,8C,35,5D),	V(FA,87,74,73),	V(FB,0B,41,2E),	\
+	V(B3,67,1D,5A),	V(92,DB,D2,52),	V(E9,10,56,33),	V(6D,D6,47,13),	\
+	V(9A,D7,61,8C),	V(37,A1,0C,7A),	V(59,F8,14,8E),	V(EB,13,3C,89),	\
+	V(CE,A9,27,EE),	V(B7,61,C9,35),	V(E1,1C,E5,ED),	V(7A,47,B1,3C),	\
+	V(9C,D2,DF,59),	V(55,F2,73,3F),	V(18,14,CE,79),	V(73,C7,37,BF),	\
+	V(53,F7,CD,EA),	V(5F,FD,AA,5B),	V(DF,3D,6F,14),	V(78,44,DB,86),	\
+	V(CA,AF,F3,81),	V(B9,68,C4,3E),	V(38,24,34,2C),	V(C2,A3,40,5F),	\
+	V(16,1D,C3,72),	V(BC,E2,25,0C),	V(28,3C,49,8B),	V(FF,0D,95,41),	\
+	V(39,A8,01,71),	V(08,0C,B3,DE),	V(D8,B4,E4,9C),	V(64,56,C1,90),	\
+	V(7B,CB,84,61),	V(D5,32,B6,70),	V(48,6C,5C,74),	V(D0,B8,57,42)
+
+#define	V(a,b,c,d) 0x##a##b##c##d
+static uint32 RT0[256] = { RT };
+#undef V
+
+#define	V(a,b,c,d) 0x##d##a##b##c
+static uint32 RT1[256] = { RT };
+#undef V
+
+#define	V(a,b,c,d) 0x##c##d##a##b
+static uint32 RT2[256] = { RT };
+#undef V
+
+#define	V(a,b,c,d) 0x##b##c##d##a
+static uint32 RT3[256] = { RT };
+#undef V
+
+#undef RT
+
+/* round constants */
+
+static uint32 RCON[10] =
+{
+	0x01000000,	0x02000000,	0x04000000,	0x08000000,
+	0x10000000,	0x20000000,	0x40000000,	0x80000000,
+	0x1B000000,	0x36000000
+};
+
+/* key schedule	tables */
+
+static int KT_init = 1;
+
+static uint32 KT0[256];
+static uint32 KT1[256];
+static uint32 KT2[256];
+static uint32 KT3[256];
+
+/* platform-independant	32-bit integer manipulation	macros */
+
+#define	GET_UINT32(n,b,i)						\
+{												\
+	(n)	= (	(uint32) (b)[(i)	] << 24	)		\
+		| (	(uint32) (b)[(i) + 1] << 16	)		\
+		| (	(uint32) (b)[(i) + 2] <<  8	)		\
+		| (	(uint32) (b)[(i) + 3]		);		\
+}
+
+#define	PUT_UINT32(n,b,i)						\
+{												\
+	(b)[(i)	   ] = (uint8) ( (n) >>	24 );		\
+	(b)[(i)	+ 1] = (uint8) ( (n) >>	16 );		\
+	(b)[(i)	+ 2] = (uint8) ( (n) >>	 8 );		\
+	(b)[(i)	+ 3] = (uint8) ( (n)	   );		\
+}
+
+
+int	rt_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
+{
+	int	i;
+	uint32 *RK,	*SK;
+
+	switch(	nbits )
+	{
+		case 128: ctx->nr =	10;	break;
+		case 192: ctx->nr =	12;	break;
+		case 256: ctx->nr =	14;	break;
+		default	: return( 1	);
+	}
+
+	RK = (uint32 *) ctx->erk;
+
+	for( i = 0;	i <	(nbits >> 5); i++ )
+	{
+		GET_UINT32(	RK[i], key,	i *	4 );
+	}
+
+	/* setup encryption	round keys */
+
+	switch(	nbits )
+	{
+	case 128:
+
+		for( i = 0;	i <	10;	i++, RK	+= 4 )
+		{
+			RK[4]  = RK[0] ^ RCON[i] ^
+						( FSb[ (uint8) ( RK[3] >> 16 ) ] <<	24 ) ^
+						( FSb[ (uint8) ( RK[3] >>  8 ) ] <<	16 ) ^
+						( FSb[ (uint8) ( RK[3]		 ) ] <<	 8 ) ^
+						( FSb[ (uint8) ( RK[3] >> 24 ) ]	   );
+
+			RK[5]  = RK[1] ^ RK[4];
+			RK[6]  = RK[2] ^ RK[5];
+			RK[7]  = RK[3] ^ RK[6];
+		}
+		break;
+
+	case 192:
+
+		for( i = 0;	i <	8; i++,	RK += 6	)
+		{
+			RK[6]  = RK[0] ^ RCON[i] ^
+						( FSb[ (uint8) ( RK[5] >> 16 ) ] <<	24 ) ^
+						( FSb[ (uint8) ( RK[5] >>  8 ) ] <<	16 ) ^
+						( FSb[ (uint8) ( RK[5]		 ) ] <<	 8 ) ^
+						( FSb[ (uint8) ( RK[5] >> 24 ) ]	   );
+
+			RK[7]  = RK[1] ^ RK[6];
+			RK[8]  = RK[2] ^ RK[7];
+			RK[9]  = RK[3] ^ RK[8];
+			RK[10] = RK[4] ^ RK[9];
+			RK[11] = RK[5] ^ RK[10];
+		}
+		break;
+
+	case 256:
+
+		for( i = 0;	i <	7; i++,	RK += 8	)
+		{
+			RK[8]  = RK[0] ^ RCON[i] ^
+						( FSb[ (uint8) ( RK[7] >> 16 ) ] <<	24 ) ^
+						( FSb[ (uint8) ( RK[7] >>  8 ) ] <<	16 ) ^
+						( FSb[ (uint8) ( RK[7]		 ) ] <<	 8 ) ^
+						( FSb[ (uint8) ( RK[7] >> 24 ) ]	   );
+
+			RK[9]  = RK[1] ^ RK[8];
+			RK[10] = RK[2] ^ RK[9];
+			RK[11] = RK[3] ^ RK[10];
+
+			RK[12] = RK[4] ^
+						( FSb[ (uint8) ( RK[11]	>> 24 )	] << 24	) ^
+						( FSb[ (uint8) ( RK[11]	>> 16 )	] << 16	) ^
+						( FSb[ (uint8) ( RK[11]	>>	8 )	] <<  8	) ^
+						( FSb[ (uint8) ( RK[11]		  )	]		);
+
+			RK[13] = RK[5] ^ RK[12];
+			RK[14] = RK[6] ^ RK[13];
+			RK[15] = RK[7] ^ RK[14];
+		}
+		break;
+	}
+
+	/* setup decryption	round keys */
+
+	if(	KT_init	)
+	{
+		for( i = 0;	i <	256; i++ )
+		{
+			KT0[i] = RT0[ FSb[i] ];
+			KT1[i] = RT1[ FSb[i] ];
+			KT2[i] = RT2[ FSb[i] ];
+			KT3[i] = RT3[ FSb[i] ];
+		}
+
+		KT_init	= 0;
+	}
+
+	SK = (uint32 *) ctx->drk;
+
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+
+	for( i = 1;	i <	ctx->nr; i++ )
+	{
+		RK -= 8;
+
+		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
+				KT1[ (uint8) ( *RK >> 16 ) ] ^
+				KT2[ (uint8) ( *RK >>  8 ) ] ^
+				KT3[ (uint8) ( *RK		 ) ]; RK++;
+
+		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
+				KT1[ (uint8) ( *RK >> 16 ) ] ^
+				KT2[ (uint8) ( *RK >>  8 ) ] ^
+				KT3[ (uint8) ( *RK		 ) ]; RK++;
+
+		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
+				KT1[ (uint8) ( *RK >> 16 ) ] ^
+				KT2[ (uint8) ( *RK >>  8 ) ] ^
+				KT3[ (uint8) ( *RK		 ) ]; RK++;
+
+		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
+				KT1[ (uint8) ( *RK >> 16 ) ] ^
+				KT2[ (uint8) ( *RK >>  8 ) ] ^
+				KT3[ (uint8) ( *RK		 ) ]; RK++;
+	}
+
+	RK -= 8;
+
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+
+	return(	0 );
+}
+
+/* AES 128-bit block encryption	routine	*/
+
+void rt_aes_encrypt(aes_context *ctx, uint8 input[16],	uint8 output[16] )
+{
+	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
+
+	RK = (uint32 *) ctx->erk;
+	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];
+	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];
+	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];
+	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];
+
+#define	AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
+{												\
+	RK += 4;									\
+												\
+	X0 = RK[0] ^ FT0[ (uint8) (	Y0 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y1 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y2 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y3		 ) ];	\
+												\
+	X1 = RK[1] ^ FT0[ (uint8) (	Y1 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y2 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y3 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y0		 ) ];	\
+												\
+	X2 = RK[2] ^ FT0[ (uint8) (	Y2 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y3 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y0 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y1		 ) ];	\
+												\
+	X3 = RK[3] ^ FT0[ (uint8) (	Y3 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y0 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y1 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y2		 ) ];	\
+}
+
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */
+	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */
+	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */
+	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */
+	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */
+
+	if(	ctx->nr	> 10 )
+	{
+		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/
+		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/
+	}
+
+	if(	ctx->nr	> 12 )
+	{
+		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/
+		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/
+	}
+
+	/* last	round */
+
+	RK += 4;
+
+	X0 = RK[0] ^ ( FSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^
+				 ( FSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^
+				 ( FSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^
+				 ( FSb[	(uint8)	( Y3	   ) ]		 );
+
+	X1 = RK[1] ^ ( FSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^
+				 ( FSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^
+				 ( FSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^
+				 ( FSb[	(uint8)	( Y0	   ) ]		 );
+
+	X2 = RK[2] ^ ( FSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^
+				 ( FSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^
+				 ( FSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^
+				 ( FSb[	(uint8)	( Y1	   ) ]		 );
+
+	X3 = RK[3] ^ ( FSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^
+				 ( FSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^
+				 ( FSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^
+				 ( FSb[	(uint8)	( Y2	   ) ]		 );
+
+	PUT_UINT32(	X0,	output,	 0 );
+	PUT_UINT32(	X1,	output,	 4 );
+	PUT_UINT32(	X2,	output,	 8 );
+	PUT_UINT32(	X3,	output,	12 );
+}
+
+/* AES 128-bit block decryption	routine	*/
+
+void rt_aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] )
+{
+	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
+
+	RK = (uint32 *) ctx->drk;
+
+	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];
+	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];
+	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];
+	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];
+
+#define	AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
+{												\
+	RK += 4;									\
+												\
+	X0 = RK[0] ^ RT0[ (uint8) (	Y0 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y3 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y2 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y1		 ) ];	\
+												\
+	X1 = RK[1] ^ RT0[ (uint8) (	Y1 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y0 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y3 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y2		 ) ];	\
+												\
+	X2 = RK[2] ^ RT0[ (uint8) (	Y2 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y1 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y0 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y3		 ) ];	\
+												\
+	X3 = RK[3] ^ RT0[ (uint8) (	Y3 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y2 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y1 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y0		 ) ];	\
+}
+
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */
+	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */
+	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */
+	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */
+	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */
+
+	if(	ctx->nr	> 10 )
+	{
+		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/
+		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/
+	}
+
+	if(	ctx->nr	> 12 )
+	{
+		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/
+		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/
+	}
+
+	/* last	round */
+
+	RK += 4;
+
+	X0 = RK[0] ^ ( RSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^
+				 ( RSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^
+				 ( RSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^
+				 ( RSb[	(uint8)	( Y1	   ) ]		 );
+
+	X1 = RK[1] ^ ( RSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^
+				 ( RSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^
+				 ( RSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^
+				 ( RSb[	(uint8)	( Y2	   ) ]		 );
+
+	X2 = RK[2] ^ ( RSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^
+				 ( RSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^
+				 ( RSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^
+				 ( RSb[	(uint8)	( Y3	   ) ]		 );
+
+	X3 = RK[3] ^ ( RSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^
+				 ( RSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^
+				 ( RSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^
+				 ( RSb[	(uint8)	( Y0	   ) ]		 );
+
+	PUT_UINT32(	X0,	output,	 0 );
+	PUT_UINT32(	X1,	output,	 4 );
+	PUT_UINT32(	X2,	output,	 8 );
+	PUT_UINT32(	X3,	output,	12 );
+}
+
+/*
+    ==========================================================================
+    Description:
+        ENCRYPT AES GTK before sending in EAPOL frame.
+        AES GTK length = 128 bit,  so fix blocks for aes-key-wrap as 2 in this function.
+        This function references to RFC 3394 for aes key wrap algorithm.
+    Return:
+    ==========================================================================
+*/
+VOID AES_GTK_KEY_WRAP(
+    IN UCHAR    *key,
+    IN UCHAR    *plaintext,
+    IN UINT32    p_len,
+    OUT UCHAR   *ciphertext)
+{
+    UCHAR       A[8], BIN[16], BOUT[16];
+    UCHAR       R[512];
+    INT         num_blocks = p_len/8;   // unit:64bits
+    INT         i, j;
+    aes_context aesctx;
+    UCHAR       xor;
+
+    rt_aes_set_key(&aesctx, key, 128);
+
+    // Init IA
+    for (i = 0; i < 8; i++)
+        A[i] = 0xa6;
+
+    //Input plaintext
+    for (i = 0; i < num_blocks; i++)
+    {
+        for (j = 0 ; j < 8; j++)
+            R[8 * (i + 1) + j] = plaintext[8 * i + j];
+    }
+
+    // Key Mix
+    for (j = 0; j < 6; j++)
+    {
+        for(i = 1; i <= num_blocks; i++)
+        {
+            //phase 1
+            NdisMoveMemory(BIN, A, 8);
+            NdisMoveMemory(&BIN[8], &R[8 * i], 8);
+            rt_aes_encrypt(&aesctx, BIN, BOUT);
+
+            NdisMoveMemory(A, &BOUT[0], 8);
+            xor = num_blocks * j + i;
+            A[7] = BOUT[7] ^ xor;
+            NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
+        }
+    }
+
+    // Output ciphertext
+    NdisMoveMemory(ciphertext, A, 8);
+
+    for (i = 1; i <= num_blocks; i++)
+    {
+        for (j = 0 ; j < 8; j++)
+            ciphertext[8 * i + j] = R[8 * i + j];
+    }
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Misc function to decrypt AES body
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+		This function references to	RFC	3394 for aes key unwrap algorithm.
+
+	========================================================================
+*/
+VOID	AES_GTK_KEY_UNWRAP(
+	IN	UCHAR	*key,
+	OUT	UCHAR	*plaintext,
+	IN	UINT32   c_len,
+	IN	UCHAR	*ciphertext)
+
+{
+	UCHAR       A[8], BIN[16], BOUT[16];
+	UCHAR       xor;
+	INT         i, j;
+	aes_context aesctx;
+	UCHAR       *R;
+	INT         num_blocks = c_len/8;	// unit:64bits
+
+
+	os_alloc_mem(NULL, (PUCHAR *)&R, 512);
+
+	if (R == NULL)
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
+        return;
+    } /* End of if */
+
+	// Initialize
+	NdisMoveMemory(A, ciphertext, 8);
+	//Input plaintext
+	for(i = 0; i < (c_len-8); i++)
+	{
+		R[ i] = ciphertext[i + 8];
+	}
+
+	rt_aes_set_key(&aesctx, key, 128);
+
+	for(j = 5; j >= 0; j--)
+	{
+		for(i = (num_blocks-1); i > 0; i--)
+		{
+			xor = (num_blocks -1 )* j + i;
+			NdisMoveMemory(BIN, A, 8);
+			BIN[7] = A[7] ^ xor;
+			NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
+			rt_aes_decrypt(&aesctx, BIN, BOUT);
+			NdisMoveMemory(A, &BOUT[0], 8);
+			NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
+		}
+	}
+
+	// OUTPUT
+	for(i = 0; i < c_len; i++)
+	{
+		plaintext[i] = R[i];
+	}
+
+
+	os_free_mem(NULL, R);
+}
diff --git a/drivers/staging/rt2860/common/cmm_asic.c b/drivers/staging/rt2860/common/cmm_asic.c
new file mode 100644
index 0000000..83ed07b
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_asic.c
@@ -0,0 +1,2531 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	cmm_asic.c
+
+	Abstract:
+	Functions used to communicate with ASIC
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+
+// Reset the RFIC setting to new series
+RTMP_RF_REGS RF2850RegTable[] = {
+//		ch	 R1		 R2		 R3(TX0~4=0) R4
+		{1,  0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
+		{2,  0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
+		{3,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
+		{4,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
+		{5,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
+		{6,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
+		{7,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
+		{8,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
+		{9,  0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
+		{10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
+		{11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
+		{12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
+		{13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
+		{14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
+
+		// 802.11 UNI / HyperLan 2
+		{36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
+		{38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
+		{40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
+		{44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
+		{46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
+		{48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
+		{52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
+		{54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
+		{56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
+		{60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
+		{62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
+		{64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
+
+		// 802.11 HyperLan 2
+		{100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
+
+		// 2008.04.30 modified
+		// The system team has AN to improve the EVM value
+		// for channel 102 to 108 for the RT2850/RT2750 dual band solution.
+		{102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
+		{104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
+		{108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
+
+		{110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
+		{112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
+		{116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
+		{118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
+		{120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
+		{124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
+		{126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
+		{128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
+		{132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
+		{134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
+		{136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
+		{140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
+
+		// 802.11 UNII
+		{149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
+		{151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
+		{153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
+		{157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
+		{159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
+		{161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
+		{165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
+		{167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f},
+		{169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327},
+		{171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307},
+		{173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f},
+
+		// Japan
+		{184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
+		{188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
+		{192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
+		{196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
+		{208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
+		{212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
+		{216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
+
+		// still lack of MMAC(Japan) ch 34,38,42,46
+};
+UCHAR	NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
+
+FREQUENCY_ITEM FreqItems3020[] =
+{
+	/**************************************************/
+	// ISM : 2.4 to 2.483 GHz                         //
+	/**************************************************/
+	// 11g
+	/**************************************************/
+	//-CH---N-------R---K-----------
+	{1,    241,  2,  2},
+	{2,    241,	 2,  7},
+	{3,    242,	 2,  2},
+	{4,    242,	 2,  7},
+	{5,    243,	 2,  2},
+	{6,    243,	 2,  7},
+	{7,    244,	 2,  2},
+	{8,    244,	 2,  7},
+	{9,    245,	 2,  2},
+	{10,   245,	 2,  7},
+	{11,   246,	 2,  2},
+	{12,   246,	 2,  7},
+	{13,   247,	 2,  2},
+	{14,   248,	 2,  4},
+};
+UCHAR	NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
+
+
+VOID AsicUpdateAutoFallBackTable(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pRateTable)
+{
+	UCHAR					i;
+	HT_FBK_CFG0_STRUC		HtCfg0;
+	HT_FBK_CFG1_STRUC		HtCfg1;
+	LG_FBK_CFG0_STRUC		LgCfg0;
+	LG_FBK_CFG1_STRUC		LgCfg1;
+	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate;
+
+	// set to initial value
+	HtCfg0.word = 0x65432100;
+	HtCfg1.word = 0xedcba988;
+	LgCfg0.word = 0xedcba988;
+	LgCfg1.word = 0x00002100;
+
+	pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
+	for (i = 1; i < *((PUCHAR) pRateTable); i++)
+	{
+		pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
+		switch (pCurrTxRate->Mode)
+		{
+			case 0:		//CCK
+				break;
+			case 1:		//OFDM
+				{
+					switch(pCurrTxRate->CurrMCS)
+					{
+						case 0:
+							LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 1:
+							LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 2:
+							LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 3:
+							LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 4:
+							LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 5:
+							LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 6:
+							LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 7:
+							LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+					}
+				}
+				break;
+			case 2:		//HT-MIX
+			case 3:		//HT-GF
+				{
+					if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
+					{
+						switch(pCurrTxRate->CurrMCS)
+						{
+							case 0:
+								HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
+								break;
+							case 1:
+								HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
+								break;
+							case 2:
+								HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
+								break;
+							case 3:
+								HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
+								break;
+							case 4:
+								HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
+								break;
+							case 5:
+								HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
+								break;
+							case 6:
+								HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
+								break;
+							case 7:
+								HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
+								break;
+							case 8:
+								HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
+								break;
+							case 9:
+								HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
+								break;
+							case 10:
+								HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
+								break;
+							case 11:
+								HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
+								break;
+							case 12:
+								HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
+								break;
+							case 13:
+								HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
+								break;
+							case 14:
+								HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
+								break;
+							case 15:
+								HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
+								break;
+							default:
+								DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
+						}
+					}
+				}
+				break;
+		}
+
+		pNextTxRate = pCurrTxRate;
+	}
+
+	RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
+	RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
+	RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
+	RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Set MAC register value according operation mode.
+		OperationMode AND bNonGFExist are for MM and GF Proteciton.
+		If MM or GF mask is not set, those passing argument doesn't not take effect.
+
+		Operation mode meaning:
+		= 0 : Pure HT, no preotection.
+		= 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
+		= 0x10: No Transmission in 40M is protected.
+		= 0x11: Transmission in both 40M and 20M shall be protected
+		if (bNonGFExist)
+			we should choose not to use GF. But still set correct ASIC registers.
+	========================================================================
+*/
+VOID	AsicUpdateProtect(
+	IN		PRTMP_ADAPTER	pAd,
+	IN		USHORT			OperationMode,
+	IN		UCHAR			SetMask,
+	IN		BOOLEAN			bDisableBGProtect,
+	IN		BOOLEAN			bNonGFExist)
+{
+	PROT_CFG_STRUC	ProtCfg, ProtCfg4;
+	UINT32 Protect[6];
+	USHORT			offset;
+	UCHAR			i;
+	UINT32 MacReg = 0;
+
+
+	if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
+	{
+		return;
+	}
+
+	if (pAd->BATable.numDoneOriginator)
+	{
+		//
+		// enable the RTS/CTS to avoid channel collision
+		//
+		SetMask = ALLN_SETPROTECT;
+		OperationMode = 8;
+	}
+
+	// Config ASIC RTS threshold register
+	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+	MacReg &= 0xFF0000FF;
+	// If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
+        if ((
+			(pAd->CommonCfg.BACapability.field.AmsduEnable) ||
+			(pAd->CommonCfg.bAggregationCapable == TRUE))
+            && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
+        {
+			MacReg |= (0x1000 << 8);
+        }
+        else
+        {
+			MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+        }
+
+	RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+	// Initial common protection settings
+	RTMPZeroMemory(Protect, sizeof(Protect));
+	ProtCfg4.word = 0;
+	ProtCfg.word = 0;
+	ProtCfg.field.TxopAllowGF40 = 1;
+	ProtCfg.field.TxopAllowGF20 = 1;
+	ProtCfg.field.TxopAllowMM40 = 1;
+	ProtCfg.field.TxopAllowMM20 = 1;
+	ProtCfg.field.TxopAllowOfdm = 1;
+	ProtCfg.field.TxopAllowCck = 1;
+	ProtCfg.field.RTSThEn = 1;
+	ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+	// update PHY mode and rate
+	if (pAd->CommonCfg.Channel > 14)
+		ProtCfg.field.ProtectRate = 0x4000;
+	ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
+
+	// Handle legacy(B/G) protection
+	if (bDisableBGProtect)
+	{
+		//ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+		ProtCfg.field.ProtectCtrl = 0;
+		Protect[0] = ProtCfg.word;
+		Protect[1] = ProtCfg.word;
+		pAd->FlgCtsEnabled = 0; /* CTS-self is not used */
+	}
+	else
+	{
+		//ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+		ProtCfg.field.ProtectCtrl = 0;			// CCK do not need to be protected
+		Protect[0] = ProtCfg.word;
+		ProtCfg.field.ProtectCtrl = ASIC_CTS;	// OFDM needs using CCK to protect
+		Protect[1] = ProtCfg.word;
+		pAd->FlgCtsEnabled = 1; /* CTS-self is used */
+	}
+
+	// Decide HT frame protection.
+	if ((SetMask & ALLN_SETPROTECT) != 0)
+	{
+		switch(OperationMode)
+		{
+			case 0x0:
+				// NO PROTECT
+				// 1.All STAs in the BSS are 20/40 MHz HT
+				// 2. in ai 20/40MHz BSS
+				// 3. all STAs are 20MHz in a 20MHz BSS
+				// Pure HT. no protection.
+
+				// MM20_PROT_CFG
+				//	Reserved (31:27)
+				//	PROT_TXOP(25:20) -- 010111
+				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+				//  PROT_CTRL(17:16) -- 00 (None)
+				//	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
+				Protect[2] = 0x01744004;
+
+				// MM40_PROT_CFG
+				//	Reserved (31:27)
+				//	PROT_TXOP(25:20) -- 111111
+				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+				//  PROT_CTRL(17:16) -- 00 (None)
+				//	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
+				Protect[3] = 0x03f44084;
+
+				// CF20_PROT_CFG
+				//	Reserved (31:27)
+				//	PROT_TXOP(25:20) -- 010111
+				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+				//  PROT_CTRL(17:16) -- 00 (None)
+				//	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
+				Protect[4] = 0x01744004;
+
+				// CF40_PROT_CFG
+				//	Reserved (31:27)
+				//	PROT_TXOP(25:20) -- 111111
+				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+				//  PROT_CTRL(17:16) -- 00 (None)
+				//	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
+				Protect[5] = 0x03f44084;
+
+				if (bNonGFExist)
+				{
+					// PROT_NAV(19:18)  -- 01 (Short NAV protectiion)
+					// PROT_CTRL(17:16) -- 01 (RTS/CTS)
+					Protect[4] = 0x01754004;
+					Protect[5] = 0x03f54084;
+				}
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+				break;
+
+			case 1:
+				// This is "HT non-member protection mode."
+				// If there may be non-HT STAs my BSS
+				ProtCfg.word = 0x01744004;	// PROT_CTRL(17:16) : 0 (None)
+				ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
+				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+				{
+					ProtCfg.word = 0x01740003;	//ERP use Protection bit is set, use protection rate at Clause 18..
+					ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
+				}
+				//Assign Protection method for 20&40 MHz packets
+				ProtCfg.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+				Protect[2] = ProtCfg.word;
+				Protect[3] = ProtCfg4.word;
+				Protect[4] = ProtCfg.word;
+				Protect[5] = ProtCfg4.word;
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+				break;
+
+			case 2:
+				// If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
+				ProtCfg.word = 0x01744004;  // PROT_CTRL(17:16) : 0 (None)
+				ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
+
+				//Assign Protection method for 40MHz packets
+				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+				Protect[2] = ProtCfg.word;
+				Protect[3] = ProtCfg4.word;
+				if (bNonGFExist)
+				{
+					ProtCfg.field.ProtectCtrl = ASIC_RTS;
+					ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+				}
+				Protect[4] = ProtCfg.word;
+				Protect[5] = ProtCfg4.word;
+
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+				break;
+
+			case 3:
+				// HT mixed mode.	 PROTECT ALL!
+				// Assign Rate
+				ProtCfg.word = 0x01744004;	//duplicaet legacy 24M. BW set 1.
+				ProtCfg4.word = 0x03f44084;
+				// both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
+				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+				{
+					ProtCfg.word = 0x01740003;	//ERP use Protection bit is set, use protection rate at Clause 18..
+					ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
+				}
+				//Assign Protection method for 20&40 MHz packets
+				ProtCfg.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+				Protect[2] = ProtCfg.word;
+				Protect[3] = ProtCfg4.word;
+				Protect[4] = ProtCfg.word;
+				Protect[5] = ProtCfg4.word;
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+				break;
+
+			case 8:
+				// Special on for Atheros problem n chip.
+				Protect[2] = 0x01754004;
+				Protect[3] = 0x03f54084;
+				Protect[4] = 0x01754004;
+				Protect[5] = 0x03f54084;
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+				break;
+		}
+	}
+
+	offset = CCK_PROT_CFG;
+	for (i = 0;i < 6;i++)
+	{
+			if ((SetMask & (1<< i)))
+		{
+		RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+	}
+}
+}
+
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicSwitchChannel(
+					  IN PRTMP_ADAPTER pAd,
+	IN	UCHAR			Channel,
+	IN	BOOLEAN			bScan)
+{
+	ULONG			R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
+	CHAR    TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
+	UCHAR	index;
+	UINT32	Value = 0; //BbpReg, Value;
+	RTMP_RF_REGS *RFRegTable;
+	UCHAR	RFValue;
+
+	RFValue = 0;
+	// Search Tx power value
+	// We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
+	// in ChannelList, so use TxPower array instead.
+	//
+	for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
+	{
+		if (Channel == pAd->TxPower[index].Channel)
+		{
+			TxPwer = pAd->TxPower[index].Power;
+			TxPwer2 = pAd->TxPower[index].Power2;
+			break;
+		}
+	}
+
+	if (index == MAX_NUM_OF_CHANNELS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
+	}
+
+#ifdef RT30xx
+	// The RF programming sequence is difference between 3xxx and 2xxx
+	if ((IS_RT3070(pAd) || IS_RT3090(pAd)||IS_RT3390(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
+		(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
+	{
+		/* modify by WY for Read RF Reg. error */
+
+		for (index = 0; index < NUM_OF_3020_CHNL; index++)
+		{
+			if (Channel == FreqItems3020[index].Channel)
+			{
+				// Programming channel parameters
+				RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
+				RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
+				RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
+				RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
+				RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
+
+				// Set Tx0 Power
+				RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
+				RFValue = (RFValue & 0xE0) | TxPwer;
+				RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
+
+				// Set Tx1 Power
+				RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
+				RFValue = (RFValue & 0xE0) | TxPwer2;
+				RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
+
+				// Tx/Rx Stream setting
+				RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+				//if (IS_RT3090(pAd))
+				//	RFValue |= 0x01; // Enable RF block.
+				RFValue &= 0x03;	//clear bit[7~2]
+				if (pAd->Antenna.field.TxPath == 1)
+					RFValue |= 0xA0;
+				else if (pAd->Antenna.field.TxPath == 2)
+					RFValue |= 0x80;
+				if (pAd->Antenna.field.RxPath == 1)
+					RFValue |= 0x50;
+				else if (pAd->Antenna.field.RxPath == 2)
+					RFValue |= 0x40;
+				RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+				// Set RF offset
+				RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
+				RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
+				RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
+
+				// Set BW
+				if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
+			{
+					RFValue = pAd->Mlme.CaliBW40RfR24;
+					//DISABLE_11N_CHECK(pAd);
+				}
+				else
+			{
+					RFValue = pAd->Mlme.CaliBW20RfR24;
+				}
+				RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
+				RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
+
+				// Enable RF tuning
+				RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+				RFValue = RFValue | 0x1;
+				RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+				// latch channel for future usage.
+				pAd->LatchRfRegs.Channel = Channel;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
+			Channel,
+			pAd->RfIcType,
+			TxPwer,
+			TxPwer2,
+			pAd->Antenna.field.TxPath,
+			FreqItems3020[index].N,
+			FreqItems3020[index].K,
+			FreqItems3020[index].R));
+
+				break;
+			}
+		}
+	}
+	else
+#endif // RT30xx //
+	{
+		RFRegTable = RF2850RegTable;
+		switch (pAd->RfIcType)
+		{
+			case RFIC_2820:
+			case RFIC_2850:
+			case RFIC_2720:
+			case RFIC_2750:
+
+				for (index = 0; index < NUM_OF_2850_CHNL; index++)
+				{
+					if (Channel == RFRegTable[index].Channel)
+					{
+						R2 = RFRegTable[index].R2;
+						if (pAd->Antenna.field.TxPath == 1)
+						{
+							R2 |= 0x4000;	// If TXpath is 1, bit 14 = 1;
+						}
+
+						if (pAd->Antenna.field.RxPath == 2)
+						{
+							R2 |= 0x40;	// write 1 to off Rxpath.
+						}
+						else if (pAd->Antenna.field.RxPath == 1)
+						{
+							R2 |= 0x20040;	// write 1 to off RxPath
+						}
+
+						if (Channel > 14)
+						{
+							// initialize R3, R4
+							R3 = (RFRegTable[index].R3 & 0xffffc1ff);
+							R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
+
+							// 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
+							// R3
+							if ((TxPwer >= -7) && (TxPwer < 0))
+							{
+								TxPwer = (7+TxPwer);
+								TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+								R3 |= (TxPwer << 10);
+								DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
+							}
+							else
+							{
+								TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+								R3 |= (TxPwer << 10) | (1 << 9);
+							}
+
+							// R4
+							if ((TxPwer2 >= -7) && (TxPwer2 < 0))
+							{
+								TxPwer2 = (7+TxPwer2);
+								TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+								R4 |= (TxPwer2 << 7);
+								DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
+							}
+							else
+							{
+								TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+								R4 |= (TxPwer2 << 7) | (1 << 6);
+							}
+						}
+						else
+						{
+							R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
+						R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
+						}
+
+						// Based on BBP current mode before changing RF channel.
+						if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
+						{
+							R4 |=0x200000;
+						}
+
+						// Update variables
+						pAd->LatchRfRegs.Channel = Channel;
+						pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
+						pAd->LatchRfRegs.R2 = R2;
+						pAd->LatchRfRegs.R3 = R3;
+						pAd->LatchRfRegs.R4 = R4;
+
+						// Set RF value 1's set R3[bit2] = [0]
+						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+						RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+						RTMPusecDelay(200);
+
+						// Set RF value 2's set R3[bit2] = [1]
+						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+						RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
+						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+						RTMPusecDelay(200);
+
+						// Set RF value 3's set R3[bit2] = [0]
+						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+						RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+						RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+						break;
+					}
+				}
+				break;
+
+			default:
+				break;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+							  Channel,
+							  pAd->RfIcType,
+							  (R3 & 0x00003e00) >> 9,
+							  (R4 & 0x000007c0) >> 6,
+							  pAd->Antenna.field.TxPath,
+							  pAd->LatchRfRegs.R1,
+							  pAd->LatchRfRegs.R2,
+							  pAd->LatchRfRegs.R3,
+							  pAd->LatchRfRegs.R4));
+	}
+
+	// Change BBP setting during siwtch from a->g, g->a
+	if (Channel <= 14)
+	{
+		ULONG	TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
+
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd)));	// According the Rory's suggestion to solve the middle range issue.
+		//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+
+		// Rx High power VGA offset for LNA select
+		if (pAd->NicConfig2.field.ExternalLNAForG)
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+		}
+		else
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+		}
+
+		// 5G band selection PIN, bit1 and bit2 are complement
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+		Value &= (~0x6);
+		Value |= (0x04);
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+		// Turn off unused PA or LNA when only 1T or 1R
+		if (pAd->Antenna.field.TxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFFFF3;
+		}
+		if (pAd->Antenna.field.RxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFF3FF;
+		}
+
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+	}
+	else
+	{
+		ULONG	TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
+
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd)));   // According the Rory's suggestion to solve the middle range issue.
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
+
+		// Rx High power VGA offset for LNA select
+		if (pAd->NicConfig2.field.ExternalLNAForA)
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+		}
+		else
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+		}
+
+		// 5G band selection PIN, bit1 and bit2 are complement
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+		Value &= (~0x6);
+		Value |= (0x02);
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+		// Turn off unused PA or LNA when only 1T or 1R
+		if (pAd->Antenna.field.TxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFFFF3;
+		}
+		if (pAd->Antenna.field.RxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFF3FF;
+		}
+
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+
+	}
+
+	// R66 should be set according to Channel and use 20MHz when scanning
+	//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
+	if (bScan)
+		RTMPSetAGCInitValue(pAd, BW_20);
+	else
+		RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
+
+	//
+	// On 11A, We should delay and wait RF/BBP to be stable
+	// and the appropriate time should be 1000 micro seconds
+	// 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
+	//
+	RTMPusecDelay(1000);
+}
+
+VOID AsicResetBBPAgent(
+IN PRTMP_ADAPTER pAd)
+{
+	BBP_CSR_CFG_STRUC	BbpCsr;
+	DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit.!! \n"));
+	// Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first.
+	RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+	BbpCsr.field.Busy = 0;
+	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
+}
+
+/*
+	==========================================================================
+	Description:
+		This function is required for 2421 only, and should not be used during
+		site survey. It's only required after NIC decided to stay at a channel
+		for a longer period.
+		When this function is called, it's always after AsicSwitchChannel().
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicLockChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR Channel)
+{
+}
+
+VOID AsicRfTuningExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+}
+
+/*
+	==========================================================================
+	Description:
+		Gives CCK TX rate 2 more dB TX power.
+		This routine works only in LINK UP in INFRASTRUCTURE mode.
+
+		calculate desired Tx power in RF R3.Tx0~5,	should consider -
+		0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+		1. TxPowerPercentage
+		2. auto calibration based on TSSI feedback
+		3. extra 2 db for CCK
+		4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+	NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+		it should be called AFTER MlmeDynamicTxRatSwitching()
+	==========================================================================
+ */
+VOID AsicAdjustTxPower(
+	IN PRTMP_ADAPTER pAd)
+{
+	INT			i, j;
+	CHAR		DeltaPwr = 0;
+	BOOLEAN		bAutoTxAgc = FALSE;
+	UCHAR		TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
+	UCHAR		BbpR1 = 0, BbpR49 = 0, idx;
+	PCHAR		pTxAgcCompensate;
+	ULONG		TxPwr[5];
+	CHAR		Value;
+	CHAR		Rssi = -127;
+
+
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
+#ifdef RTMP_MAC_PCI
+		(pAd->bPCIclkOff == TRUE) ||
+#endif // RTMP_MAC_PCI //
+		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
+		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+		return;
+
+		Rssi = RTMPMaxRssi(pAd,
+						   pAd->StaCfg.RssiSample.AvgRssi0,
+						   pAd->StaCfg.RssiSample.AvgRssi1,
+						   pAd->StaCfg.RssiSample.AvgRssi2);
+
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+	{
+		if (pAd->CommonCfg.CentralChannel > 14)
+		{
+			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+		}
+		else
+		{
+			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+		}
+	}
+	else
+	{
+		if (pAd->CommonCfg.Channel > 14)
+		{
+			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+		}
+		else
+		{
+			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+		}
+	}
+
+	// TX power compensation for temperature variation based on TSSI. try every 4 second
+	if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+	{
+		if (pAd->CommonCfg.Channel <= 14)
+		{
+			/* bg channel */
+			bAutoTxAgc         = pAd->bAutoTxAgcG;
+			TssiRef            = pAd->TssiRefG;
+			pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryG[0];
+			TxAgcStep          = pAd->TxAgcStepG;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
+		}
+		else
+		{
+			/* a channel */
+			bAutoTxAgc         = pAd->bAutoTxAgcA;
+			TssiRef            = pAd->TssiRefA;
+			pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryA[0];
+			TxAgcStep          = pAd->TxAgcStepA;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
+		}
+
+		if (bAutoTxAgc)
+		{
+			/* BbpR1 is unsigned char */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+			/* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+			/* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
+			/* step value is defined in pAd->TxAgcStepG for tx power value */
+
+			/* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
+			/* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+			   above value are examined in mass factory production */
+			/*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
+
+			/* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
+			/* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+			/* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
+
+			if (BbpR49 > pTssiMinusBoundary[1])
+			{
+				// Reading is larger than the reference value
+				// check for how large we need to decrease the Tx power
+				for (idx = 1; idx < 5; idx++)
+				{
+					if (BbpR49 <= pTssiMinusBoundary[idx])  // Found the range
+						break;
+				}
+				// The index is the step we should decrease, idx = 0 means there is nothing to compensate
+//				if (R3 > (ULONG) (TxAgcStep * (idx-1)))
+					*pTxAgcCompensate = -(TxAgcStep * (idx-1));
+//				else
+//					*pTxAgcCompensate = -((UCHAR)R3);
+
+				DeltaPwr += (*pTxAgcCompensate);
+				DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+					BbpR49, TssiRef, TxAgcStep, idx-1));
+			}
+			else if (BbpR49 < pTssiPlusBoundary[1])
+			{
+				// Reading is smaller than the reference value
+				// check for how large we need to increase the Tx power
+				for (idx = 1; idx < 5; idx++)
+				{
+					if (BbpR49 >= pTssiPlusBoundary[idx])   // Found the range
+						break;
+				}
+				// The index is the step we should increase, idx = 0 means there is nothing to compensate
+				*pTxAgcCompensate = TxAgcStep * (idx-1);
+				DeltaPwr += (*pTxAgcCompensate);
+				DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+					BbpR49, TssiRef, TxAgcStep, idx-1));
+			}
+			else
+			{
+				*pTxAgcCompensate = 0;
+				DBGPRINT(RT_DEBUG_TRACE, ("   Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+					BbpR49, TssiRef, TxAgcStep, 0));
+			}
+		}
+	}
+	else
+	{
+		if (pAd->CommonCfg.Channel <= 14)
+		{
+			bAutoTxAgc         = pAd->bAutoTxAgcG;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
+		}
+		else
+		{
+			bAutoTxAgc         = pAd->bAutoTxAgcA;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
+		}
+
+		if (bAutoTxAgc)
+			DeltaPwr += (*pTxAgcCompensate);
+	}
+
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
+	BbpR1 &= 0xFC;
+
+
+	/* calculate delta power based on the percentage specified from UI */
+	// E2PROM setting is calibrated for maximum TX power (i.e. 100%)
+	// We lower TX power here according to the percentage specified from UI
+	if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)       // AUTO TX POWER control
+	{
+		{
+			// to patch high power issue with some APs, like Belkin N1.
+			if (Rssi > -35)
+			{
+				BbpR1 |= 0x02;		// DeltaPwr -= 12;
+			}
+			else if (Rssi > -40)
+			{
+				BbpR1 |= 0x01;		// DeltaPwr -= 6;
+			}
+			else
+		;
+		}
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 90)  // 91 ~ 100% & AUTO, treat as 100% in terms of mW
+		;
+	else if (pAd->CommonCfg.TxPowerPercentage > 60)  // 61 ~ 90%, treat as 75% in terms of mW		// DeltaPwr -= 1;
+	{
+		DeltaPwr -= 1;
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 30)  // 31 ~ 60%, treat as 50% in terms of mW		// DeltaPwr -= 3;
+	{
+		DeltaPwr -= 3;
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 15)  // 16 ~ 30%, treat as 25% in terms of mW		// DeltaPwr -= 6;
+	{
+		BbpR1 |= 0x01;
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 9)   // 10 ~ 15%, treat as 12.5% in terms of mW		// DeltaPwr -= 9;
+	{
+		BbpR1 |= 0x01;
+		DeltaPwr -= 3;
+	}
+	else                                           // 0 ~ 9 %, treat as MIN(~3%) in terms of mW		// DeltaPwr -= 12;
+	{
+		BbpR1 |= 0x02;
+	}
+
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+	/* reset different new tx power for different TX rate */
+	for(i=0; i<5; i++)
+	{
+		if (TxPwr[i] != 0xffffffff)
+		{
+			for (j=0; j<8; j++)
+			{
+				Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
+
+				if ((Value + DeltaPwr) < 0)
+				{
+					Value = 0; /* min */
+				}
+				else if ((Value + DeltaPwr) > 0xF)
+				{
+					Value = 0xF; /* max */
+				}
+				else
+				{
+					Value += DeltaPwr; /* temperature compensation */
+				}
+
+				/* fill new value to CSR offset */
+				TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+			}
+
+			/* write tx power value to CSR */
+			/* TX_PWR_CFG_0 (8 tx rate) for	TX power for OFDM 12M/18M
+											TX power for OFDM 6M/9M
+											TX power for CCK5.5M/11M
+											TX power for CCK1M/2M */
+			/* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
+			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
+		}
+	}
+
+
+}
+
+
+/*
+	==========================================================================
+	Description:
+		put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
+		automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
+		the wakeup timer timeout. Driver has to issue a separate command to wake
+		PHY up.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicSleepThenAutoWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TbttNumToNextWakeUp)
+{
+	RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
+}
+
+/*
+	==========================================================================
+	Description:
+		AsicForceWakeup() is used whenever manual wakeup is required
+		AsicForceSleep() should only be used when not in INFRA BSS. When
+		in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
+	==========================================================================
+ */
+VOID AsicForceSleep(
+	IN PRTMP_ADAPTER pAd)
+{
+
+}
+
+/*
+	==========================================================================
+	Description:
+		AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
+		expired.
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+	==========================================================================
+ */
+VOID AsicForceWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN    bFromTx)
+{
+    DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n"));
+    RTMP_STA_FORCE_WAKEUP(pAd, bFromTx);
+}
+
+
+/*
+	==========================================================================
+	Description:
+		Set My BSSID
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicSetBssid(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pBssid)
+{
+	ULONG		  Addr4;
+	DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
+		pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
+
+	Addr4 = (ULONG)(pBssid[0])		 |
+			(ULONG)(pBssid[1] << 8)  |
+			(ULONG)(pBssid[2] << 16) |
+			(ULONG)(pBssid[3] << 24);
+	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
+
+	Addr4 = 0;
+	// always one BSSID in STA mode
+	Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
+
+	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
+}
+
+VOID AsicSetMcastWC(
+	IN PRTMP_ADAPTER pAd)
+{
+	MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
+	USHORT		offset;
+
+	pEntry->Sst        = SST_ASSOC;
+	pEntry->Aid        = MCAST_WCID;	// Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
+	pEntry->PsMode     = PWR_ACTIVE;
+	pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
+	offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicDelWcidTab(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR	Wcid)
+{
+	ULONG		  Addr0 = 0x0, Addr1 = 0x0;
+	ULONG		offset;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
+	offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
+	RTMP_IO_WRITE32(pAd, offset, Addr0);
+	offset += 4;
+	RTMP_IO_WRITE32(pAd, offset, Addr1);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicEnableRDG(
+	IN PRTMP_ADAPTER pAd)
+{
+	TX_LINK_CFG_STRUC	TxLinkCfg;
+	UINT32				Data = 0;
+
+	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+	TxLinkCfg.field.TxRDGEn = 1;
+	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+	Data  &= 0xFFFFFF00;
+	Data  |= 0x80;
+	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+	//OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicDisableRDG(
+	IN PRTMP_ADAPTER pAd)
+{
+	TX_LINK_CFG_STRUC	TxLinkCfg;
+	UINT32				Data = 0;
+
+
+	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+	TxLinkCfg.field.TxRDGEn = 0;
+	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+
+	Data  &= 0xFFFFFF00;
+	//Data  |= 0x20;
+#ifndef WIFI_TEST
+	//if ( pAd->CommonCfg.bEnableTxBurst )
+	//	Data |= 0x60; // for performance issue not set the TXOP to 0
+#endif
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
+		&& (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
+	)
+	{
+		// For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
+		if (pAd->CommonCfg.bEnableTxBurst)
+		Data |= 0x20;
+	}
+	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicDisableSync(
+	IN PRTMP_ADAPTER pAd)
+{
+	BCN_TIME_CFG_STRUC csr;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
+
+	// 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
+	//			  that NIC will never wakes up because TSF stops and no more
+	//			  TBTT interrupts
+	pAd->TbttTickCount = 0;
+	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+	csr.field.bBeaconGen = 0;
+	csr.field.bTBTTEnable = 0;
+	csr.field.TsfSyncMode = 0;
+	csr.field.bTsfTicking = 0;
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicEnableBssSync(
+	IN PRTMP_ADAPTER pAd)
+{
+	BCN_TIME_CFG_STRUC csr;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
+
+	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+//	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
+	{
+		csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
+		csr.field.bTsfTicking = 1;
+		csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
+		csr.field.bBeaconGen  = 0; // do NOT generate BEACON
+		csr.field.bTBTTEnable = 1;
+	}
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+}
+
+/*
+	==========================================================================
+	Description:
+	Note:
+		BEACON frame in shared memory should be built ok before this routine
+		can be called. Otherwise, a garbage frame maybe transmitted out every
+		Beacon period.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicEnableIbssSync(
+	IN PRTMP_ADAPTER pAd)
+{
+	BCN_TIME_CFG_STRUC csr9;
+	PUCHAR			ptr;
+	UINT i;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
+
+	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
+	csr9.field.bBeaconGen = 0;
+	csr9.field.bTBTTEnable = 0;
+	csr9.field.bTsfTicking = 0;
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+
+#ifdef RTMP_MAC_PCI
+	// move BEACON TXD and frame content to on-chip memory
+	ptr = (PUCHAR)&pAd->BeaconTxWI;
+	for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
+	{
+		UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
+		ptr += 4;
+	}
+
+	// start right after the 16-byte TXWI field
+	ptr = pAd->BeaconBuf;
+	for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
+	{
+		UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
+		ptr +=4;
+	}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+	// move BEACON TXD and frame content to on-chip memory
+	ptr = (PUCHAR)&pAd->BeaconTxWI;
+	for (i=0; i<TXWI_SIZE; i+=2)  // 16-byte TXWI field
+	{
+		//UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+		//RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
+		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
+		ptr += 2;
+	}
+
+	// start right after the 16-byte TXWI field
+	ptr = pAd->BeaconBuf;
+	for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
+	{
+		//UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+		//RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
+		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
+		ptr +=2;
+	}
+#endif // RTMP_MAC_USB //
+
+	//
+	// For Wi-Fi faily generated beacons between participating stations.
+	// Set TBTT phase adaptive adjustment step to 8us (default 16us)
+	// don't change settings 2006-5- by Jerry
+	//RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
+
+	// start sending BEACON
+	csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
+	csr9.field.bTsfTicking = 1;
+	csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
+	csr9.field.bTBTTEnable = 1;
+	csr9.field.bBeaconGen = 1;
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicSetEdcaParm(
+	IN PRTMP_ADAPTER pAd,
+	IN PEDCA_PARM	 pEdcaParm)
+{
+	EDCA_AC_CFG_STRUC   Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
+	AC_TXOP_CSR0_STRUC csr0;
+	AC_TXOP_CSR1_STRUC csr1;
+	AIFSN_CSR_STRUC    AifsnCsr;
+	CWMIN_CSR_STRUC    CwminCsr;
+	CWMAX_CSR_STRUC    CwmaxCsr;
+	int i;
+
+	Ac0Cfg.word = 0;
+	Ac1Cfg.word = 0;
+	Ac2Cfg.word = 0;
+	Ac3Cfg.word = 0;
+	if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+		for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+		{
+			if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
+				CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
+		}
+
+		//========================================================
+		//      MAC Register has a copy .
+		//========================================================
+//#ifndef WIFI_TEST
+		if( pAd->CommonCfg.bEnableTxBurst )
+		{
+			// For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
+			Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
+		}
+		else
+			Ac0Cfg.field.AcTxop = 0;	// QID_AC_BE
+//#else
+//		Ac0Cfg.field.AcTxop = 0;	// QID_AC_BE
+//#endif
+		Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac0Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+
+		Ac1Cfg.field.AcTxop = 0;	// QID_AC_BK
+		Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac1Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+
+		if (pAd->CommonCfg.PhyMode == PHY_11B)
+		{
+			Ac2Cfg.field.AcTxop = 192;	// AC_VI: 192*32us ~= 6ms
+			Ac3Cfg.field.AcTxop = 96;	// AC_VO: 96*32us  ~= 3ms
+		}
+		else
+		{
+			Ac2Cfg.field.AcTxop = 96;	// AC_VI: 96*32us ~= 3ms
+			Ac3Cfg.field.AcTxop = 48;	// AC_VO: 48*32us ~= 1.5ms
+		}
+		Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac2Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+		Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac3Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+		//========================================================
+		//      DMA Register has a copy too.
+		//========================================================
+		csr0.field.Ac0Txop = 0;		// QID_AC_BE
+		csr0.field.Ac1Txop = 0;		// QID_AC_BK
+		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+		if (pAd->CommonCfg.PhyMode == PHY_11B)
+		{
+			csr1.field.Ac2Txop = 192;		// AC_VI: 192*32us ~= 6ms
+			csr1.field.Ac3Txop = 96;		// AC_VO: 96*32us  ~= 3ms
+		}
+		else
+		{
+			csr1.field.Ac2Txop = 96;		// AC_VI: 96*32us ~= 3ms
+			csr1.field.Ac3Txop = 48;		// AC_VO: 48*32us ~= 1.5ms
+		}
+		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+		CwminCsr.word = 0;
+		CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
+		CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
+		CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
+		CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
+		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+		CwmaxCsr.word = 0;
+		CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
+		CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
+		CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
+		CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
+		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
+
+		NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
+	}
+	else
+	{
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+		//========================================================
+		//      MAC Register has a copy.
+		//========================================================
+		//
+		// Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
+		// To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
+		//
+		//pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
+
+		Ac0Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BE];
+		Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
+		Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
+		Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
+
+		Ac1Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BK];
+		Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
+		Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
+		Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
+
+		Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
+		if(pAd->Antenna.field.TxPath == 1)
+		{
+			Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
+			Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
+		}
+		else
+		{
+		Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
+		Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
+		}
+		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
+#ifdef RTMP_MAC_USB
+		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3;
+#endif // RTMP_MAC_USB //
+
+		{
+			// Tuning for Wi-Fi WMM S06
+			if (pAd->CommonCfg.bWiFiTest &&
+				pEdcaParm->Aifsn[QID_AC_VI] == 10)
+				Ac2Cfg.field.Aifsn -= 1;
+
+			// Tuning for TGn Wi-Fi 5.2.32
+			// STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
+			if (STA_TGN_WIFI_ON(pAd) &&
+				pEdcaParm->Aifsn[QID_AC_VI] == 10)
+			{
+				Ac0Cfg.field.Aifsn = 3;
+				Ac2Cfg.field.AcTxop = 5;
+			}
+#ifdef RT30xx
+			if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
+			{
+				// Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
+				Ac2Cfg.field.Aifsn = 5;
+			}
+#endif // RT30xx //
+		}
+
+		Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
+		Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
+		Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
+		Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
+
+//#ifdef WIFI_TEST
+		if (pAd->CommonCfg.bWiFiTest)
+		{
+			if (Ac3Cfg.field.AcTxop == 102)
+			{
+			Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
+				Ac0Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
+			Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
+				Ac1Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BK];
+			Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
+			} /* End of if */
+		}
+//#endif // WIFI_TEST //
+
+		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+
+		//========================================================
+		//      DMA Register has a copy too.
+		//========================================================
+		csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
+		csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
+		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+
+		csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
+		csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
+		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+		CwminCsr.word = 0;
+		CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
+		CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
+		CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
+			CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
+		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+		CwmaxCsr.word = 0;
+		CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
+		CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
+		CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
+		CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
+		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+		AifsnCsr.word = 0;
+		AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
+		AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
+		AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
+
+		{
+			// Tuning for Wi-Fi WMM S06
+			if (pAd->CommonCfg.bWiFiTest &&
+				pEdcaParm->Aifsn[QID_AC_VI] == 10)
+				AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
+
+			// Tuning for TGn Wi-Fi 5.2.32
+			// STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
+			if (STA_TGN_WIFI_ON(pAd) &&
+				pEdcaParm->Aifsn[QID_AC_VI] == 10)
+			{
+				AifsnCsr.field.Aifsn0 = 3;
+				AifsnCsr.field.Aifsn2 = 7;
+			}
+
+			if (INFRA_ON(pAd))
+				CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
+		}
+
+		{
+			AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
+#ifdef RT30xx
+			// TODO: Shiang, this modification also suitable for RT3052/RT3050 ???
+			if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
+			{
+					AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
+			}
+#endif // RT30xx //
+		}
+		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
+
+		NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+		if (!ADHOC_ON(pAd))
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax  TXOP(us)  ACM\n", pEdcaParm->EdcaUpdateCount));
+			DBGPRINT(RT_DEBUG_TRACE,("     AC_BE      %2d     %2d     %2d      %4d     %d\n",
+									 pEdcaParm->Aifsn[0],
+									 pEdcaParm->Cwmin[0],
+									 pEdcaParm->Cwmax[0],
+									 pEdcaParm->Txop[0]<<5,
+									 pEdcaParm->bACM[0]));
+			DBGPRINT(RT_DEBUG_TRACE,("     AC_BK      %2d     %2d     %2d      %4d     %d\n",
+									 pEdcaParm->Aifsn[1],
+									 pEdcaParm->Cwmin[1],
+									 pEdcaParm->Cwmax[1],
+									 pEdcaParm->Txop[1]<<5,
+									 pEdcaParm->bACM[1]));
+			DBGPRINT(RT_DEBUG_TRACE,("     AC_VI      %2d     %2d     %2d      %4d     %d\n",
+									 pEdcaParm->Aifsn[2],
+									 pEdcaParm->Cwmin[2],
+									 pEdcaParm->Cwmax[2],
+									 pEdcaParm->Txop[2]<<5,
+									 pEdcaParm->bACM[2]));
+			DBGPRINT(RT_DEBUG_TRACE,("     AC_VO      %2d     %2d     %2d      %4d     %d\n",
+									 pEdcaParm->Aifsn[3],
+									 pEdcaParm->Cwmin[3],
+									 pEdcaParm->Cwmax[3],
+									 pEdcaParm->Txop[3]<<5,
+									 pEdcaParm->bACM[3]));
+		}
+	}
+
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID	AsicSetSlotTime(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN bUseShortSlotTime)
+{
+	ULONG	SlotTime;
+	UINT32	RegValue = 0;
+
+	if (pAd->CommonCfg.Channel > 14)
+		bUseShortSlotTime = TRUE;
+
+	if (bUseShortSlotTime && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
+		return;
+	else if ((!bUseShortSlotTime) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
+		return;
+
+	if (bUseShortSlotTime)
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+	else
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+
+	SlotTime = (bUseShortSlotTime)? 9 : 20;
+
+	{
+		// force using short SLOT time for FAE to demo performance when TxBurst is ON
+		if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
+			|| ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
+			)
+		{
+			// In this case, we will think it is doing Wi-Fi test
+			// And we will not set to short slot when bEnableTxBurst is TRUE.
+		}
+		else if (pAd->CommonCfg.bEnableTxBurst)
+		{
+			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+			SlotTime = 9;
+		}
+	}
+
+	//
+	// For some reasons, always set it to short slot time.
+	//
+	// ToDo: Should consider capability with 11B
+	//
+	{
+		if (pAd->StaCfg.BssType == BSS_ADHOC)
+		{
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+			SlotTime = 20;
+		}
+	}
+
+	RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
+	RegValue = RegValue & 0xFFFFFF00;
+
+	RegValue |= SlotTime;
+
+	RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
+}
+
+/*
+	========================================================================
+	Description:
+		Add Shared key information into ASIC.
+		Update shared key, TxMic and RxMic to Asic Shared key table
+		Update its cipherAlg to Asic Shared key Mode.
+
+    Return:
+	========================================================================
+*/
+VOID AsicAddSharedKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 BssIndex,
+	IN UCHAR		 KeyIdx,
+	IN UCHAR		 CipherAlg,
+	IN PUCHAR		 pKey,
+	IN PUCHAR		 pTxMic,
+	IN PUCHAR		 pRxMic)
+{
+	ULONG offset; //, csr0;
+	SHAREDKEY_MODE_STRUC csr1;
+#ifdef RTMP_MAC_PCI
+	INT   i;
+#endif // RTMP_MAC_PCI //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
+//============================================================================================
+
+	DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("		Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+		pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
+	if (pRxMic)
+	{
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("		Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+	}
+	if (pTxMic)
+	{
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("		Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+	}
+//============================================================================================
+	//
+	// fill key material - key + TX MIC + RX MIC
+	//
+#ifdef RTMP_MAC_PCI
+	offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
+	for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
+	{
+		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+	}
+
+	offset += MAX_LEN_OF_SHARE_KEY;
+	if (pTxMic)
+	{
+		for (i=0; i<8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
+		}
+	}
+
+	offset += 8;
+	if (pRxMic)
+	{
+		for (i=0; i<8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
+		}
+	}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+{
+	offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
+	RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
+
+	offset += MAX_LEN_OF_SHARE_KEY;
+	if (pTxMic)
+	{
+		RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+	}
+
+	offset += 8;
+	if (pRxMic)
+	{
+		RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+	}
+}
+#endif // RTMP_MAC_USB //
+
+	//
+	// Update cipher algorithm. WSTA always use BSS0
+	//
+	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+	DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
+	if ((BssIndex%2) == 0)
+	{
+		if (KeyIdx == 0)
+			csr1.field.Bss0Key0CipherAlg = CipherAlg;
+		else if (KeyIdx == 1)
+			csr1.field.Bss0Key1CipherAlg = CipherAlg;
+		else if (KeyIdx == 2)
+			csr1.field.Bss0Key2CipherAlg = CipherAlg;
+		else
+			csr1.field.Bss0Key3CipherAlg = CipherAlg;
+	}
+	else
+	{
+		if (KeyIdx == 0)
+			csr1.field.Bss1Key0CipherAlg = CipherAlg;
+		else if (KeyIdx == 1)
+			csr1.field.Bss1Key1CipherAlg = CipherAlg;
+		else if (KeyIdx == 2)
+			csr1.field.Bss1Key2CipherAlg = CipherAlg;
+		else
+			csr1.field.Bss1Key3CipherAlg = CipherAlg;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+
+}
+
+//	IRQL = DISPATCH_LEVEL
+VOID AsicRemoveSharedKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 BssIndex,
+	IN UCHAR		 KeyIdx)
+{
+	//ULONG SecCsr0;
+	SHAREDKEY_MODE_STRUC csr1;
+
+	DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
+
+	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+	if ((BssIndex%2) == 0)
+	{
+		if (KeyIdx == 0)
+			csr1.field.Bss0Key0CipherAlg = 0;
+		else if (KeyIdx == 1)
+			csr1.field.Bss0Key1CipherAlg = 0;
+		else if (KeyIdx == 2)
+			csr1.field.Bss0Key2CipherAlg = 0;
+		else
+			csr1.field.Bss0Key3CipherAlg = 0;
+	}
+	else
+	{
+		if (KeyIdx == 0)
+			csr1.field.Bss1Key0CipherAlg = 0;
+		else if (KeyIdx == 1)
+			csr1.field.Bss1Key1CipherAlg = 0;
+		else if (KeyIdx == 2)
+			csr1.field.Bss1Key2CipherAlg = 0;
+		else
+			csr1.field.Bss1Key3CipherAlg = 0;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+	ASSERT(BssIndex < 4);
+	ASSERT(KeyIdx < 4);
+
+}
+
+
+VOID AsicUpdateWCIDAttribute(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN UCHAR		BssIndex,
+	IN UCHAR        CipherAlg,
+	IN BOOLEAN		bUsePairewiseKeyTable)
+{
+	ULONG   WCIDAttri = 0, offset;
+
+	//
+	// Update WCID attribute.
+	// Only TxKey could update WCID attribute.
+	//
+	offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
+	WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
+	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+VOID AsicUpdateWCIDIVEIV(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN ULONG        uIV,
+	IN ULONG        uEIV)
+{
+	ULONG	offset;
+
+	offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+
+	RTMP_IO_WRITE32(pAd, offset, uIV);
+	RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
+}
+
+VOID AsicUpdateRxWCIDTable(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN PUCHAR        pAddr)
+{
+	ULONG offset;
+	ULONG Addr;
+
+	offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
+	Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
+	RTMP_IO_WRITE32(pAd, offset, Addr);
+	Addr = pAddr[4] + (pAddr[5] << 8);
+	RTMP_IO_WRITE32(pAd, offset + 4, Addr);
+}
+
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Set Cipher Key, Cipher algorithm, IV/EIV to Asic
+
+    Arguments:
+        pAd                     Pointer to our adapter
+        WCID                    WCID Entry number.
+        BssIndex                BSSID index, station or none multiple BSSID support
+                                this value should be 0.
+        KeyIdx                  This KeyIdx will set to IV's KeyID if bTxKey enabled
+        pCipherKey              Pointer to Cipher Key.
+        bUsePairewiseKeyTable   TRUE means saved the key in SharedKey table,
+                                otherwise PairewiseKey table
+        bTxKey                  This is the transmit key if enabled.
+
+    Return Value:
+        None
+
+    Note:
+        This routine will set the relative key stuff to Asic including WCID attribute,
+        Cipher Key, Cipher algorithm and IV/EIV.
+
+        IV/EIV will be update if this CipherKey is the transmission key because
+        ASIC will base on IV's KeyID value to select Cipher Key.
+
+        If bTxKey sets to FALSE, this is not the TX key, but it could be
+        RX key
+
+	For AP mode bTxKey must be always set to TRUE.
+    ========================================================================
+*/
+VOID AsicAddKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN UCHAR		BssIndex,
+	IN UCHAR		KeyIdx,
+	IN PCIPHER_KEY	pCipherKey,
+	IN BOOLEAN		bUsePairewiseKeyTable,
+	IN BOOLEAN		bTxKey)
+{
+	ULONG	offset;
+//	ULONG   WCIDAttri = 0;
+	UCHAR	IV4 = 0;
+	PUCHAR		pKey = pCipherKey->Key;
+//	ULONG		KeyLen = pCipherKey->KeyLen;
+	PUCHAR		pTxMic = pCipherKey->TxMic;
+	PUCHAR		pRxMic = pCipherKey->RxMic;
+	PUCHAR		pTxtsc = pCipherKey->TxTsc;
+	UCHAR		CipherAlg = pCipherKey->CipherAlg;
+	SHAREDKEY_MODE_STRUC csr1;
+#ifdef RTMP_MAC_PCI
+	UCHAR		i;
+#endif // RTMP_MAC_PCI //
+
+//	ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
+	//
+	// 1.) decide key table offset
+	//
+	if (bUsePairewiseKeyTable)
+		offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+	else
+		offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
+
+	//
+	// 2.) Set Key to Asic
+	//
+	//for (i = 0; i < KeyLen; i++)
+#ifdef RTMP_MAC_PCI
+	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
+	{
+		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+	}
+	offset += MAX_LEN_OF_PEER_KEY;
+
+	//
+	// 3.) Set MIC key if available
+	//
+	if (pTxMic)
+	{
+		for (i = 0; i < 8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
+		}
+	}
+	offset += LEN_TKIP_TXMICK;
+
+	if (pRxMic)
+	{
+		for (i = 0; i < 8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
+		}
+	}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+	RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
+	offset += MAX_LEN_OF_PEER_KEY;
+
+	//
+	// 3.) Set MIC key if available
+	//
+	if (pTxMic)
+	{
+		RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+	}
+	offset += LEN_TKIP_TXMICK;
+
+	if (pRxMic)
+	{
+		RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+	}
+#endif // RTMP_MAC_USB //
+
+	//
+	// 4.) Modify IV/EIV if needs
+	//     This will force Asic to use this key ID by setting IV.
+	//
+	if (bTxKey)
+	{
+#ifdef RTMP_MAC_PCI
+		offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+		//
+		// Write IV
+		//
+		RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
+		RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
+		RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
+
+		IV4 = (KeyIdx << 6);
+		if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
+			IV4 |= 0x20;  // turn on extension bit means EIV existence
+
+		RTMP_IO_WRITE8(pAd, offset + 3, IV4);
+
+		//
+		// Write EIV
+		//
+		offset += 4;
+		for (i = 0; i < 4; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
+		}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+		UINT32 tmpVal;
+
+		//
+		// Write IV
+		//
+		IV4 = (KeyIdx << 6);
+		if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
+			IV4 |= 0x20;  // turn on extension bit means EIV existence
+
+		tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
+		RTMP_IO_WRITE32(pAd, offset, tmpVal);
+
+		//
+		// Write EIV
+		//
+		offset += 4;
+		RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
+#endif // RTMP_MAC_USB //
+
+		AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
+	}
+
+	if (!bUsePairewiseKeyTable)
+	{
+		//
+		// Only update the shared key security mode
+		//
+		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
+		if ((BssIndex % 2) == 0)
+		{
+			if (KeyIdx == 0)
+				csr1.field.Bss0Key0CipherAlg = CipherAlg;
+			else if (KeyIdx == 1)
+				csr1.field.Bss0Key1CipherAlg = CipherAlg;
+			else if (KeyIdx == 2)
+				csr1.field.Bss0Key2CipherAlg = CipherAlg;
+			else
+				csr1.field.Bss0Key3CipherAlg = CipherAlg;
+		}
+		else
+		{
+			if (KeyIdx == 0)
+				csr1.field.Bss1Key0CipherAlg = CipherAlg;
+			else if (KeyIdx == 1)
+				csr1.field.Bss1Key1CipherAlg = CipherAlg;
+			else if (KeyIdx == 2)
+				csr1.field.Bss1Key2CipherAlg = CipherAlg;
+			else
+				csr1.field.Bss1Key3CipherAlg = CipherAlg;
+		}
+		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
+}
+
+
+/*
+	========================================================================
+	Description:
+		Add Pair-wise key material into ASIC.
+		Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
+
+    Return:
+	========================================================================
+*/
+VOID AsicAddPairwiseKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR        pAddr,
+	IN UCHAR		WCID,
+	IN CIPHER_KEY		 *pCipherKey)
+{
+	INT i;
+	ULONG		offset;
+	PUCHAR		 pKey = pCipherKey->Key;
+	PUCHAR		 pTxMic = pCipherKey->TxMic;
+	PUCHAR		 pRxMic = pCipherKey->RxMic;
+#ifdef DBG
+	UCHAR		CipherAlg = pCipherKey->CipherAlg;
+#endif // DBG //
+
+	// EKEY
+	offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+#ifdef RTMP_MAC_PCI
+	for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
+	{
+		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+	}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+	RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
+#endif // RTMP_MAC_USB //
+	for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
+	{
+		UINT32 Value;
+		RTMP_IO_READ32(pAd, offset + i, &Value);
+	}
+
+	offset += MAX_LEN_OF_PEER_KEY;
+
+	//  MIC KEY
+	if (pTxMic)
+	{
+#ifdef RTMP_MAC_PCI
+		for (i=0; i<8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
+		}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+		RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
+#endif // RTMP_MAC_USB //
+	}
+	offset += 8;
+	if (pRxMic)
+	{
+#ifdef RTMP_MAC_PCI
+		for (i=0; i<8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
+		}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+		RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
+#endif // RTMP_MAC_USB //
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
+	DBGPRINT(RT_DEBUG_TRACE,("	Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+		pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
+	if (pRxMic)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("	Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+	}
+	if (pTxMic)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("	Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+	}
+}
+/*
+	========================================================================
+	Description:
+		Remove Pair-wise key material from ASIC.
+
+    Return:
+	========================================================================
+*/
+VOID AsicRemovePairwiseKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 BssIdx,
+	IN UCHAR		 Wcid)
+{
+	ULONG		WCIDAttri;
+	USHORT		offset;
+
+	// re-set the entry's WCID attribute as OPEN-NONE.
+	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+	WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
+	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+BOOLEAN AsicSendCommandToMcu(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 Command,
+	IN UCHAR		 Token,
+	IN UCHAR		 Arg0,
+	IN UCHAR		 Arg1)
+{
+
+	if (pAd->chipOps.sendCommandToMcu)
+		pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
+
+	return TRUE;
+}
+
+
+VOID AsicSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant)
+{
+#ifdef RT30xx
+	/* RT3572 ATE need not to do this. */
+	RT30xxSetRxAnt(pAd, Ant);
+#endif // RT30xx //
+}
+
+
+VOID AsicTurnOffRFClk(
+	IN PRTMP_ADAPTER pAd,
+	IN	UCHAR		Channel)
+{
+	if (pAd->chipOps.AsicRfTurnOff)
+	{
+		pAd->chipOps.AsicRfTurnOff(pAd);
+	}
+	else
+	{
+		// RF R2 bit 18 = 0
+		UINT32			R1 = 0, R2 = 0, R3 = 0;
+		UCHAR			index;
+		RTMP_RF_REGS	*RFRegTable;
+
+		RFRegTable = RF2850RegTable;
+
+		switch (pAd->RfIcType)
+		{
+			case RFIC_2820:
+			case RFIC_2850:
+			case RFIC_2720:
+			case RFIC_2750:
+
+				for (index = 0; index < NUM_OF_2850_CHNL; index++)
+				{
+					if (Channel == RFRegTable[index].Channel)
+					{
+						R1 = RFRegTable[index].R1 & 0xffffdfff;
+						R2 = RFRegTable[index].R2 & 0xfffbffff;
+						R3 = RFRegTable[index].R3 & 0xfff3ffff;
+
+						RTMP_RF_IO_WRITE32(pAd, R1);
+						RTMP_RF_IO_WRITE32(pAd, R2);
+
+						// Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
+						// Set RF R2 bit18=0, R3 bit[18:19]=0
+						//if (pAd->StaCfg.bRadio == FALSE)
+						if (1)
+						{
+							RTMP_RF_IO_WRITE32(pAd, R3);
+
+							DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x,  R3 = 0x%08x \n",
+								Channel, pAd->RfIcType, R2, R3));
+						}
+						else
+							DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
+								Channel, pAd->RfIcType, R2));
+						break;
+					}
+				}
+				break;
+
+			default:
+				break;
+		}
+	}
+}
+
+
+VOID AsicTurnOnRFClk(
+	IN PRTMP_ADAPTER pAd,
+	IN	UCHAR			Channel)
+{
+	// RF R2 bit 18 = 0
+	UINT32			R1 = 0, R2 = 0, R3 = 0;
+	UCHAR			index;
+	RTMP_RF_REGS	*RFRegTable;
+
+
+	RFRegTable = RF2850RegTable;
+
+	switch (pAd->RfIcType)
+	{
+		case RFIC_2820:
+		case RFIC_2850:
+		case RFIC_2720:
+		case RFIC_2750:
+
+			for (index = 0; index < NUM_OF_2850_CHNL; index++)
+			{
+				if (Channel == RFRegTable[index].Channel)
+				{
+					R3 = pAd->LatchRfRegs.R3;
+					R3 &= 0xfff3ffff;
+					R3 |= 0x00080000;
+					RTMP_RF_IO_WRITE32(pAd, R3);
+
+					R1 = RFRegTable[index].R1;
+					RTMP_RF_IO_WRITE32(pAd, R1);
+
+					R2 = RFRegTable[index].R2;
+					if (pAd->Antenna.field.TxPath == 1)
+					{
+						R2 |= 0x4000;	// If TXpath is 1, bit 14 = 1;
+					}
+
+					if (pAd->Antenna.field.RxPath == 2)
+					{
+						R2 |= 0x40;	// write 1 to off Rxpath.
+					}
+					else if (pAd->Antenna.field.RxPath == 1)
+					{
+						R2 |= 0x20040;	// write 1 to off RxPath
+					}
+					RTMP_RF_IO_WRITE32(pAd, R2);
+
+					break;
+				}
+			}
+			break;
+
+		default:
+			break;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
+		Channel,
+		pAd->RfIcType,
+		R2));
+}
diff --git a/drivers/staging/rt2860/common/cmm_cfg.c b/drivers/staging/rt2860/common/cmm_cfg.c
new file mode 100644
index 0000000..c1cf2bf
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_cfg.c
@@ -0,0 +1,290 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	cmm_cfg.c
+
+    Abstract:
+    Ralink WiFi Driver configuration related subroutines
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+*/
+
+
+
+#include "../rt_config.h"
+
+
+char* GetPhyMode(
+	int Mode)
+{
+	switch(Mode)
+	{
+		case MODE_CCK:
+			return "CCK";
+
+		case MODE_OFDM:
+			return "OFDM";
+		case MODE_HTMIX:
+			return "HTMIX";
+
+		case MODE_HTGREENFIELD:
+			return "GREEN";
+		default:
+			return "N/A";
+	}
+}
+
+
+char* GetBW(
+	int BW)
+{
+	switch(BW)
+	{
+		case BW_10:
+			return "10M";
+
+		case BW_20:
+			return "20M";
+		case BW_40:
+			return "40M";
+		default:
+			return "N/A";
+	}
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Set Country Region to pAd->CommonCfg.CountryRegion.
+        This command will not work, if the field of CountryRegion in eeprom is programmed.
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT RT_CfgSetCountryRegion(
+	IN PRTMP_ADAPTER	pAd,
+	IN PSTRING			arg,
+	IN INT				band)
+{
+	LONG region, regionMax;
+	UCHAR *pCountryRegion;
+
+	region = simple_strtol(arg, 0, 10);
+
+	if (band == BAND_24G)
+	{
+		pCountryRegion = &pAd->CommonCfg.CountryRegion;
+		regionMax = REGION_MAXIMUM_BG_BAND;
+	}
+	else
+	{
+		pCountryRegion = &pAd->CommonCfg.CountryRegionForABand;
+		regionMax = REGION_MAXIMUM_A_BAND;
+	}
+
+	// TODO: Is it neccesay for following check???
+	// Country can be set only when EEPROM not programmed
+	if (*pCountryRegion & 0x80)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n"));
+		return FALSE;
+	}
+
+	if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
+	{
+		*pCountryRegion= (UCHAR) region;
+	}
+	else if ((region == REGION_31_BG_BAND) && (band == BAND_24G))
+	{
+		*pCountryRegion = (UCHAR) region;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():region(%ld) out of range!\n", region));
+		return FALSE;
+	}
+
+	return TRUE;
+
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Set Wireless Mode
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT RT_CfgSetWirelessMode(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	INT		MaxPhyMode = PHY_11G;
+	LONG	WirelessMode;
+
+	MaxPhyMode = PHY_11N_5G;
+
+	WirelessMode = simple_strtol(arg, 0, 10);
+	if (WirelessMode <= MaxPhyMode)
+	{
+		pAd->CommonCfg.PhyMode = WirelessMode;
+		return TRUE;
+	}
+
+	return FALSE;
+
+}
+
+
+INT RT_CfgSetShortSlot(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	LONG ShortSlot;
+
+	ShortSlot = simple_strtol(arg, 0, 10);
+
+	if (ShortSlot == 1)
+		pAd->CommonCfg.bUseShortSlotTime = TRUE;
+	else if (ShortSlot == 0)
+		pAd->CommonCfg.bUseShortSlotTime = FALSE;
+	else
+		return FALSE;  //Invalid argument
+
+	return TRUE;
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Set WEP KEY base on KeyIdx
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	RT_CfgSetWepKey(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			keyString,
+	IN	CIPHER_KEY		*pSharedKey,
+	IN	INT				keyIdx)
+{
+	INT				KeyLen;
+	INT				i;
+	UCHAR			CipherAlg = CIPHER_NONE;
+	BOOLEAN			bKeyIsHex = FALSE;
+
+	// TODO: Shall we do memset for the original key info??
+	memset(pSharedKey, 0, sizeof(CIPHER_KEY));
+	KeyLen = strlen(keyString);
+	switch (KeyLen)
+	{
+		case 5: //wep 40 Ascii type
+		case 13: //wep 104 Ascii type
+			bKeyIsHex = FALSE;
+			pSharedKey->KeyLen = KeyLen;
+			NdisMoveMemory(pSharedKey->Key, keyString, KeyLen);
+			break;
+
+		case 10: //wep 40 Hex type
+		case 26: //wep 104 Hex type
+			for(i=0; i < KeyLen; i++)
+			{
+				if( !isxdigit(*(keyString+i)) )
+					return FALSE;  //Not Hex value;
+			}
+			bKeyIsHex = TRUE;
+			pSharedKey->KeyLen = KeyLen/2 ;
+			AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen);
+			break;
+
+		default: //Invalid argument
+			DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n", keyIdx, keyString));
+			return FALSE;
+	}
+
+	pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64);
+	DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n",
+						keyIdx, (bKeyIsHex == FALSE ? "Ascii" : "Hex"), CipherName[CipherAlg]));
+
+	return TRUE;
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Set WPA PSK key
+
+    Arguments:
+        pAdapter	Pointer to our adapter
+        keyString	WPA pre-shared key string
+        pHashStr	String used for password hash function
+        hashStrLen	Lenght of the hash string
+        pPMKBuf		Output buffer of WPAPSK key
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT RT_CfgSetWPAPSKKey(
+	IN RTMP_ADAPTER	*pAd,
+	IN PSTRING		keyString,
+	IN UCHAR		*pHashStr,
+	IN INT			hashStrLen,
+	OUT PUCHAR		pPMKBuf)
+{
+	int keyLen;
+	UCHAR keyMaterial[40];
+
+	keyLen = strlen(keyString);
+	if ((keyLen < 8) || (keyLen > 64))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
+									keyLen, keyString));
+		return FALSE;
+	}
+
+	memset(pPMKBuf, 0, 32);
+	if (keyLen == 64)
+	{
+	    AtoH(keyString, pPMKBuf, 32);
+	}
+	else
+	{
+	    PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
+	    NdisMoveMemory(pPMKBuf, keyMaterial, 32);
+	}
+
+	return TRUE;
+}
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c
index 774fabb..3696913 100644
--- a/drivers/staging/rt2860/common/cmm_data.c
+++ b/drivers/staging/rt2860/common/cmm_data.c
@@ -25,9 +25,8 @@ 
  *************************************************************************
 */
 
-#include "../rt_config.h"
 
-#define MAX_TX_IN_TBTT		(16)
+#include "../rt_config.h"
 
 
 UCHAR	SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
@@ -67,6 +66,7 @@  UCHAR	 RxwiMCSToOfdmRate[12] = {
 char*   MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
 
 UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
+//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};
 UCHAR default_sta_aifsn[]={3,7,2,2};
 
 UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
@@ -105,28 +105,38 @@  NDIS_STATUS MiniportMMRequest(
 	PNDIS_PACKET	pPacket;
 	NDIS_STATUS  	Status = NDIS_STATUS_SUCCESS;
 	ULONG	 		FreeNum;
-#ifdef RT2860
+	UCHAR			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+#ifdef RTMP_MAC_PCI
 	unsigned long	IrqFlags = 0;
-#endif
 	UCHAR			IrqState;
-	UCHAR			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+#endif // RTMP_MAC_PCI //
+	BOOLEAN			bUseDataQ = FALSE;
+	int			retryCnt = 0;
 
 	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
 
-	QueIdx=3;
+	if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG)
+	{
+		bUseDataQ = TRUE;
+		QueIdx &= (~MGMT_USE_QUEUE_FLAG);
+	}
 
+#ifdef RTMP_MAC_PCI
 	// 2860C use Tx Ring
-
 	IrqState = pAd->irq_disabled;
-
-#ifdef RT2860
-	if ((pAd->MACVersion == 0x28600100) && (!IrqState))
+	if (pAd->MACVersion == 0x28600100)
+	{
+		QueIdx = (bUseDataQ ==TRUE ? QueIdx : 3);
+		bUseDataQ = TRUE;
+	}
+	if (bUseDataQ && (!IrqState))
 		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-#endif
+#endif // RTMP_MAC_PCI //
+
 	do
 	{
 		// Reset is in progress, stop immediately
-		if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
 			 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
 			 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
 		{
@@ -136,13 +146,16 @@  NDIS_STATUS MiniportMMRequest(
 
 		// Check Free priority queue
 		// Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
-
-		// 2860C use Tx Ring
-		if (pAd->MACVersion == 0x28600100)
+#ifdef RTMP_MAC_PCI
+		if (bUseDataQ)
 		{
+			retryCnt = MAX_DATAMM_RETRY;
+			// free Tx(QueIdx) resources
+			RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
 			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
 		}
 		else
+#endif // RTMP_MAC_PCI //
 		{
 			FreeNum = GET_MGMTRING_FREENO(pAd);
 		}
@@ -162,96 +175,51 @@  NDIS_STATUS MiniportMMRequest(
 			//pAd->CommonCfg.MlmeRate = RATE_2;
 
 
+#ifdef RTMP_MAC_PCI
+			if (bUseDataQ)
+			{
+				Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
+				retryCnt--;
+			}
+			else
+#endif // RTMP_MAC_PCI //
 			Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
-			if (Status != NDIS_STATUS_SUCCESS)
+			if (Status == NDIS_STATUS_SUCCESS)
+				retryCnt = 0;
+			else
 				RTMPFreeNdisPacket(pAd, pPacket);
 		}
 		else
 		{
 			pAd->RalinkCounters.MgmtRingFullCount++;
+#ifdef RTMP_MAC_PCI
+			if (bUseDataQ)
+			{
+				retryCnt--;
+				DBGPRINT(RT_DEBUG_TRACE, ("retryCnt %d\n", retryCnt));
+				if (retryCnt == 0)
+				{
+					DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
+											QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+				}
+			}
+#endif // RTMP_MAC_PCI //
 			DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
 										QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
 		}
+	} while (retryCnt > 0);
 
-	} while (FALSE);
 
-#ifdef RT2860
-	// 2860C use Tx Ring
-	if ((pAd->MACVersion == 0x28600100) && (!IrqState))
+#ifdef RTMP_MAC_PCI
+	if (bUseDataQ && (!IrqState))
 		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-#endif
+#endif // RTMP_MAC_PCI //
+
 	return Status;
 }
 
-#ifdef RT2860
-NDIS_STATUS MiniportMMRequestUnlock(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			QueIdx,
-	IN	PUCHAR			pData,
-	IN	UINT			Length)
-{
-	PNDIS_PACKET	pPacket;
-	NDIS_STATUS  Status = NDIS_STATUS_SUCCESS;
-	ULONG	 FreeNum;
-	TXWI_STRUC		TXWI;
-	ULONG	SW_TX_IDX;
-	PTXD_STRUC		pTxD;
-
-	QueIdx = 3;
-	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
-
-	do
-	{
-		// Reset is in progress, stop immediately
-		if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-			 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
-			 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
-		{
-			Status = NDIS_STATUS_FAILURE;
-			break;
-		}
-
-		// Check Free priority queue
-		// Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
-		// 2860C use Tx Ring
-		if (pAd->MACVersion == 0x28600100)
-		{
-			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
-			SW_TX_IDX = pAd->TxRing[QueIdx].TxCpuIdx;
-			pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SW_TX_IDX].AllocVa;
-		}
-		else
-		{
-			FreeNum = GET_MGMTRING_FREENO(pAd);
-			SW_TX_IDX = pAd->MgmtRing.TxCpuIdx;
-			pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SW_TX_IDX].AllocVa;
-		}
-		if ((FreeNum > 0))
-		{
-			NdisZeroMemory(&TXWI, TXWI_SIZE);
-			Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&TXWI, TXWI_SIZE, pData, Length);
-			if (Status != NDIS_STATUS_SUCCESS)
-			{
-				DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
-				break;
-			}
-
-			Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
-			if (Status != NDIS_STATUS_SUCCESS)
-				RTMPFreeNdisPacket(pAd, pPacket);
-		}
-		else
-		{
-			pAd->RalinkCounters.MgmtRingFullCount++;
-			DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing\n", QueIdx));
-		}
-
-	} while (FALSE);
 
 
-	return Status;
-}
-#endif
 
 /*
 	========================================================================
@@ -282,203 +250,33 @@  NDIS_STATUS MlmeHardTransmit(
 	IN	UCHAR			QueIdx,
 	IN	PNDIS_PACKET	pPacket)
 {
-	if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
-	{
-		return NDIS_STATUS_FAILURE;
-	}
-
-#ifdef RT2860
-	if ( pAd->MACVersion == 0x28600100 )
-		return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
-	else
-#endif
-		return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
-
-}
-
-#ifdef RT2860
-NDIS_STATUS MlmeHardTransmitTxRing(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	QueIdx,
-	IN	PNDIS_PACKET	pPacket)
-{
 	PACKET_INFO 	PacketInfo;
 	PUCHAR			pSrcBufVA;
 	UINT			SrcBufLen;
-	PTXD_STRUC		pTxD;
 	PHEADER_802_11	pHeader_802_11;
-	BOOLEAN 		bAckRequired, bInsertTimestamp;
-	ULONG			SrcBufPA;
-	UCHAR			MlmeRate;
-	ULONG			SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
-	PTXWI_STRUC 	pFirstTxWI;
-	ULONG	 FreeNum;
-	MAC_TABLE_ENTRY	*pMacEntry = NULL;
-
 
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-	if (pSrcBufVA == NULL)
-	{
-		// The buffer shouldn't be NULL
-		return NDIS_STATUS_FAILURE;
-	}
-
-	// Make sure MGMT ring resource won't be used by other threads
-	//NdisAcquireSpinLock(&pAd->TxRingLock);
-
-	FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
-
-	if (FreeNum == 0)
+	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+		)
 	{
-		//NdisReleaseSpinLock(&pAd->TxRingLock);
 		return NDIS_STATUS_FAILURE;
 	}
 
-	SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
-
-	pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
-
-	if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
-	{
-		printk("MlmeHardTransmit Error\n");
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+	if (pSrcBufVA == NULL)
 		return NDIS_STATUS_FAILURE;
-	}
 
-	// outgoing frame always wakeup PHY to prevent frame lost
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		AsicForceWakeup(pAd, FROM_TX);
+	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);
 
-	pFirstTxWI	=(PTXWI_STRUC)pSrcBufVA;
 
-	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
-	if (pHeader_802_11->Addr1[0] & 0x01)
-	{
-		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
-	}
-	else
-	{
-		MlmeRate = pAd->CommonCfg.MlmeRate;
-	}
-
-	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
-		(pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
-	{
-		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
-	}
-
-	// Verify Mlme rate for a / g bands.
-	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
-		MlmeRate = RATE_6;
-
-	//
-	// Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
-	// Snice it's been set to 0 while on MgtMacHeaderInit
-	// By the way this will cause frame to be send on PWR_SAVE failed.
-	//
-	//
-	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
-
-    // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
-	if (pHeader_802_11->FC.Type != BTYPE_DATA)
-    {
-    	if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
-    	{
-    		pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
-    	}
-    	else
-    	{
-    		pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
-    	}
-    }
-
-	bInsertTimestamp = FALSE;
-	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
-	{
-		bAckRequired = FALSE;
-	}
-	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
-	{
-		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
-		{
-			bAckRequired = FALSE;
-			pHeader_802_11->Duration = 0;
-		}
-		else
-		{
-			bAckRequired = TRUE;
-			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
-			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
-			{
-				bInsertTimestamp = TRUE;
-			}
-		}
-	}
-	pHeader_802_11->Sequence = pAd->Sequence++;
-	if (pAd->Sequence > 0xfff)
-		pAd->Sequence = 0;
-	// Before radar detection done, mgmt frame can not be sent but probe req
-	// Because we need to use probe req to trigger driver to send probe req in passive scan
-	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
-		&& (pAd->CommonCfg.bIEEE80211H == 1)
-		&& (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
-		return (NDIS_STATUS_FAILURE);
-	}
-
-	//
-	// fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
-	// should always has only one ohysical buffer, and the whole frame size equals
-	// to the first scatter buffer size
-	//
-
-	// Initialize TX Descriptor
-	// For inter-frame gap, the number is for this frame and next frame
-	// For MLME rate, we will fix as 2Mb to match other vendor's implement
-
-// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
-	// Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
-	if (pMacEntry == NULL)
-	{
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
-		0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	}
+#ifdef RTMP_MAC_PCI
+	if ( pAd->MACVersion == 0x28600100 )
+		return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
 	else
-	{
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
-					bInsertTimestamp, FALSE, bAckRequired, FALSE,
-					0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
-					pMacEntry->MaxHTPhyMode.field.MCS, 0,
-					(UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
-					IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
-	}
-
-	pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
-	pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
-
-	SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
-
-
-	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
-	pTxD->LastSec0 = 1;
-	pTxD->LastSec1 = 1;
-	pTxD->SDLen0 = SrcBufLen;
-	pTxD->SDLen1 = 0;
-	pTxD->SDPtr0 = SrcBufPA;
-	pTxD->DMADONE = 0;
-
-	pAd->RalinkCounters.KickTxCount++;
-	pAd->RalinkCounters.OneSecTxDoneCount++;
-
-   	// Increase TX_CTX_IDX, but write to register later.
-	INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
-
-	RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10,  pAd->TxRing[QueIdx].TxCpuIdx);
+#endif // RTMP_MAC_PCI //
+		return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
 
-	return NDIS_STATUS_SUCCESS;
 }
-#endif /* RT2860 */
+
 
 NDIS_STATUS MlmeHardTransmitMgmtRing(
 	IN	PRTMP_ADAPTER	pAd,
@@ -493,25 +291,24 @@  NDIS_STATUS MlmeHardTransmitMgmtRing(
 	UCHAR			MlmeRate;
 	PTXWI_STRUC 	pFirstTxWI;
 	MAC_TABLE_ENTRY	*pMacEntry = NULL;
+	UCHAR			PID;
 
 	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-		RTMP_SEM_LOCK(&pAd->MgmtRingLock);
-
 
+	// Make sure MGMT ring resource won't be used by other threads
+	RTMP_SEM_LOCK(&pAd->MgmtRingLock);
 	if (pSrcBufVA == NULL)
 	{
+		// The buffer shouldn't be NULL
 		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
 		return NDIS_STATUS_FAILURE;
 	}
 
+	{
 	// outgoing frame always wakeup PHY to prevent frame lost
 	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
-		AsicForceWakeup(pAd, FROM_TX);
-#endif
-#ifdef RT2870
 		AsicForceWakeup(pAd, TRUE);
-#endif
+	}
 
 	pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA +  TXINFO_SIZE);
 	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
@@ -553,19 +350,28 @@  NDIS_STATUS MlmeHardTransmitMgmtRing(
 	// Snice it's been set to 0 while on MgtMacHeaderInit
 	// By the way this will cause frame to be send on PWR_SAVE failed.
 	//
-	// pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
+	pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; // (pAd->StaCfg.Psm == PWR_SAVE);
+
 	//
 	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
-
     // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
-	if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
+//	if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
 	{
-		if ((pAd->StaCfg.Psm == PWR_SAVE) &&
-			(pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
+		if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) ||
+			((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+			((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) ||
+			(pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC))))
+		{
+			if (pAd->StaCfg.Psm == PWR_SAVE)
 			pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
 		else
-			pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
+				pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
 	}
+	}
+
+
+
+
 
 	bInsertTimestamp = FALSE;
 	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
@@ -579,6 +385,9 @@  NDIS_STATUS MlmeHardTransmitMgmtRing(
 	}
 	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
 	{
+		//pAd->Sequence++;
+		//pHeader_802_11->Sequence = pAd->Sequence;
+
 		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
 		{
 			bAckRequired = FALSE;
@@ -588,9 +397,14 @@  NDIS_STATUS MlmeHardTransmitMgmtRing(
 		{
 			bAckRequired = TRUE;
 			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
-			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
+			if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) && (pHeader_802_11->FC.Type == BTYPE_MGMT))
 			{
 				bInsertTimestamp = TRUE;
+				bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Response
+			}
+			else if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) && (pHeader_802_11->FC.Type == BTYPE_MGMT))
+			{
+				bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Request
 			}
 		}
 	}
@@ -606,28 +420,35 @@  NDIS_STATUS MlmeHardTransmitMgmtRing(
 		&& (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
 	{
 		DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
+//		if (!IrqState)
 		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
 		return (NDIS_STATUS_FAILURE);
 	}
 
+
 	//
 	// fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
-	// should always has only one ohysical buffer, and the whole frame size equals
+	// should always has only one physical buffer, and the whole frame size equals
 	// to the first scatter buffer size
 	//
 
 	// Initialize TX Descriptor
 	// For inter-frame gap, the number is for this frame and next frame
 	// For MLME rate, we will fix as 2Mb to match other vendor's implement
+//	pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
 
 // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
+	PID = PID_MGMT;
+
+
 	if (pMacEntry == NULL)
 	{
 		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
-		0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+		0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
 	}
 	else
 	{
+		/* dont use low rate to send QoS Null data frame */
 		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
 					bInsertTimestamp, FALSE, bAckRequired, FALSE,
 					0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
@@ -640,6 +461,7 @@  NDIS_STATUS MlmeHardTransmitMgmtRing(
 	HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
 
 	// Make sure to release MGMT ring resource
+//	if (!IrqState)
 	RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
 	return NDIS_STATUS_SUCCESS;
 }
@@ -737,10 +559,6 @@  static UCHAR TxPktClassification(
 		bHTRate = TRUE;
 		if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
 			TxFrameType = TX_LEGACY_FRAME;
-#ifdef UAPSD_AP_SUPPORT
-		else if (RTMP_GET_PACKET_EOSP(pPacket))
-			TxFrameType = TX_LEGACY_FRAME;
-#endif // UAPSD_AP_SUPPORT //
 		else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
 			return TX_AMPDU_FRAME;
 		else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
@@ -799,12 +617,6 @@  BOOLEAN RTMP_FillTxBlkInfo(
 	{
 		pTxBlk->pMacEntry = NULL;
 		{
-#ifdef MCAST_RATE_SPECIFIC
-			PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
-			if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
-				pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
-			else
-#endif // MCAST_RATE_SPECIFIC //
 				pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
 		}
 
@@ -832,16 +644,25 @@  BOOLEAN RTMP_FillTxBlkInfo(
 		else
 			TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
 
+		if ((pAd->OpMode == OPMODE_STA) &&
+			(ADHOC_ON(pAd)) &&
+			(RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS)))
 		{
+			if(pAd->CommonCfg.PSPXlink)
+				TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
+		}
+
+		{
+		{
+
 			// If support WMM, enable it.
-#ifdef RT2860
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
-#endif
-#ifdef RT2870
 			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
 				CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
-#endif
 				TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
+
+//				if (pAd->StaCfg.bAutoTxRateSwitch)
+//					TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
+			}
 		}
 
 		if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
@@ -871,12 +692,6 @@  BOOLEAN RTMP_FillTxBlkInfo(
 			{
 				TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
 			}
-#ifdef UAPSD_AP_SUPPORT
-			if (RTMP_GET_PACKET_EOSP(pPacket))
-			{
-				TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
-			}
-#endif // UAPSD_AP_SUPPORT //
 		}
 		else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
 		{
@@ -896,7 +711,7 @@  BOOLEAN CanDoAggregateTransmit(
 	IN TX_BLK		*pTxBlk)
 {
 
-	//printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
+	//DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType));
 
 	if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
 		return FALSE;
@@ -922,6 +737,7 @@  BOOLEAN CanDoAggregateTransmit(
 		return TRUE;
 	else
 		return FALSE;
+
 }
 
 
@@ -970,7 +786,6 @@  VOID RTMPDeQueuePacket(
 	if (QIdx == NUM_OF_TX_RING)
 	{
 		sQIdx = 0;
-//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
 		eQIdx = 3;	// 4 ACs, start from 0.
 	}
 	else
@@ -982,7 +797,7 @@  VOID RTMPDeQueuePacket(
 	{
 		Count=0;
 
-		RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
+		RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags);
 
 
 		while (1)
@@ -993,7 +808,7 @@  VOID RTMPDeQueuePacket(
 										fRTMP_ADAPTER_HALT_IN_PROGRESS |
 										fRTMP_ADAPTER_NIC_NOT_EXIST))))
 			{
-				RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+				RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
 				return;
 			}
 
@@ -1006,7 +821,8 @@  VOID RTMPDeQueuePacket(
 				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
 				break;
 			}
-#ifdef RT2860
+
+#ifdef RTMP_MAC_PCI
 			FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
 
 
@@ -1016,7 +832,8 @@  VOID RTMPDeQueuePacket(
 				RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
 				FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
 			}
-#endif /* RT2860 */
+#endif // RTMP_MAC_PCI //
+
 			// probe the Queue Head
 			pQueue = &pAd->TxSwQueue[QueIdx];
 			if ((pEntry = pQueue->Head) == NULL)
@@ -1027,12 +844,14 @@  VOID RTMPDeQueuePacket(
 
 			pTxBlk = &TxBlk;
 			NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
+			//InitializeQueueHeader(&pTxBlk->TxPacketList);		// Didn't need it because we already memzero it.
 			pTxBlk->QueIdx = QueIdx;
 
-			pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+
 
 			// Early check to make sure we have enoguh Tx Resource.
-			hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
+			hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
 			if (!hasTxDesc)
 			{
 				pAd->PrivateInfo.TxRingFullCnt++;
@@ -1065,16 +884,16 @@  VOID RTMPDeQueuePacket(
 						break;
 
 					// For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
-					pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
 					FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
-					hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
+					hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
 					if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
 						break;
 
 					//Remove the packet from the TxSwQueue and insert into pTxBlk
 					pEntry = RemoveHeadQueue(pQueue);
 					ASSERT(pEntry);
-					pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
 					pTxBlk->TotalFrameNum++;
 					pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	// The real fragment number maybe vary
 					pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
@@ -1085,29 +904,29 @@  VOID RTMPDeQueuePacket(
 					pTxBlk->TxFrameType = TX_LEGACY_FRAME;
 			}
 
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-#endif // RT2870 //
-
+#endif // RTMP_MAC_USB //
 			Count += pTxBlk->TxPacketList.Number;
 
 			// Do HardTransmit now.
 			Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
 
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
 			// static rate also need NICUpdateFifoStaCounters() function.
 			//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
 				NICUpdateFifoStaCounters(pAd);
-#endif
+#endif // RTMP_MAC_PCI //
+
 		}
 
-		RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+		RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
 
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 		if (!hasTxDesc)
 			RTUSBKickBulkOut(pAd);
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
 	}
 
 }
@@ -1243,9 +1062,16 @@  VOID RTMPWriteTxWI(
 	pTxWI->NSEQ = NSeq;
 	// John tune the performace with Intel Client in 20 MHz performance
 	BASize = pAd->CommonCfg.TxBASize;
-
+	if (pAd->MACVersion == 0x28720200)
+	{
+		if( BASize >13 )
+			BASize =13;
+	}
+	else
+	{
 	if( BASize >7 )
 		BASize =7;
+	}
 	pTxWI->BAWinSize = BASize;
 	pTxWI->ShortGI = pTransmit->field.ShortGI;
 	pTxWI->STBC = pTransmit->field.STBC;
@@ -1387,7 +1213,7 @@  VOID RTMPWriteTxWI_Cache(
 	IN	OUT PTXWI_STRUC		pTxWI,
 	IN	TX_BLK				*pTxBlk)
 {
-	PHTTRANSMIT_SETTING	pTransmit;
+	PHTTRANSMIT_SETTING	/*pTxHTPhyMode,*/ pTransmit;
 	PMAC_TABLE_ENTRY	pMacEntry;
 
 	//
@@ -1396,6 +1222,9 @@  VOID RTMPWriteTxWI_Cache(
 	pMacEntry = pTxBlk->pMacEntry;
 	pTransmit = pTxBlk->pTransmit;
 
+	//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
+	//if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
+	//if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
 	if (pMacEntry->bAutoTxRateSwitch)
 	{
 		pTxWI->txop = IFS_HTTXOP;
@@ -1440,53 +1269,6 @@  VOID RTMPWriteTxWI_Cache(
 }
 
 
-/*
-	========================================================================
-
-	Routine Description:
-		Calculates the duration which is required to transmit out frames
-	with given size and specified rate.
-
-	Arguments:
-		pTxD		Pointer to transmit descriptor
-		Ack 		Setting for Ack requirement bit
-		Fragment	Setting for Fragment bit
-		RetryMode	Setting for retry mode
-		Ifs 		Setting for IFS gap
-		Rate		Setting for transmit rate
-		Service 	Setting for service
-		Length		Frame length
-		TxPreamble	Short or Long preamble when using CCK rates
-		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID RTMPWriteTxDescriptor(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PTXD_STRUC		pTxD,
-	IN	BOOLEAN 		bWIV,
-	IN	UCHAR			QueueSEL)
-{
-	//
-	// Always use Long preamble before verifiation short preamble functionality works well.
-	// Todo: remove the following line if short preamble functionality works
-	//
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-
-	pTxD->WIV	= (bWIV) ? 1: 0;
-	pTxD->QSEL= (QueueSEL);
-	if (pAd->bGenOneHCCA == TRUE)
-		pTxD->QSEL= FIFO_HCCA;
-	pTxD->DMADONE = 0;
-}
-
-
 // should be called only when -
 // 1. MEADIA_CONNECTED
 // 2. AGGREGATION_IN_USED
@@ -1582,12 +1364,14 @@  PQUEUE_HEADER	RTMPCheckTxSwQueue(
 {
 
 	ULONG	Number;
+	// 2004-11-15 to be removed. test aggregation only
+//	if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
+//		 return NULL;
 
 	Number = pAd->TxSwQueue[QID_AC_BK].Number
 			 + pAd->TxSwQueue[QID_AC_BE].Number
 			 + pAd->TxSwQueue[QID_AC_VI].Number
-			 + pAd->TxSwQueue[QID_AC_VO].Number
-			 + pAd->TxSwQueue[QID_HCCA].Number;
+			 + pAd->TxSwQueue[QID_AC_VO].Number;
 
 	if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
 	{
@@ -1609,11 +1393,6 @@  PQUEUE_HEADER	RTMPCheckTxSwQueue(
 		*pQueIdx = QID_AC_BK;
 		return (&pAd->TxSwQueue[QID_AC_BK]);
 	}
-	else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
-	{
-		*pQueIdx = QID_HCCA;
-		return (&pAd->TxSwQueue[QID_HCCA]);
-	}
 
 	// No packet pending in Tx Sw queue
 	*pQueIdx = QID_AC_BK;
@@ -1621,277 +1400,6 @@  PQUEUE_HEADER	RTMPCheckTxSwQueue(
 	return (NULL);
 }
 
-#ifdef RT2860
-BOOLEAN  RTMPFreeTXDUponTxDmaDone(
-	IN PRTMP_ADAPTER	pAd,
-	IN UCHAR			QueIdx)
-{
-	PRTMP_TX_RING pTxRing;
-	PTXD_STRUC	  pTxD;
-	PNDIS_PACKET  pPacket;
-	UCHAR	FREE = 0;
-	TXD_STRUC	TxD, *pOriTxD;
-	//ULONG		IrqFlags;
-	BOOLEAN			bReschedule = FALSE;
-
-
-	ASSERT(QueIdx < NUM_OF_TX_RING);
-	pTxRing = &pAd->TxRing[QueIdx];
-
-	RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
-	while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
-	{
-		// static rate also need NICUpdateFifoStaCounters() function.
-		//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
-			NICUpdateFifoStaCounters(pAd);
-
-		/* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
-		FREE++;
-                pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
-		pOriTxD = pTxD;
-                NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
-		pTxD = &TxD;
-
-		pTxD->DMADONE = 0;
-
-/*====================================================================*/
-		{
-			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
-			if (pPacket)
-			{
-#ifdef CONFIG_5VT_ENHANCE
-				if (RTMP_GET_PACKET_5VT(pPacket))
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
-				else
-#endif // CONFIG_5VT_ENHANCE //
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNdisPacket as NULL after clear
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
-
-			ASSERT(pPacket == NULL);
-			if (pPacket)
-			{
-#ifdef CONFIG_5VT_ENHANCE
-				if (RTMP_GET_PACKET_5VT(pPacket))
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
-				else
-#endif // CONFIG_5VT_ENHANCE //
-					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-			}
-			//Always assign pNextNdisPacket as NULL after clear
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-		}
-/*====================================================================*/
-
-		pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
-		pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
-		INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
-		/* get tx_tdx_idx again */
-		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
-
-        NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
-	}
-
-
-	return  bReschedule;
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process TX Rings DMA Done interrupt, running in DPC level
-
-	Arguments:
-		Adapter 	Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-BOOLEAN	RTMPHandleTxRingDmaDoneInterrupt(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	INT_SOURCE_CSR_STRUC TxRingBitmap)
-{
-    unsigned long	IrqFlags;
-	BOOLEAN			bReschedule = FALSE;
-
-	// Make sure Tx ring resource won't be used by other threads
-
-	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-
-	if (TxRingBitmap.field.Ac0DmaDone)
-		bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
-
-	if (TxRingBitmap.field.HccaDmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
-
-	if (TxRingBitmap.field.Ac3DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
-
-	if (TxRingBitmap.field.Ac2DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
-
-	if (TxRingBitmap.field.Ac1DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
-
-	// Make sure to release Tx ring resource
-	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-
-	// Dequeue outgoing frames from TxSwQueue[] and process it
-	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-
-	return  bReschedule;
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process MGMT ring DMA done interrupt, running in DPC level
-
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-VOID	RTMPHandleMgmtRingDmaDoneInterrupt(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	PTXD_STRUC	 pTxD;
-	PNDIS_PACKET pPacket;
-	UCHAR	FREE = 0;
-	PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
-
-	NdisAcquireSpinLock(&pAd->MgmtRingLock);
-
-	RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
-	while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
-	{
-		FREE++;
-		pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
-		pTxD->DMADONE = 0;
-		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
-
-
-		if (pPacket)
-		{
-			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-		}
-		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
-
-		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
-		if (pPacket)
-		{
-			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-		}
-		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-		INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
-	}
-	NdisReleaseSpinLock(&pAd->MgmtRingLock);
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		Adapter 	Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID	RTMPHandleTBTTInterrupt(
-	IN PRTMP_ADAPTER pAd)
-{
-	{
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		{
-		}
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		Adapter 	Pointer to our adapter. Rewrite beacon content before next send-out.
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-VOID	RTMPHandlePreTBTTInterrupt(
-	IN PRTMP_ADAPTER pAd)
-{
-	{
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
-		}
-	}
-
-
-}
-
-VOID	RTMPHandleRxCoherentInterrupt(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-
-	if (pAd == NULL)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
-		return;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
-
-	GloCfg.field.EnTXWriteBackDDONE = 0;
-	GloCfg.field.EnableRxDMA = 0;
-	GloCfg.field.EnableTxDMA = 0;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	RTMPRingCleanUp(pAd, QID_AC_BE);
-	RTMPRingCleanUp(pAd, QID_AC_BK);
-	RTMPRingCleanUp(pAd, QID_AC_VI);
-	RTMPRingCleanUp(pAd, QID_AC_VO);
-	RTMPRingCleanUp(pAd, QID_HCCA);
-	RTMPRingCleanUp(pAd, QID_MGMT);
-	RTMPRingCleanUp(pAd, QID_RX);
-
-	RTMPEnableRxTx(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
-}
-#endif /* RT2860 */
 
 /*
 	========================================================================
@@ -1922,9 +1430,11 @@  VOID	RTMPSuspendMsduTransmission(
 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
 
 	// set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
+	//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
 	RTMPSetAGCInitValue(pAd, BW_20);
 
 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+	//RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000);		// abort all TX rings
 }
 
 
@@ -1949,8 +1459,11 @@  VOID	RTMPSuspendMsduTransmission(
 VOID RTMPResumeMsduTransmission(
 	IN	PRTMP_ADAPTER	pAd)
 {
+//    UCHAR			IrqState;
+
 	DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
 
+
 	// After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
 	// R66 should not be 0
 	if (pAd->BbpTuning.R66CurrentValue == 0)
@@ -1962,6 +1475,11 @@  VOID RTMPResumeMsduTransmission(
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
 
 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+// sample, for IRQ LOCK to SEM LOCK
+//    IrqState = pAd->irq_disabled;
+//	if (IrqState)
+//		RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+//    else
 	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
 }
 
@@ -1990,7 +1508,9 @@  UINT deaggregate_AMSDU_announce(
 
 		nMSDU++;
 
+		//hex_dump("subheader", pData, 64);
 		pAMSDUsubheader = (PHEADER_802_3)pData;
+		//pData += LENGTH_802_3;
 		PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
 		SubFrameSize = PayloadSize + LENGTH_802_3;
 
@@ -2000,6 +1520,8 @@  UINT deaggregate_AMSDU_announce(
 			break;
 		}
 
+		//DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n",  nMSDU, PayloadSize));
+
 		pPayload = pData + LENGTH_802_3;
 		pDA = pData;
 		pSA = pData + MAC_ADDR_LEN;
@@ -2009,15 +1531,17 @@  UINT deaggregate_AMSDU_announce(
 
 		if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
 		{
-		    // avoid local heap overflow, use dyanamic allocation
+			/* avoid local heap overflow, use dyanamic allocation */
 		   MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-		   if (Elem == NULL)
-			return;
+			if (Elem != NULL)
+			{
 		   memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
 		   Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
-		   WpaEAPOLKeyAction(pAd, Elem);
+				//WpaEAPOLKeyAction(pAd, Elem);
+				REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID, Elem->Msg, Elem->MsgLen, 0, 0, 0, 0);
 		   kfree(Elem);
 		}
+		}
 
 		{
 	        	if (pRemovedLLCSNAP)
@@ -2121,6 +1645,8 @@  MAC_TABLE_ENTRY *MacTableInsertEntry(
 	UCHAR HashIdx;
 	int i, FirstWcid;
 	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+//	USHORT	offset;
+//	ULONG	addr;
 
 	// if FULL, return
 	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
@@ -2183,22 +1709,15 @@  MAC_TABLE_ENTRY *MacTableInsertEntry(
 					pEntry->AuthMode = pAd->StaCfg.AuthMode;
 					pEntry->WepStatus = pAd->StaCfg.WepStatus;
 					pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 					AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
-#endif
+#endif // RTMP_MAC_PCI //
 				}
 			}
 
 			pEntry->GTKState = REKEY_NEGOTIATING;
 			pEntry->PairwiseKey.KeyLen = 0;
 			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
-
-#ifdef RT2860
-			if ((pAd->OpMode == OPMODE_STA) &&
-				(pAd->StaCfg.BssType == BSS_ADHOC))
-				pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-			else
-#endif
 			pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
 
 			pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
@@ -2210,13 +1729,14 @@  MAC_TABLE_ENTRY *MacTableInsertEntry(
 			pEntry->PsMode = PWR_ACTIVE;
 			pEntry->PsQIdleCount = 0;
 			pEntry->NoDataIdleCount = 0;
+			pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
 			pEntry->ContinueTxFailCnt = 0;
 			InitializeQueueHeader(&pEntry->PsQueue);
 
 
 			pAd->MacTab.Size ++;
 			// Add this entry into ASIC RX WCID search table
-			RT28XX_STA_ENTRY_ADD(pAd, pEntry);
+			RTMP_STA_ENTRY_ADD(pAd, pEntry);
 
 
 
@@ -2260,6 +1780,8 @@  BOOLEAN MacTableDeleteEntry(
 	USHORT HashIdx;
 	MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
 	BOOLEAN Cancelled;
+	//USHORT	offset;	// unused variable
+	//UCHAR	j;			// unused variable
 
 	if (wcid >= MAX_LEN_OF_MAC_TABLE)
 		return FALSE;
@@ -2267,6 +1789,7 @@  BOOLEAN MacTableDeleteEntry(
 	NdisAcquireSpinLock(&pAd->MacTabLock);
 
 	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+	//pEntry = pAd->MacTab.Hash[HashIdx];
 	pEntry = &pAd->MacTab.Content[wcid];
 
 	if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
@@ -2276,7 +1799,7 @@  BOOLEAN MacTableDeleteEntry(
 		{
 
 			// Delete this entry from ASIC on-chip WCID Table
-			RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
+			RTMP_STA_ENTRY_MAC_RESET(pAd, wcid);
 
 			// free resources of BA
 			BASessionTearDownALL(pAd, pEntry->Aid);
@@ -2308,7 +1831,7 @@  BOOLEAN MacTableDeleteEntry(
 			// not found !!!
 			ASSERT(pProbeEntry != NULL);
 
-			RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
+			RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
 
 
 		if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
@@ -2324,7 +1847,7 @@  BOOLEAN MacTableDeleteEntry(
 		}
 		else
 		{
-			printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid);
+			DBGPRINT(RT_DEBUG_OFF, ("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid));
 		}
 	}
 
@@ -2334,13 +1857,8 @@  BOOLEAN MacTableDeleteEntry(
 	if (pAd->MacTab.Size == 0)
 	{
 		pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
-#ifdef RT2860
-		AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
-#else
-		// edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
-		// Set MAC register value according operation mode
-		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
-#endif
+		//AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
+		RTMP_UPDATE_PROTECT(pAd);  // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
 	}
 
 	return TRUE;
@@ -2362,24 +1880,25 @@  VOID MacTableReset(
 	DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
 	//NdisAcquireSpinLock(&pAd->MacTabLock);
 
+
 	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
 	{
-#ifdef RT2860
-		RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
-#endif
+#ifdef RTMP_MAC_PCI
+		RTMP_STA_ENTRY_MAC_RESET(pAd, i);
+#endif // RTMP_MAC_PCI //
 		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
 	   {
+
+
 			// free resources of BA
 			BASessionTearDownALL(pAd, i);
 
 			pAd->MacTab.Content[i].ValidAsCLI = FALSE;
 
-
-
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 			NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
-			RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
-#endif // RT2870 //
+			RTMP_STA_ENTRY_MAC_RESET(pAd, i);
+#endif // RTMP_MAC_USB //
 
 			//AsicDelWcidTab(pAd, i);
 		}
@@ -2544,7 +2063,7 @@  BOOLEAN RTMPCheckEtherType(
 	RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
 
 	// get Ethernet protocol field
-	TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
+	TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13];
 
 	pSrcBuf += LENGTH_802_3;	// Skip the Ethernet Header.
 
@@ -2558,7 +2077,7 @@  BOOLEAN RTMPCheckEtherType(
 		*/
 		if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
 		{
-			Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
+			Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 6, &Byte0, &Byte1);
 			RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
 			TypeLen = (USHORT)((Byte0 << 8) + Byte1);
 			pSrcBuf += 8; // Skip this LLC/SNAP header
@@ -2584,7 +2103,7 @@  BOOLEAN RTMPCheckEtherType(
 		   Frame Check Sequence (4-bytes) */
 
 		RTMP_SET_PACKET_VLAN(pPacket, 1);
-		Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
+		Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 2, &Byte0, &Byte1);
 		TypeLen = (USHORT)((Byte0 << 8) + Byte1);
 
 		pSrcBuf += 4; // Skip the VLAN Header.
@@ -2600,8 +2119,8 @@  BOOLEAN RTMPCheckEtherType(
 					ASSERT((pktLen > 34));	// 14 for ethernet header, 20 for IP header
 
 					pSrcBuf += 20;	// Skip the IP header
-					srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
-					dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
+					srcPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf)));
+					dstPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf+2)));
 
 					if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
 					{	//It's a BOOTP/DHCP packet
@@ -2692,7 +2211,7 @@  VOID Indicate_Legacy_Packet(
 
 	STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
 
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 	if (pAd->CommonCfg.bDisableReordering == 0)
 	{
 		PBA_REC_ENTRY		pBAEntry;
@@ -2701,7 +2220,7 @@  VOID Indicate_Legacy_Packet(
 		UCHAR				TID = pRxBlk->pRxWI->TID;
 		USHORT				Idx;
 
-#define REORDERING_PACKET_TIMEOUT		((100 * HZ)/1000)	// system ticks -- 100 ms
+#define REORDERING_PACKET_TIMEOUT		((100 * OS_HZ)/1000)	// system ticks -- 100 ms
 
 		if (Wcid < MAX_LEN_OF_MAC_TABLE)
 		{
@@ -2715,14 +2234,15 @@  VOID Indicate_Legacy_Packet(
 					 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
 	   				)
 				{
-					printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU);
+					DBGPRINT(RT_DEBUG_OFF, ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n",
+												pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU));
 					hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
 					ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
 				}
 			}
 		}
 	}
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
 
 	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
 
diff --git a/drivers/staging/rt2860/common/cmm_data_pci.c b/drivers/staging/rt2860/common/cmm_data_pci.c
new file mode 100644
index 0000000..d808e7d
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_data_pci.c
@@ -0,0 +1,1153 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+/*
+   All functions in this file must be PCI-depended, or you should out your function
+	in other files.
+
+*/
+#include	"../rt_config.h"
+
+
+USHORT RtmpPCI_WriteTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber)
+{
+
+	UCHAR			*pDMAHeaderBufVA;
+	USHORT			TxIdx, RetTxIdx;
+	PTXD_STRUC		pTxD;
+	UINT32			BufBasePaLow;
+	PRTMP_TX_RING	pTxRing;
+	USHORT			hwHeaderLen;
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+	if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+	{
+		//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
+		hwHeaderLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
+	}
+	else
+	{
+		//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+		hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+	}
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
+
+	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+	//
+	// build Tx Descriptor
+	//
+
+	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+	RetTxIdx = TxIdx;
+	//
+	// Update Tx index
+	//
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+}
+
+
+USHORT RtmpPCI_WriteSingleTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber)
+{
+
+	UCHAR			*pDMAHeaderBufVA;
+	USHORT			TxIdx, RetTxIdx;
+	PTXD_STRUC		pTxD;
+	UINT32			BufBasePaLow;
+	PRTMP_TX_RING	pTxRing;
+	USHORT			hwHeaderLen;
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+	//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
+
+	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+	//
+	// build Tx Descriptor
+	//
+	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+	RetTxIdx = TxIdx;
+	//
+	// Update Tx index
+	//
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+}
+
+
+USHORT RtmpPCI_WriteMultiTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			frameNum,
+	OUT	USHORT			*FreeNumber)
+{
+	BOOLEAN bIsLast;
+	UCHAR			*pDMAHeaderBufVA;
+	USHORT			TxIdx, RetTxIdx;
+	PTXD_STRUC		pTxD;
+	UINT32			BufBasePaLow;
+	PRTMP_TX_RING	pTxRing;
+	USHORT			hwHdrLen;
+	UINT32			firstDMALen;
+
+	bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	if (frameNum == 0)
+	{
+		// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+		if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+			//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
+			hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
+		else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
+			//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
+			hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
+		else
+			//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+			hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+		firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
+	}
+	else
+	{
+		firstDMALen = pTxBlk->MpduHeaderLen;
+	}
+
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
+
+	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+	//
+	// build Tx Descriptor
+	//
+	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = firstDMALen; // include padding
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+
+	RetTxIdx = TxIdx;
+	//
+	// Update Tx index
+	//
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+
+}
+
+
+VOID RtmpPCI_FinalWriteTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	USHORT			totalMPDUSize,
+	IN	USHORT			FirstTxIdx)
+{
+
+	PTXWI_STRUC		pTxWI;
+	PRTMP_TX_RING	pTxRing;
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
+	pTxWI->MPDUtotalByteCount = totalMPDUSize;
+
+}
+
+
+VOID RtmpPCIDataLastTxIdx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			QueIdx,
+	IN	USHORT			LastTxIdx)
+{
+	PTXD_STRUC		pTxD;
+	PRTMP_TX_RING	pTxRing;
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[QueIdx];
+
+	//
+	// build Tx Descriptor
+	//
+	pTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
+
+	pTxD->LastSec1 = 1;
+
+
+}
+
+
+USHORT	RtmpPCI_WriteFragTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			fragNum,
+	OUT	USHORT			*FreeNumber)
+{
+	UCHAR			*pDMAHeaderBufVA;
+	USHORT			TxIdx, RetTxIdx;
+	PTXD_STRUC		pTxD;
+	UINT32			BufBasePaLow;
+	PRTMP_TX_RING	pTxRing;
+	USHORT			hwHeaderLen;
+	UINT32			firstDMALen;
+
+	//
+	// Get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	//
+	// Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+	//
+	//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+	firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
+
+
+	//
+	// Build Tx Descriptor
+	//
+	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	if (fragNum == pTxBlk->TotalFragNum)
+	{
+		pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+		pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+	}
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = firstDMALen; // include padding
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = 1;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+
+	RetTxIdx = TxIdx;
+	pTxBlk->Priv += pTxBlk->SrcBufLen;
+
+	//
+	// Update Tx index
+	//
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+
+}
+
+
+/*
+	Must be run in Interrupt context
+	This function handle PCI specific TxDesc and cpu index update and kick the packet out.
+ */
+int RtmpPCIMgmtKickOut(
+	IN RTMP_ADAPTER		*pAd,
+	IN UCHAR			QueIdx,
+	IN PNDIS_PACKET		pPacket,
+	IN PUCHAR			pSrcBufVA,
+	IN UINT				SrcBufLen)
+{
+	PTXD_STRUC		pTxD;
+	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
+
+	pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
+
+	pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
+	pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
+	pTxD->LastSec0 = 1;
+	pTxD->LastSec1 = 1;
+	pTxD->DMADONE = 0;
+	pTxD->SDLen1 = 0;
+	pTxD->SDPtr0 = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
+	pTxD->SDLen0 = SrcBufLen;
+
+
+//==================================================================
+/*	DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));
+	for (i = 0; i < (TXWI_SIZE+24); i++)
+	{
+
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));
+		if ( i%4 == 3)
+			DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));
+		if ( i%16 == 15)
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));
+	}
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));*/
+//=======================================================================
+
+	pAd->RalinkCounters.KickTxCount++;
+	pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	// Increase TX_CTX_IDX, but write to register later.
+	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
+
+	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX,  pAd->MgmtRing.TxCpuIdx);
+
+	return 0;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
+
+	Arguments:
+		pRxD		Pointer to the Rx descriptor
+
+	Return Value:
+		NDIS_STATUS_SUCCESS	No err
+		NDIS_STATUS_FAILURE	Error
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS RTMPCheckRxError(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	PHEADER_802_11		pHeader,
+	IN	PRXWI_STRUC		pRxWI,
+	IN  PRT28XX_RXD_STRUC	pRxD)
+{
+	PCIPHER_KEY pWpaKey;
+	INT dBm;
+
+	// Phy errors & CRC errors
+	if (/*(pRxD->PhyErr) ||*/ (pRxD->Crc))
+	{
+		// Check RSSI for Noise Hist statistic collection.
+		dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
+		if (dBm <= -87)
+			pAd->StaCfg.RPIDensity[0] += 1;
+		else if (dBm <= -82)
+			pAd->StaCfg.RPIDensity[1] += 1;
+		else if (dBm <= -77)
+			pAd->StaCfg.RPIDensity[2] += 1;
+		else if (dBm <= -72)
+			pAd->StaCfg.RPIDensity[3] += 1;
+		else if (dBm <= -67)
+			pAd->StaCfg.RPIDensity[4] += 1;
+		else if (dBm <= -62)
+			pAd->StaCfg.RPIDensity[5] += 1;
+		else if (dBm <= -57)
+			pAd->StaCfg.RPIDensity[6] += 1;
+		else if (dBm > -57)
+			pAd->StaCfg.RPIDensity[7] += 1;
+
+		return(NDIS_STATUS_FAILURE);
+	}
+
+	// Add Rx size to channel load counter, we should ignore error counts
+	pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
+
+	// Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
+	if (pHeader != NULL)
+	{
+		if (pHeader->FC.ToDs)
+		{
+			return(NDIS_STATUS_FAILURE);
+		}
+	}
+
+	// Drop not U2M frames, cant's drop here because we will drop beacon in this case
+	// I am kind of doubting the U2M bit operation
+	// if (pRxD->U2M == 0)
+	//	return(NDIS_STATUS_FAILURE);
+
+	// drop decyption fail frame
+	if (pRxD->CipherErr)
+	{
+		if (pRxD->CipherErr == 2)
+			{DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV ok but MICErr "));}
+		else if (pRxD->CipherErr == 1)
+			{DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV Err "));}
+		else if (pRxD->CipherErr == 3)
+			DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: Key not valid "));
+
+        if (((pRxD->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+            RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+		DBGPRINT_RAW(RT_DEBUG_TRACE,(" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
+			pRxD->CipherErr,
+			pRxD->SDL0,
+			pRxD->Mcast | pRxD->Bcast,
+			pRxD->MyBss,
+			pRxWI->WirelessCliID,
+//			CipherName[pRxD->CipherAlg],
+			pRxWI->KeyIndex));
+
+		//
+		// MIC Error
+		//
+		if (pRxD->CipherErr == 2)
+		{
+			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
+            if (pAd->StaCfg.WpaSupplicantUP)
+                WpaSendMicFailureToWpaSupplicant(pAd,
+                                   (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE);
+            else
+			    RTMPReportMicError(pAd, pWpaKey);
+
+            if (((pRxD->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+                RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+			DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
+		}
+
+		if (pHeader == NULL)
+			return(NDIS_STATUS_SUCCESS);
+		/*if ((pRxD->CipherAlg == CIPHER_AES) &&
+			(pHeader->Sequence == pAd->FragFrame.Sequence))
+		{
+			//
+			// Acceptable since the First FragFrame no CipherErr problem.
+			//
+			return(NDIS_STATUS_SUCCESS);
+		}*/
+
+		return(NDIS_STATUS_FAILURE);
+	}
+
+	return(NDIS_STATUS_SUCCESS);
+}
+
+
+BOOLEAN  RTMPFreeTXDUponTxDmaDone(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			QueIdx)
+{
+	PRTMP_TX_RING pTxRing;
+	PTXD_STRUC	  pTxD;
+	PNDIS_PACKET  pPacket;
+	UCHAR	FREE = 0;
+	TXD_STRUC	TxD, *pOriTxD;
+	//ULONG		IrqFlags;
+	BOOLEAN			bReschedule = FALSE;
+
+
+	ASSERT(QueIdx < NUM_OF_TX_RING);
+	pTxRing = &pAd->TxRing[QueIdx];
+
+	RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
+	while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
+	{
+//		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+
+		// static rate also need NICUpdateFifoStaCounters() function.
+		//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
+			NICUpdateFifoStaCounters(pAd);
+
+		/* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
+		FREE++;
+                pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
+		pOriTxD = pTxD;
+                NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
+		pTxD = &TxD;
+
+		pTxD->DMADONE = 0;
+
+
+		{
+			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
+			if (pPacket)
+			{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+			//Always assign pNdisPacket as NULL after clear
+			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
+
+			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
+
+			ASSERT(pPacket == NULL);
+			if (pPacket)
+			{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+			//Always assign pNextNdisPacket as NULL after clear
+			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
+		}
+
+		pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
+		pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
+		INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
+		/* get tx_tdx_idx again */
+		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
+        NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
+
+//         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+	}
+
+
+	return  bReschedule;
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process TX Rings DMA Done interrupt, running in DPC level
+
+	Arguments:
+		Adapter		Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+BOOLEAN	RTMPHandleTxRingDmaDoneInterrupt(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	INT_SOURCE_CSR_STRUC TxRingBitmap)
+{
+//	UCHAR			Count = 0;
+    unsigned long	IrqFlags;
+	BOOLEAN			bReschedule = FALSE;
+
+	// Make sure Tx ring resource won't be used by other threads
+	//NdisAcquireSpinLock(&pAd->TxRingLock);
+
+	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+
+	if (TxRingBitmap.field.Ac0DmaDone)
+		bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
+
+	if (TxRingBitmap.field.HccaDmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
+
+	if (TxRingBitmap.field.Ac3DmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
+
+	if (TxRingBitmap.field.Ac2DmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
+
+	if (TxRingBitmap.field.Ac1DmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
+
+	// Make sure to release Tx ring resource
+	//NdisReleaseSpinLock(&pAd->TxRingLock);
+	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+	// Dequeue outgoing frames from TxSwQueue[] and process it
+	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+
+	return  bReschedule;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process MGMT ring DMA done interrupt, running in DPC level
+
+	Arguments:
+		pAd	Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPHandleMgmtRingDmaDoneInterrupt(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PTXD_STRUC	 pTxD;
+	PNDIS_PACKET pPacket;
+//	int		 i;
+	UCHAR	FREE = 0;
+	PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
+
+	NdisAcquireSpinLock(&pAd->MgmtRingLock);
+
+	RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
+	while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
+	{
+		FREE++;
+		pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
+		pTxD->DMADONE = 0;
+		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
+
+
+		if (pPacket)
+		{
+			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+		}
+		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
+
+		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
+		if (pPacket)
+		{
+			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+		}
+		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
+		INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
+
+	}
+	NdisReleaseSpinLock(&pAd->MgmtRingLock);
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+	Arguments:
+		Adapter		Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+VOID	RTMPHandleTBTTInterrupt(
+	IN PRTMP_ADAPTER pAd)
+{
+	{
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+		{
+		}
+	}
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+	Arguments:
+		pAd		Pointer to our adapter. Rewrite beacon content before next send-out.
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+VOID	RTMPHandlePreTBTTInterrupt(
+	IN PRTMP_ADAPTER pAd)
+{
+	{
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
+		}
+	}
+
+
+}
+
+VOID	RTMPHandleRxCoherentInterrupt(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	WPDMA_GLO_CFG_STRUC	GloCfg;
+
+	if (pAd == NULL)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
+		return;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
+
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
+
+	GloCfg.field.EnTXWriteBackDDONE = 0;
+	GloCfg.field.EnableRxDMA = 0;
+	GloCfg.field.EnableTxDMA = 0;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+	RTMPRingCleanUp(pAd, QID_AC_BE);
+	RTMPRingCleanUp(pAd, QID_AC_BK);
+	RTMPRingCleanUp(pAd, QID_AC_VI);
+	RTMPRingCleanUp(pAd, QID_AC_VO);
+	RTMPRingCleanUp(pAd, QID_HCCA);
+	RTMPRingCleanUp(pAd, QID_MGMT);
+	RTMPRingCleanUp(pAd, QID_RX);
+
+	RTMPEnableRxTx(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
+}
+
+PNDIS_PACKET GetPacketFromRxRing(
+	IN		PRTMP_ADAPTER	pAd,
+	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
+	OUT		BOOLEAN			*pbReschedule,
+	IN OUT	UINT32			*pRxPending)
+{
+	PRXD_STRUC				pRxD;
+	PNDIS_PACKET			pRxPacket = NULL;
+	PNDIS_PACKET			pNewPacket;
+	PVOID					AllocVa;
+	NDIS_PHYSICAL_ADDRESS	AllocPa;
+	BOOLEAN					bReschedule = FALSE;
+	RTMP_DMACB				*pRxCell;
+
+	RTMP_SEM_LOCK(&pAd->RxRingLock);
+
+	if (*pRxPending == 0)
+	{
+		// Get how may packets had been received
+		RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
+
+		if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
+		{
+			// no more rx packets
+			bReschedule = FALSE;
+			goto done;
+		}
+
+		// get rx pending count
+		if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
+			*pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
+		else
+			*pRxPending	= pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
+
+	}
+
+	pRxCell = &pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx];
+
+	// Point to Rx indexed rx ring descriptor
+	pRxD = (PRXD_STRUC) pRxCell->AllocVa;
+
+	if (pRxD->DDONE == 0)
+	{
+		*pRxPending = 0;
+		// DMAIndx had done but DDONE bit not ready
+		bReschedule = TRUE;
+		goto done;
+	}
+
+
+	// return rx descriptor
+	NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
+
+	pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
+
+	if (pNewPacket)
+	{
+		// unmap the rx buffer
+		PCI_UNMAP_SINGLE(pAd, pRxCell->DmaBuf.AllocPa,
+					 pRxCell->DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
+		pRxPacket = pRxCell->pNdisPacket;
+
+		pRxCell->DmaBuf.AllocSize	= RX_BUFFER_AGGRESIZE;
+		pRxCell->pNdisPacket		= (PNDIS_PACKET) pNewPacket;
+		pRxCell->DmaBuf.AllocVa	= AllocVa;
+		pRxCell->DmaBuf.AllocPa	= AllocPa;
+		/* update SDP0 to new buffer of rx packet */
+		pRxD->SDP0 = AllocPa;
+	}
+	else
+	{
+		//DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n"));
+		pRxPacket = NULL;
+		bReschedule = TRUE;
+	}
+
+	pRxD->DDONE = 0;
+
+	// had handled one rx packet
+	*pRxPending = *pRxPending - 1;
+
+	// update rx descriptor and kick rx
+	INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
+
+	pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
+	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+
+done:
+	RTMP_SEM_UNLOCK(&pAd->RxRingLock);
+	*pbReschedule = bReschedule;
+	return pRxPacket;
+}
+
+
+NDIS_STATUS MlmeHardTransmitTxRing(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	QueIdx,
+	IN	PNDIS_PACKET	pPacket)
+{
+	PACKET_INFO	PacketInfo;
+	PUCHAR			pSrcBufVA;
+	UINT			SrcBufLen;
+	PTXD_STRUC		pTxD;
+	PHEADER_802_11	pHeader_802_11;
+	BOOLEAN			bAckRequired, bInsertTimestamp;
+	ULONG			SrcBufPA;
+	//UCHAR			TxBufIdx;
+	UCHAR			MlmeRate;
+	ULONG			SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
+	PTXWI_STRUC	pFirstTxWI;
+	//ULONG	i;
+	//HTTRANSMIT_SETTING	MlmeTransmit;   //Rate for this MGMT frame.
+	ULONG	 FreeNum;
+	MAC_TABLE_ENTRY	*pMacEntry = NULL;
+
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+
+	if (pSrcBufVA == NULL)
+	{
+		// The buffer shouldn't be NULL
+		return NDIS_STATUS_FAILURE;
+	}
+
+	// Make sure MGMT ring resource won't be used by other threads
+	//NdisAcquireSpinLock(&pAd->TxRingLock);
+
+	FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+
+	if (FreeNum == 0)
+	{
+		//NdisReleaseSpinLock(&pAd->TxRingLock);
+		return NDIS_STATUS_FAILURE;
+	}
+
+	SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
+
+	pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
+
+	if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
+	{
+		DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
+		//NdisReleaseSpinLock(&pAd->TxRingLock);
+		return NDIS_STATUS_FAILURE;
+	}
+
+	{
+		// outgoing frame always wakeup PHY to prevent frame lost
+		// if (pAd->StaCfg.Psm == PWR_SAVE)
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+			AsicForceWakeup(pAd, TRUE);
+	}
+	pFirstTxWI	=(PTXWI_STRUC)pSrcBufVA;
+
+	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
+	if (pHeader_802_11->Addr1[0] & 0x01)
+	{
+		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+	}
+	else
+	{
+		MlmeRate = pAd->CommonCfg.MlmeRate;
+	}
+
+	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+		(pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
+	{
+		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
+	}
+
+	// Verify Mlme rate for a / g bands.
+	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
+		MlmeRate = RATE_6;
+
+	//
+	// Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
+	// Snice it's been set to 0 while on MgtMacHeaderInit
+	// By the way this will cause frame to be send on PWR_SAVE failed.
+	//
+	//
+	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
+    // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
+	if (pHeader_802_11->FC.Type != BTYPE_DATA)
+    {
+	if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
+	{
+		pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
+	}
+	else
+	{
+		pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
+	}
+    }
+
+	bInsertTimestamp = FALSE;
+	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
+	{
+		bAckRequired = FALSE;
+	}
+	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
+	{
+		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
+		{
+			bAckRequired = FALSE;
+			pHeader_802_11->Duration = 0;
+		}
+		else
+		{
+			bAckRequired = TRUE;
+			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
+			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
+			{
+				bInsertTimestamp = TRUE;
+			}
+		}
+	}
+	pHeader_802_11->Sequence = pAd->Sequence++;
+	if (pAd->Sequence > 0xfff)
+		pAd->Sequence = 0;
+	// Before radar detection done, mgmt frame can not be sent but probe req
+	// Because we need to use probe req to trigger driver to send probe req in passive scan
+	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
+		&& (pAd->CommonCfg.bIEEE80211H == 1)
+		&& (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
+		//NdisReleaseSpinLock(&pAd->TxRingLock);
+		return (NDIS_STATUS_FAILURE);
+	}
+
+	//
+	// fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
+	// should always has only one ohysical buffer, and the whole frame size equals
+	// to the first scatter buffer size
+	//
+
+	// Initialize TX Descriptor
+	// For inter-frame gap, the number is for this frame and next frame
+	// For MLME rate, we will fix as 2Mb to match other vendor's implement
+//	pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
+
+// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
+	// Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
+	if (pMacEntry == NULL)
+	{
+	RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
+		0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+	}
+	else
+	{
+		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
+					bInsertTimestamp, FALSE, bAckRequired, FALSE,
+					0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
+					pMacEntry->MaxHTPhyMode.field.MCS, 0,
+					(UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
+					IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
+	}
+
+	pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
+	pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
+//	pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE;
+	SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
+
+
+	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
+	pTxD->LastSec0 = 1;
+	pTxD->LastSec1 = 1;
+	pTxD->SDLen0 = SrcBufLen;
+	pTxD->SDLen1 = 0;
+	pTxD->SDPtr0 = SrcBufPA;
+	pTxD->DMADONE = 0;
+
+
+	pAd->RalinkCounters.KickTxCount++;
+	pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	// Increase TX_CTX_IDX, but write to register later.
+	INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
+
+	RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10,  pAd->TxRing[QueIdx].TxCpuIdx);
+
+	// Make sure to release MGMT ring resource
+//	NdisReleaseSpinLock(&pAd->TxRingLock);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+NDIS_STATUS MlmeDataHardTransmit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	QueIdx,
+	IN	PNDIS_PACKET	pPacket)
+{
+	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+		)
+	{
+		return NDIS_STATUS_FAILURE;
+	}
+
+	return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Calculates the duration which is required to transmit out frames
+	with given size and specified rate.
+
+	Arguments:
+		pTxD		Pointer to transmit descriptor
+		Ack		Setting for Ack requirement bit
+		Fragment	Setting for Fragment bit
+		RetryMode	Setting for retry mode
+		Ifs		Setting for IFS gap
+		Rate		Setting for transmit rate
+		Service		Setting for service
+		Length		Frame length
+		TxPreamble	Short or Long preamble when using CCK rates
+		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+VOID RTMPWriteTxDescriptor(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXD_STRUC		pTxD,
+	IN	BOOLEAN			bWIV,
+	IN	UCHAR			QueueSEL)
+{
+	//
+	// Always use Long preamble before verifiation short preamble functionality works well.
+	// Todo: remove the following line if short preamble functionality works
+	//
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+
+	pTxD->WIV	= (bWIV) ? 1: 0;
+	pTxD->QSEL= (QueueSEL);
+	//RT2860c??  fixed using EDCA queue for test...  We doubt Queue1 has problem.  2006-09-26 Jan
+	//pTxD->QSEL= FIFO_EDCA;
+	if (pAd->bGenOneHCCA == TRUE)
+		pTxD->QSEL= FIFO_HCCA;
+	pTxD->DMADONE = 0;
+}
diff --git a/drivers/staging/rt2860/common/cmm_data_usb.c b/drivers/staging/rt2860/common/cmm_data_usb.c
new file mode 100644
index 0000000..bd6f9d8
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_data_usb.c
@@ -0,0 +1,968 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+/*
+   All functions in this file must be USB-depended, or you should out your function
+	in other files.
+
+*/
+
+#ifdef RTMP_MAC_USB
+
+
+#include	"../rt_config.h"
+
+
+/*
+	We can do copy the frame into pTxContext when match following conditions.
+		=>
+		=>
+		=>
+*/
+static inline NDIS_STATUS RtmpUSBCanDoWrite(
+	IN RTMP_ADAPTER		*pAd,
+	IN UCHAR			QueIdx,
+	IN HT_TX_CONTEXT	*pHTTXContext)
+{
+	NDIS_STATUS	canWrite = NDIS_STATUS_RESOURCES;
+
+	if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
+		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+	}
+	else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
+		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+	}
+	else if (pHTTXContext->bCurWriting == TRUE)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
+	}
+	else
+	{
+		canWrite = NDIS_STATUS_SUCCESS;
+	}
+
+
+	return canWrite;
+}
+
+
+USHORT RtmpUSB_WriteSubTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber)
+{
+
+	// Dummy function. Should be removed in the future.
+	return 0;
+
+}
+
+USHORT	RtmpUSB_WriteFragTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			fragNum,
+	OUT	USHORT			*FreeNumber)
+{
+	HT_TX_CONTEXT	*pHTTXContext;
+	USHORT			hwHdrLen;	// The hwHdrLen consist of 802.11 header length plus the header padding length.
+	UINT32			fillOffset;
+	TXINFO_STRUC	*pTxInfo;
+	TXWI_STRUC		*pTxWI;
+	PUCHAR			pWirelessPacket = NULL;
+	UCHAR			QueIdx;
+	NDIS_STATUS		Status;
+	unsigned long	IrqFlags;
+	UINT32			USBDMApktLen = 0, DMAHdrLen, padding;
+	BOOLEAN			TxQLastRound = FALSE;
+
+	//
+	// get Tx Ring Resource & Dma Buffer address
+	//
+	QueIdx = pTxBlk->QueIdx;
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+	fillOffset = pHTTXContext->CurWritePosition;
+
+	if(fragNum == 0)
+	{
+		// Check if we have enough space for this bulk-out batch.
+		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+		if (Status == NDIS_STATUS_SUCCESS)
+		{
+			pHTTXContext->bCurWriting = TRUE;
+
+			// Reserve space for 8 bytes padding.
+			if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+			{
+				pHTTXContext->ENextBulkOutPosition += 8;
+				pHTTXContext->CurWritePosition += 8;
+				fillOffset += 8;
+			}
+			pTxBlk->Priv = 0;
+			pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+			return(Status);
+		}
+	}
+	else
+	{
+		// For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
+		Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+		if (Status == NDIS_STATUS_SUCCESS)
+		{
+			fillOffset += pTxBlk->Priv;
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+			return(Status);
+		}
+	}
+
+	NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
+	pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+	pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+	pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+	// copy TXWI + WLAN Header + LLC into DMA Header Buffer
+	//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+	hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+	// Build our URB for USBD
+	DMAHdrLen = TXWI_SIZE + hwHdrLen;
+	USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+	padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment
+	USBDMApktLen += padding;
+
+	pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
+
+	// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
+	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
+
+	if (fragNum == pTxBlk->TotalFragNum)
+	{
+		pTxInfo->USBDMATxburst = 0;
+		if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)
+		{
+			pTxInfo->SwUseLastRound = 1;
+			TxQLastRound = TRUE;
+		}
+	}
+	else
+	{
+		pTxInfo->USBDMATxburst = 1;
+	}
+
+	NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+	pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+	pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+
+	//	Zero the last padding.
+	pWirelessPacket += pTxBlk->SrcBufLen;
+	NdisZeroMemory(pWirelessPacket, padding + 8);
+
+	if (fragNum == pTxBlk->TotalFragNum)
+	{
+		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		// Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.
+		pHTTXContext->CurWritePosition += pTxBlk->Priv;
+		if (TxQLastRound == TRUE)
+			pHTTXContext->CurWritePosition = 8;
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+
+		// Finally, set bCurWriting as FALSE
+	pHTTXContext->bCurWriting = FALSE;
+
+		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		// succeed and release the skb buffer
+		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+	}
+
+
+	return(Status);
+
+}
+
+
+USHORT RtmpUSB_WriteSingleTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber)
+{
+	HT_TX_CONTEXT	*pHTTXContext;
+	USHORT			hwHdrLen;
+	UINT32			fillOffset;
+	TXINFO_STRUC	*pTxInfo;
+	TXWI_STRUC		*pTxWI;
+	PUCHAR			pWirelessPacket;
+	UCHAR			QueIdx;
+	unsigned long	IrqFlags;
+	NDIS_STATUS		Status;
+	UINT32			USBDMApktLen = 0, DMAHdrLen, padding;
+	BOOLEAN			bTxQLastRound = FALSE;
+
+	// For USB, didn't need PCI_MAP_SINGLE()
+	//SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);
+
+
+	//
+	// get Tx Ring Resource & Dma Buffer address
+	//
+	QueIdx = pTxBlk->QueIdx;
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+	fillOffset = pHTTXContext->CurWritePosition;
+
+
+
+	// Check ring full.
+	Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+	if(Status == NDIS_STATUS_SUCCESS)
+	{
+		pHTTXContext->bCurWriting = TRUE;
+
+		pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+		pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+		// Reserve space for 8 bytes padding.
+		if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+		{
+			pHTTXContext->ENextBulkOutPosition += 8;
+			pHTTXContext->CurWritePosition += 8;
+			fillOffset += 8;
+		}
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+		pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+		// copy TXWI + WLAN Header + LLC into DMA Header Buffer
+		//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+		hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+		// Build our URB for USBD
+		DMAHdrLen = TXWI_SIZE + hwHdrLen;
+		USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+		padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment
+		USBDMApktLen += padding;
+
+		pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
+
+		// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
+		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
+
+		if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
+		{
+			pTxInfo->SwUseLastRound = 1;
+			bTxQLastRound = TRUE;
+		}
+		NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+		pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+		// We unlock it here to prevent the first 8 bytes maybe over-writed issue.
+		//	1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
+		//	2. An interrupt break our routine and handle bulk-out complete.
+		//	3. In the bulk-out compllete, it need to do another bulk-out,
+		//			if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
+		//			but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
+		//	4. Interrupt complete.
+		//  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
+		//	6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
+		//		and the packet will wrong.
+		pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+		pWirelessPacket += pTxBlk->SrcBufLen;
+		NdisZeroMemory(pWirelessPacket, padding + 8);
+
+		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		pHTTXContext->CurWritePosition += pTxBlk->Priv;
+		if (bTxQLastRound)
+			pHTTXContext->CurWritePosition = 8;
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+	pHTTXContext->bCurWriting = FALSE;
+	}
+
+
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+
+	// succeed and release the skb buffer
+	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+	return(Status);
+
+}
+
+
+USHORT RtmpUSB_WriteMultiTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			frameNum,
+	OUT	USHORT			*FreeNumber)
+{
+	HT_TX_CONTEXT	*pHTTXContext;
+	USHORT			hwHdrLen;	// The hwHdrLen consist of 802.11 header length plus the header padding length.
+	UINT32			fillOffset;
+	TXINFO_STRUC	*pTxInfo;
+	TXWI_STRUC		*pTxWI;
+	PUCHAR			pWirelessPacket = NULL;
+	UCHAR			QueIdx;
+	NDIS_STATUS		Status;
+	unsigned long	IrqFlags;
+	//UINT32			USBDMApktLen = 0, DMAHdrLen, padding;
+
+	//
+	// get Tx Ring Resource & Dma Buffer address
+	//
+	QueIdx = pTxBlk->QueIdx;
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	if(frameNum == 0)
+	{
+		// Check if we have enough space for this bulk-out batch.
+		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+		if (Status == NDIS_STATUS_SUCCESS)
+		{
+			pHTTXContext->bCurWriting = TRUE;
+
+			pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+			pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+
+			// Reserve space for 8 bytes padding.
+			if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+			{
+
+				pHTTXContext->CurWritePosition += 8;
+				pHTTXContext->ENextBulkOutPosition += 8;
+			}
+			fillOffset = pHTTXContext->CurWritePosition;
+			pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+			pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+			//
+			// Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+			//
+			if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
+				hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
+			else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
+				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
+				hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
+			else
+				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+				hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+			// Update the pTxBlk->Priv.
+			pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
+
+			//	pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
+			RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
+
+			// Copy it.
+			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
+			pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
+			pWirelessPacket += pTxBlk->Priv;
+		}
+	}
+	else
+	{	// For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
+
+		Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+		if (Status == NDIS_STATUS_SUCCESS)
+		{
+			fillOffset =  (pHTTXContext->CurWritePosition + pTxBlk->Priv);
+			pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+			//hwHdrLen = pTxBlk->MpduHeaderLen;
+			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
+			pWirelessPacket += (pTxBlk->MpduHeaderLen);
+			pTxBlk->Priv += pTxBlk->MpduHeaderLen;
+		}
+		else
+		{	// It should not happened now unless we are going to shutdown.
+			DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
+			Status = NDIS_STATUS_FAILURE;
+		}
+	}
+
+
+	// We unlock it here to prevent the first 8 bytes maybe over-write issue.
+	//	1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
+	//	2. An interrupt break our routine and handle bulk-out complete.
+	//	3. In the bulk-out compllete, it need to do another bulk-out,
+	//			if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
+	//			but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
+	//	4. Interrupt complete.
+	//  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
+	//	6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
+	//		and the packet will wrong.
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	if (Status != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
+		goto done;
+	}
+
+	// Copy the frame content into DMA buffer and update the pTxBlk->Priv
+	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+	pWirelessPacket += pTxBlk->SrcBufLen;
+	pTxBlk->Priv += pTxBlk->SrcBufLen;
+
+done:
+	// Release the skb buffer here
+	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+	return(Status);
+
+}
+
+
+VOID RtmpUSB_FinalWriteTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	USHORT			totalMPDUSize,
+	IN	USHORT			TxIdx)
+{
+	UCHAR			QueIdx;
+	HT_TX_CONTEXT	*pHTTXContext;
+	UINT32			fillOffset;
+	TXINFO_STRUC	*pTxInfo;
+	TXWI_STRUC		*pTxWI;
+	UINT32			USBDMApktLen, padding;
+	unsigned long	IrqFlags;
+	PUCHAR			pWirelessPacket;
+
+	QueIdx = pTxBlk->QueIdx;
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	if (pHTTXContext->bCurWriting == TRUE)
+	{
+		fillOffset = pHTTXContext->CurWritePosition;
+		if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
+			&& (pHTTXContext->bCopySavePad == TRUE))
+			pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
+		else
+			pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
+
+		//
+		// Update TxInfo->USBDMApktLen ,
+		//		the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
+		//
+		pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
+
+		// Calculate the bulk-out padding
+		USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
+		padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment
+		USBDMApktLen += padding;
+
+		pTxInfo->USBDMATxPktLen = USBDMApktLen;
+
+		//
+		// Update TXWI->MPDUtotalByteCount ,
+		//		the length = 802.11 header + payload_of_all_batch_frames
+		pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
+		pTxWI->MPDUtotalByteCount = totalMPDUSize;
+
+		//
+		// Update the pHTTXContext->CurWritePosition
+		//
+		pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
+		if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
+		{	// Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
+			pHTTXContext->CurWritePosition = 8;
+			pTxInfo->SwUseLastRound = 1;
+		}
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+
+		//
+		//	Zero the last padding.
+		//
+		pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
+		NdisZeroMemory(pWirelessPacket, padding + 8);
+
+		// Finally, set bCurWriting as FALSE
+		pHTTXContext->bCurWriting = FALSE;
+
+	}
+	else
+	{	// It should not happened now unless we are going to shutdown.
+		DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
+	}
+
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+}
+
+
+VOID RtmpUSBDataLastTxIdx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			QueIdx,
+	IN	USHORT			TxIdx)
+{
+	// DO nothing for USB.
+}
+
+
+/*
+	When can do bulk-out:
+		1. TxSwFreeIdx < TX_RING_SIZE;
+			It means has at least one Ring entity is ready for bulk-out, kick it out.
+		2. If TxSwFreeIdx == TX_RING_SIZE
+			Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
+
+*/
+VOID RtmpUSBDataKickOut(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			QueIdx)
+{
+	RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+	RTUSBKickBulkOut(pAd);
+
+}
+
+
+/*
+	Must be run in Interrupt context
+	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
+ */
+int RtmpUSBMgmtKickOut(
+	IN RTMP_ADAPTER		*pAd,
+	IN UCHAR			QueIdx,
+	IN PNDIS_PACKET		pPacket,
+	IN PUCHAR			pSrcBufVA,
+	IN UINT				SrcBufLen)
+{
+	PTXINFO_STRUC	pTxInfo;
+	ULONG			BulkOutSize;
+	UCHAR			padLen;
+	PUCHAR			pDest;
+	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
+	PTX_CONTEXT		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
+	unsigned long	IrqFlags;
+
+
+	pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
+
+	// Build our URB for USBD
+	BulkOutSize = SrcBufLen;
+	BulkOutSize = (BulkOutSize + 3) & (~3);
+	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
+
+	BulkOutSize += 4; // Always add 4 extra bytes at every packet.
+
+	// If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
+	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
+		BulkOutSize += 4;
+
+	padLen = BulkOutSize - SrcBufLen;
+	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
+
+	// Now memzero all extra padding bytes.
+	pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
+	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
+	NdisZeroMemory(pDest, padLen);
+
+	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
+	pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
+
+	// Length in TxInfo should be 8 less than bulkout size.
+	pMLMEContext->BulkOutSize = BulkOutSize;
+	pMLMEContext->InUse = TRUE;
+	pMLMEContext->bWaitingBulkOut = TRUE;
+
+
+	//for debug
+	//hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
+
+	//pAd->RalinkCounters.KickTxCount++;
+	//pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	//if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
+	//	needKickOut = TRUE;
+
+	// Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
+	pAd->MgmtRing.TxSwFreeIdx--;
+	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
+
+	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+	//if (needKickOut)
+	RTUSBKickBulkOut(pAd);
+
+	return 0;
+}
+
+
+VOID RtmpUSBNullFrameKickOut(
+	IN RTMP_ADAPTER *pAd,
+	IN UCHAR		QueIdx,
+	IN UCHAR		*pNullFrame,
+	IN UINT32		frameLen)
+{
+	if (pAd->NullContext.InUse == FALSE)
+	{
+		PTX_CONTEXT		pNullContext;
+		PTXINFO_STRUC	pTxInfo;
+		PTXWI_STRUC		pTxWI;
+		PUCHAR			pWirelessPkt;
+
+		pNullContext = &(pAd->NullContext);
+
+		// Set the in use bit
+		pNullContext->InUse = TRUE;
+		pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
+
+		RTMPZeroMemory(&pWirelessPkt[0], 100);
+		pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
+		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
+		pTxInfo->QSEL = FIFO_EDCA;
+		pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
+		RTMPWriteTxWI(pAd, pTxWI,  FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
+			0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
+
+		RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+		pAd->NullContext.BulkOutSize =  TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
+
+		// Fill out frame length information for global Bulk out arbitor
+		//pNullContext->BulkOutSize = TransferBufferLength;
+		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
+		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
+
+		// Kick bulk out
+		RTUSBKickBulkOut(pAd);
+	}
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Get a received packet.
+
+Arguments:
+	pAd					device control block
+	pSaveRxD			receive descriptor information
+	*pbReschedule		need reschedule flag
+	*pRxPending			pending received packet flag
+
+Return Value:
+    the recieved packet
+
+Note:
+========================================================================
+*/
+PNDIS_PACKET GetPacketFromRxRing(
+	IN		PRTMP_ADAPTER		pAd,
+	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
+	OUT		BOOLEAN				*pbReschedule,
+	IN OUT	UINT32				*pRxPending)
+{
+	PRX_CONTEXT		pRxContext;
+	PNDIS_PACKET	pSkb;
+	PUCHAR			pData;
+	ULONG			ThisFrameLen;
+	ULONG			RxBufferLength;
+	PRXWI_STRUC		pRxWI;
+
+	pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
+	if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
+		return NULL;
+
+	RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
+	if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
+	{
+		goto label_null;
+	}
+
+	pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
+	// The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
+	ThisFrameLen = *pData + (*(pData+1)<<8);
+    if (ThisFrameLen == 0)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
+								pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
+		goto label_null;
+	}
+	if ((ThisFrameLen&0x3) != 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
+								pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
+		goto label_null;
+	}
+
+	if ((ThisFrameLen + 8)> RxBufferLength)	// 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
+						pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
+
+		// error frame. finish this loop
+		goto label_null;
+	}
+
+	// skip USB frame length field
+	pData += RT2870_RXDMALEN_FIELD_SIZE;
+	pRxWI = (PRXWI_STRUC)pData;
+	if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
+									__FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
+		goto label_null;
+	}
+
+	// allocate a rx packet
+	pSkb = dev_alloc_skb(ThisFrameLen);
+	if (pSkb == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__));
+		goto label_null;
+	}
+
+	// copy the rx packet
+	memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
+	RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
+	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
+
+	// copy RxD
+	*pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
+
+	// update next packet read position.
+	pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE);	// 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
+
+	return pSkb;
+
+label_null:
+
+	return NULL;
+}
+
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
+
+	Arguments:
+		pRxD		Pointer	to the Rx descriptor
+
+	Return Value:
+		NDIS_STATUS_SUCCESS		No err
+		NDIS_STATUS_FAILURE		Error
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS	RTMPCheckRxError(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PHEADER_802_11	pHeader,
+	IN	PRXWI_STRUC	pRxWI,
+	IN	PRT28XX_RXD_STRUC	pRxINFO)
+{
+	PCIPHER_KEY pWpaKey;
+	INT	dBm;
+
+	if (pAd->bPromiscuous == TRUE)
+		return(NDIS_STATUS_SUCCESS);
+	if(pRxINFO == NULL)
+		return(NDIS_STATUS_FAILURE);
+
+	// Phy errors & CRC errors
+	if (pRxINFO->Crc)
+	{
+		// Check RSSI for Noise Hist statistic collection.
+		dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
+		if (dBm <= -87)
+			pAd->StaCfg.RPIDensity[0] += 1;
+		else if (dBm <= -82)
+			pAd->StaCfg.RPIDensity[1] += 1;
+		else if (dBm <= -77)
+			pAd->StaCfg.RPIDensity[2] += 1;
+		else if (dBm <= -72)
+			pAd->StaCfg.RPIDensity[3] += 1;
+		else if (dBm <= -67)
+			pAd->StaCfg.RPIDensity[4] += 1;
+		else if (dBm <= -62)
+			pAd->StaCfg.RPIDensity[5] += 1;
+		else if (dBm <= -57)
+			pAd->StaCfg.RPIDensity[6] += 1;
+		else if (dBm > -57)
+			pAd->StaCfg.RPIDensity[7] += 1;
+
+		return(NDIS_STATUS_FAILURE);
+	}
+
+	// Add Rx size to channel load counter, we should ignore error counts
+	pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
+
+	// Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
+	if (pHeader->FC.ToDs)
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	// Paul 04-03 for OFDM Rx length issue
+	if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	// Drop not U2M frames, cant's drop here because we will drop beacon in this case
+	// I am kind of doubting the U2M bit operation
+	// if (pRxD->U2M == 0)
+	//	return(NDIS_STATUS_FAILURE);
+
+	// drop decyption fail frame
+	if (pRxINFO->Decrypted && pRxINFO->CipherErr)
+	{
+
+		if (((pRxINFO->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+            RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+		if (((pRxINFO->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+                RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+		//
+		// MIC Error
+		//
+		if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
+		{
+			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
+			RTMPReportMicError(pAd, pWpaKey);
+			DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
+		}
+
+		if (pRxINFO->Decrypted &&
+			(pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
+			(pHeader->Sequence == pAd->FragFrame.Sequence))
+		{
+			//
+			// Acceptable since the First FragFrame no CipherErr problem.
+			//
+			return(NDIS_STATUS_SUCCESS);
+		}
+
+		return(NDIS_STATUS_FAILURE);
+	}
+
+	return(NDIS_STATUS_SUCCESS);
+}
+
+VOID RtmpUsbStaAsicForceWakeupTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+
+	if (pAd && pAd->Mlme.AutoWakeupTimerRunning)
+	{
+		AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+		pAd->Mlme.AutoWakeupTimerRunning = FALSE;
+	}
+}
+
+VOID RT28xxUsbStaAsicForceWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN       bFromTx)
+{
+	BOOLEAN	Canceled;
+
+	if (pAd->Mlme.AutoWakeupTimerRunning)
+		RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled);
+
+	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+}
+
+VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TbttNumToNextWakeUp)
+{
+
+
+	// we have decided to SLEEP, so at least do it for a BEACON period.
+	if (TbttNumToNextWakeUp == 0)
+		TbttNumToNextWakeUp = 1;
+
+	RTMPSetTimer(&pAd->Mlme.AutoWakeupTimer, AUTO_WAKEUP_TIMEOUT);
+	pAd->Mlme.AutoWakeupTimerRunning = TRUE;
+
+	AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);   // send POWER-SAVE command to MCU. Timeout 40us.
+
+	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+
+}
+
+#endif // RTMP_MAC_USB //
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
index 019cc44..49e9bdf 100644
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -23,154 +23,154 @@ 
  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  *                                                                       *
  *************************************************************************
-*/
+ */
 
 #include <linux/sched.h>
 #include "../rt_config.h"
 
 INT	Show_SSID_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_WirelessMode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_TxBurst_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_TxPreamble_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_TxPower_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_Channel_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_BGProtection_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_RTSThreshold_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_FragThreshold_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtBw_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtMcs_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtGi_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtOpMode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtExtcha_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtMpduDensity_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtBaWinSize_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtRdg_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtAmsdu_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_HtAutoBa_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_CountryRegion_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_CountryRegionABand_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_CountryCode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 #ifdef AGGREGATION_SUPPORT
 INT	Show_PktAggregate_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 #endif // AGGREGATION_SUPPORT //
 
 #ifdef WMM_SUPPORT
 INT	Show_WmmCapable_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 #endif // WMM_SUPPORT //
 
 INT	Show_IEEE80211H_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_NetworkType_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_AuthMode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_EncrypType_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_DefaultKeyID_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_Key1_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_Key2_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_Key3_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_Key4_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 INT	Show_WPAPSK_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf);
+	OUT	PSTRING			pBuf);
 
 static struct {
-	CHAR *name;
-	INT (*show_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
+	PSTRING name;
+	INT (*show_proc)(PRTMP_ADAPTER pAdapter, PSTRING arg);
 } *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = {
 	{"SSID",					Show_SSID_Proc},
 	{"WirelessMode",			Show_WirelessMode_Proc},
@@ -224,8 +224,9 @@  static struct {
 */
 INT Set_DriverVersion_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
+
 	DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION));
 
     return TRUE;
@@ -242,32 +243,14 @@  INT Set_DriverVersion_Proc(
 */
 INT Set_CountryRegion_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
-	ULONG region;
+	int retval;
 
-	region = simple_strtol(arg, 0, 10);
 
-	// Country can be set only when EEPROM not programmed
-	if (pAd->CommonCfg.CountryRegion & 0x80)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameter of CountryRegion in eeprom is programmed \n"));
+	retval = RT_CfgSetCountryRegion(pAd, arg, BAND_24G);
+	if (retval == FALSE)
 		return FALSE;
-	}
-
-	if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
-	{
-		pAd->CommonCfg.CountryRegion = (UCHAR) region;
-	}
-	else if (region == REGION_31_BG_BAND)
-	{
-		pAd->CommonCfg.CountryRegion = (UCHAR) region;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameters out of range\n"));
-		return FALSE;
-	}
 
 	// if set country region, driver needs to be reset
 	BuildChannelList(pAd);
@@ -288,28 +271,14 @@  INT Set_CountryRegion_Proc(
 */
 INT Set_CountryRegionABand_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
-	ULONG region;
-
-	region = simple_strtol(arg, 0, 10);
+	int retval;
 
-	// Country can be set only when EEPROM not programmed
-	if (pAd->CommonCfg.CountryRegionForABand & 0x80)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameter of CountryRegion in eeprom is programmed \n"));
-		return FALSE;
-	}
 
-	if((region >= 0) && (region <= REGION_MAXIMUM_A_BAND))
-	{
-		pAd->CommonCfg.CountryRegionForABand = (UCHAR) region;
-	}
-	else
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameters out of range\n"));
+	retval = RT_CfgSetCountryRegion(pAd, arg, BAND_5G);
+	if (retval == FALSE)
 		return FALSE;
-	}
 
 	// if set country region, driver needs to be reset
 	BuildChannelList(pAd);
@@ -329,22 +298,17 @@  INT Set_CountryRegionABand_Proc(
 */
 INT	Set_WirelessMode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
-	ULONG	WirelessMode;
 	INT		success = TRUE;
 
-	WirelessMode = simple_strtol(arg, 0, 10);
-
+	success = RT_CfgSetWirelessMode(pAd, arg);
+	if (success)
 	{
-		INT MaxPhyMode = PHY_11G;
-
-		MaxPhyMode = PHY_11N_5G;
-
-		if (WirelessMode <= MaxPhyMode)
 		{
-			RTMPSetPhyMode(pAd, WirelessMode);
+			LONG	WirelessMode = pAd->CommonCfg.PhyMode;
 
+			RTMPSetPhyMode(pAd, WirelessMode);
 			if (WirelessMode >= PHY_11ABGN_MIXED)
 			{
 				pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
@@ -364,17 +328,10 @@  INT	Set_WirelessMode_Proc(
 				AsicEnableIbssSync(pAd);       // copy to on-chip memory
 			}
 		}
-		else
-		{
-			success = FALSE;
-		}
-	}
 
 	// it is needed to set SSID to take effect
-	if (success == TRUE)
-	{
 		SetCommonHT(pAd);
-		DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%ld)\n", WirelessMode));
+		DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%d)\n", pAd->CommonCfg.PhyMode));
 	}
 	else
 	{
@@ -394,7 +351,7 @@  INT	Set_WirelessMode_Proc(
 */
 INT	Set_Channel_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
  	INT		success = TRUE;
 	UCHAR	Channel;
@@ -451,24 +408,18 @@  INT	Set_Channel_Proc(
 */
 INT	Set_ShortSlot_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
-	ULONG ShortSlot;
-
-	ShortSlot = simple_strtol(arg, 0, 10);
-
-	if (ShortSlot == 1)
-		pAd->CommonCfg.bUseShortSlotTime = TRUE;
-	else if (ShortSlot == 0)
-		pAd->CommonCfg.bUseShortSlotTime = FALSE;
-	else
-		return FALSE;  //Invalid argument
+	int retval;
 
+	retval = RT_CfgSetShortSlot(pAd, arg);
+	if (retval == TRUE)
 	DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
 
-	return TRUE;
+	return retval;
 }
 
+
 /*
     ==========================================================================
     Description:
@@ -479,12 +430,12 @@  INT	Set_ShortSlot_Proc(
 */
 INT	Set_TxPower_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
-	ULONG TxPower;
+	LONG TxPower;
 	INT   success = FALSE;
 
-	TxPower = (ULONG) simple_strtol(arg, 0, 10);
+	TxPower = simple_strtol(arg, 0, 10);
 	if (TxPower <= 100)
 	{
 		{
@@ -511,7 +462,7 @@  INT	Set_TxPower_Proc(
 */
 INT	Set_BGProtection_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	switch (simple_strtol(arg, 0, 10))
 	{
@@ -544,7 +495,7 @@  INT	Set_BGProtection_Proc(
 */
 INT	Set_TxPreamble_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	RT_802_11_PREAMBLE	Preamble;
 
@@ -585,7 +536,7 @@  INT	Set_TxPreamble_Proc(
 */
 INT	Set_RTSThreshold_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	 NDIS_802_11_RTS_THRESHOLD           RtsThresh;
 
@@ -613,7 +564,7 @@  INT	Set_RTSThreshold_Proc(
 */
 INT	Set_FragThreshold_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	 NDIS_802_11_FRAGMENTATION_THRESHOLD     FragThresh;
 
@@ -657,9 +608,9 @@  INT	Set_FragThreshold_Proc(
 */
 INT	Set_TxBurst_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
-	ULONG TxBurst;
+	LONG TxBurst;
 
 	TxBurst = simple_strtol(arg, 0, 10);
 	if (TxBurst == 1)
@@ -685,9 +636,9 @@  INT	Set_TxBurst_Proc(
 */
 INT	Set_PktAggregate_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
-	ULONG aggre;
+	LONG aggre;
 
 	aggre = simple_strtol(arg, 0, 10);
 
@@ -716,9 +667,9 @@  INT	Set_PktAggregate_Proc(
 */
 INT	Set_IEEE80211H_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
-    ULONG ieee80211h;
+    LONG ieee80211h;
 
 	ieee80211h = simple_strtol(arg, 0, 10);
 
@@ -746,7 +697,7 @@  INT	Set_IEEE80211H_Proc(
 */
 INT	Set_Debug_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n"));
 
@@ -761,10 +712,11 @@  INT	Set_Debug_Proc(
 
 INT	Show_DescInfo_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 	INT i, QueIdx=0;
+//  ULONG	RegValue;
 	PRT28XX_RXD_STRUC pRxD;
     PTXD_STRUC pTxD;
 	PRTMP_TX_RING	pTxRing = &pAd->TxRing[QueIdx];
@@ -774,27 +726,28 @@  INT	Show_DescInfo_Proc(
 	for(i=0;i<TX_RING_SIZE;i++)
 	{
 	    pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
-	    printk("Desc #%d\n",i);
-	    hex_dump("Tx Descriptor", (char *)pTxD, 16);
-	    printk("pTxD->DMADONE = %x\n", pTxD->DMADONE);
+	    DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
+	    hex_dump("Tx Descriptor", (PUCHAR)pTxD, 16);
+	    DBGPRINT(RT_DEBUG_OFF, ("pTxD->DMADONE = %x\n", pTxD->DMADONE));
 	}
-	printk("---------------------------------------------------\n");
+	DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n"));
 	for(i=0;i<MGMT_RING_SIZE;i++)
 	{
 	    pTxD = (PTXD_STRUC) pMgmtRing->Cell[i].AllocVa;
-	    printk("Desc #%d\n",i);
-	    hex_dump("Mgmt Descriptor", (char *)pTxD, 16);
-	    printk("pMgmt->DMADONE = %x\n", pTxD->DMADONE);
+	    DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
+	    hex_dump("Mgmt Descriptor", (PUCHAR)pTxD, 16);
+	    DBGPRINT(RT_DEBUG_OFF, ("pMgmt->DMADONE = %x\n", pTxD->DMADONE));
 	}
-	printk("---------------------------------------------------\n");
+	DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n"));
 	for(i=0;i<RX_RING_SIZE;i++)
 	{
 	    pRxD = (PRT28XX_RXD_STRUC) pRxRing->Cell[i].AllocVa;
-	    printk("Desc #%d\n",i);
-	    hex_dump("Rx Descriptor", (char *)pRxD, 16);
-		printk("pRxD->DDONE = %x\n", pRxD->DDONE);
+	    DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
+	    hex_dump("Rx Descriptor", (PUCHAR)pRxD, 16);
+	    DBGPRINT(RT_DEBUG_OFF, ("pRxD->DDONE = %x\n", pRxD->DDONE));
 	}
-#endif /* RT2860 */
+#endif // RTMP_MAC_PCI //
+
 	return TRUE;
 }
 
@@ -813,8 +766,11 @@  INT	Show_DescInfo_Proc(
 */
 INT	Set_ResetStatCounter_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
+	//UCHAR           i;
+	//MAC_TABLE_ENTRY *pEntry;
+
 	DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
 
 	// add the most up-to-date h/w raw counters into software counters
@@ -824,9 +780,33 @@  INT	Set_ResetStatCounter_Proc(
 	NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
 	NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
 
+	// Reset HotSpot counter
+
+
 	return TRUE;
 }
 
+/*
+	========================================================================
+
+	Routine Description:
+		Add WPA key process.
+		In Adhoc WPANONE, bPairwise = 0;  KeyIdx = 0;
+
+	Arguments:
+		pAd					Pointer to our adapter
+		pBuf							Pointer to the where the key stored
+
+	Return Value:
+		NDIS_SUCCESS					Add key successfully
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+
 BOOLEAN RTMPCheckStrPrintAble(
     IN  CHAR *pInPutStr,
     IN  UCHAR strLen)
@@ -1100,7 +1080,7 @@  VOID	RTMPWPARemoveAllKeys(
 	UCHAR 	i;
 
 	DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
-
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 	// For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
 	// Link up. And it will be replaced if user changed it.
 	if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
@@ -1122,9 +1102,33 @@  VOID	RTMPWPARemoveAllKeys(
 
 		AsicRemoveSharedKeyEntry(pAd, BSS0, i);
 	}
-
+	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 }
 
+
+/*
+	========================================================================
+
+	Routine Description:
+		As STA's BSSID is a WC too, it uses shared key table.
+		This function write correct unicast TX key to ASIC WCID.
+		And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
+		Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
+		Caller guarantee WEP calls this function when set Txkey,  default key index=0~3.
+
+	Arguments:
+		pAd					Pointer to our adapter
+		pKey							Pointer to the where the key stored
+
+	Return Value:
+		NDIS_SUCCESS					Add key successfully
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
 /*
 	========================================================================
 	Routine Description:
@@ -1147,6 +1151,11 @@  VOID	RTMPSetPhyMode(
 	INT i;
 	// the selected phymode must be supported by the RF IC encoded in E2PROM
 
+	// if no change, do nothing
+	/* bug fix
+	if (pAd->CommonCfg.PhyMode == phymode)
+		return;
+    */
 	pAd->CommonCfg.PhyMode = (UCHAR)phymode;
 
 	DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
@@ -1466,7 +1475,10 @@  VOID	RTMPSetHT(
 	}
 	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
 
+		{
 	RTMPSetIndividualHT(pAd, 0);
+		}
+
 }
 
 /*
@@ -1657,12 +1669,8 @@  VOID	RTMPAddWcidAttributeEntry(
 			// 1.	In ADHOC mode, the AID is wcid number. And NO mesh link exists.
 			// 2.	In Infra mode, the AID:1 MUST be wcid of infra STA.
 			//					   the AID:2~ assign to mesh link entry.
-			if (pEntry && ADHOC_ON(pAd))
+			if (pEntry)
 				Wcid = pEntry->Aid;
-			else if (pEntry && INFRA_ON(pAd))
-			{
-				Wcid = BSSID_WCID;
-			}
 			else
 				Wcid = MCAST_WCID;
 		}
@@ -1697,12 +1705,12 @@  VOID	RTMPAddWcidAttributeEntry(
 	}
 
 	// For key index and ext IV bit, so only need to update the position(offset+3).
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 	RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
-#endif
-#ifdef RT2870
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
 	RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
 
 	DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
 	DBGPRINT(RT_DEBUG_TRACE,("	WCIDAttri = 0x%x \n",  WCIDAttri));
@@ -1723,7 +1731,7 @@  Arguments:
     Note:
     ==========================================================================
 */
-CHAR *GetEncryptType(CHAR enc)
+PSTRING GetEncryptType(CHAR enc)
 {
     if(enc == Ndis802_11WEPDisabled)
         return "NONE";
@@ -1739,7 +1747,7 @@  CHAR *GetEncryptType(CHAR enc)
     	return "UNKNOW";
 }
 
-CHAR *GetAuthMode(CHAR auth)
+PSTRING GetAuthMode(CHAR auth)
 {
     if(auth == Ndis802_11AuthModeOpen)
     	return "OPEN";
@@ -1783,71 +1791,133 @@  CHAR *GetAuthMode(CHAR auth)
         		3.) UI needs to prepare at least 4096bytes to get the results
     ==========================================================================
 */
-#define	LINE_LEN	(4+33+20+8+10+9+7+3)	// Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType
-VOID RTMPIoctlGetSiteSurvey(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq)
+#define	LINE_LEN	(4+33+20+23+9+7+7+3)	// Channel+SSID+Bssid+Security+Signal+WiressMode+ExtCh+NetworkType
+VOID	RTMPCommSiteSurveyData(
+	IN  PSTRING		msg,
+	IN  PBSS_ENTRY	pBss)
 {
-	CHAR		*msg;
-	INT 		i=0;
-	INT			WaitCnt;
-	INT 		Status=0;
-	CHAR		Ssid[MAX_LEN_OF_SSID +1];
-    INT         Rssi = 0, max_len = LINE_LEN;
+	INT         Rssi = 0;
 	UINT        Rssi_Quality = 0;
 	NDIS_802_11_NETWORK_TYPE    wireless_mode;
+	CHAR		Ssid[MAX_LEN_OF_SSID +1];
+	STRING		SecurityStr[32] = {0};
+	NDIS_802_11_ENCRYPTION_STATUS	ap_cipher = Ndis802_11EncryptionDisabled;
+	NDIS_802_11_AUTHENTICATION_MODE	ap_auth_mode = Ndis802_11AuthModeOpen;
 
-	os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
-
-	if (msg == NULL)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
-		return;
-	}
-
-	memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
 	memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
-	sprintf(msg,"%s","\n");
-	sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
-	    "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
-
-	WaitCnt = 0;
-	pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
-
-	while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
-		OS_WAIT(500);
-
-	for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
-	{
-		if( pAdapter->ScanTab.BssEntry[i].Channel==0)
-			break;
-
-		if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
-			break;
 
 		//Channel
-		sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel);
+		sprintf(msg+strlen(msg),"%-4d", pBss->Channel);
 		//SSID
-		memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
-		Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0';
+		memcpy(Ssid, pBss->Ssid, pBss->SsidLen);
+		Ssid[pBss->SsidLen] = '\0';
 		sprintf(msg+strlen(msg),"%-33s", Ssid);
 		//BSSID
 		sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x   ",
-			pAdapter->ScanTab.BssEntry[i].Bssid[0],
-			pAdapter->ScanTab.BssEntry[i].Bssid[1],
-			pAdapter->ScanTab.BssEntry[i].Bssid[2],
-			pAdapter->ScanTab.BssEntry[i].Bssid[3],
-			pAdapter->ScanTab.BssEntry[i].Bssid[4],
-			pAdapter->ScanTab.BssEntry[i].Bssid[5]);
-		//Encryption Type
-		sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus));
-		//Authentication Mode
-		if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled)
-			sprintf(msg+strlen(msg),"%-10s", "UNKNOW");
+			pBss->Bssid[0],
+			pBss->Bssid[1],
+			pBss->Bssid[2],
+			pBss->Bssid[3],
+			pBss->Bssid[4],
+			pBss->Bssid[5]);
+
+	//Security
+	if ((Ndis802_11AuthModeWPA <= pBss->AuthMode) &&
+		(pBss->AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+	{
+		if (pBss->AuthModeAux == Ndis802_11AuthModeWPANone)
+		{
+			ap_auth_mode = pBss->AuthMode;
+			if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+				ap_cipher = pBss->WPA.PairCipher;
+			else
+				ap_cipher = Ndis802_11Encryption4Enabled;
+	}
+		else if (pBss->AuthModeAux == Ndis802_11AuthModeOpen)
+		{
+			ap_auth_mode = pBss->AuthMode;
+			if ((ap_auth_mode == Ndis802_11AuthModeWPA) ||
+				(ap_auth_mode == Ndis802_11AuthModeWPAPSK))
+			{
+				if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+					ap_cipher = pBss->WPA.PairCipher;
+				else
+					ap_cipher = Ndis802_11Encryption4Enabled;
+			}
+			else if ((ap_auth_mode == Ndis802_11AuthModeWPA2) ||
+					 (ap_auth_mode == Ndis802_11AuthModeWPA2PSK))
+			{
+				if (pBss->WPA2.PairCipherAux == Ndis802_11WEPDisabled)
+					ap_cipher = pBss->WPA2.PairCipher;
+				else
+					ap_cipher = Ndis802_11Encryption4Enabled;
+			}
+		}
+		else if ((pBss->AuthMode == Ndis802_11AuthModeWPAPSK) ||
+				 (pBss->AuthMode == Ndis802_11AuthModeWPA2PSK))
+		{
+			if ((pBss->AuthModeAux == Ndis802_11AuthModeWPAPSK) ||
+				(pBss->AuthModeAux == Ndis802_11AuthModeWPA2PSK))
+				ap_auth_mode = Ndis802_11AuthModeWPA1PSKWPA2PSK;
+			else
+				ap_auth_mode = pBss->AuthMode;
+
+			if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher)
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux))
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
+					 (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled))
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
+					 (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled))
+				ap_cipher = pBss->WPA.PairCipher;
+		}
+		else if ((pBss->AuthMode == Ndis802_11AuthModeWPA) ||
+				 (pBss->AuthMode == Ndis802_11AuthModeWPA2))
+		{
+			if ((pBss->AuthModeAux == Ndis802_11AuthModeWPA) ||
+				(pBss->AuthMode == Ndis802_11AuthModeWPA2))
+				ap_auth_mode = Ndis802_11AuthModeWPA1WPA2;
+			else
+				ap_auth_mode = pBss->AuthMode;
+
+			if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher)
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux))
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
+					 (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled))
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
+					 (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled))
+				ap_cipher = pBss->WPA.PairCipher;
+		}
+
+		sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher));
+	}
+	else
+	{
+		ap_auth_mode = pBss->AuthMode;
+		ap_cipher = pBss->WepStatus;
+		if (ap_cipher == Ndis802_11WEPDisabled)
+			sprintf(SecurityStr, "NONE");
+		else if (ap_cipher == Ndis802_11WEPEnabled)
+			sprintf(SecurityStr, "WEP");
 		else
-			sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode));
+			sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher));
+	}
+
+	sprintf(msg+strlen(msg), "%-23s", SecurityStr);
+
 		// Rssi
-		Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi;
+		Rssi = (INT)pBss->Rssi;
 		if (Rssi >= -50)
 			Rssi_Quality = 100;
 		else if (Rssi >= -80)    // between -50 ~ -80dbm
@@ -1858,7 +1928,7 @@  VOID RTMPIoctlGetSiteSurvey(
 			Rssi_Quality = 0;
 		sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
 		// Wireless Mode
-		wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
+		wireless_mode = NetworkTypeInUseSanity(pBss);
 		if (wireless_mode == Ndis802_11FH ||
 			wireless_mode == Ndis802_11DS)
 			sprintf(msg+strlen(msg),"%-7s", "11b");
@@ -1872,13 +1942,79 @@  VOID RTMPIoctlGetSiteSurvey(
 			sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
 		else
 			sprintf(msg+strlen(msg),"%-7s", "unknow");
+
+		// Ext Channel
+		if (pBss->AddHtInfoLen > 0)
+		{
+			if (pBss->AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE)
+				sprintf(msg+strlen(msg),"%-7s", " ABOVE");
+			else if (pBss->AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW)
+				sprintf(msg+strlen(msg),"%-7s", " BELOW");
+			else
+				sprintf(msg+strlen(msg),"%-7s", " NONE");
+		}
+		else
+		{
+			sprintf(msg+strlen(msg),"%-7s", " NONE");
+		}
+
 		//Network Type
-		if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC)
+		if (pBss->BssType == BSS_ADHOC)
 			sprintf(msg+strlen(msg),"%-3s", " Ad");
 		else
 			sprintf(msg+strlen(msg),"%-3s", " In");
 
         sprintf(msg+strlen(msg),"\n");
+
+	return;
+}
+
+VOID RTMPIoctlGetSiteSurvey(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq)
+{
+	PSTRING		msg;
+	INT		i=0;
+	INT			WaitCnt;
+	INT		Status=0;
+    INT         max_len = LINE_LEN;
+	PBSS_ENTRY	pBss;
+
+
+	os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
+
+	if (msg == NULL)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
+		return;
+	}
+
+	memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
+	sprintf(msg,"%s","\n");
+	sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-23s%-9s%-7s%-7s%-3s\n",
+	    "Ch", "SSID", "BSSID", "Security", "Siganl(%)", "W-Mode", " ExtCH"," NT");
+
+
+
+	WaitCnt = 0;
+	pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+	while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
+		OS_WAIT(500);
+
+	for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
+	{
+		pBss = &pAdapter->ScanTab.BssEntry[i];
+
+		if( pBss->Channel==0)
+			break;
+
+		if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
+			break;
+
+
+		RTMPCommSiteSurveyData(msg, pBss);
+
+
 	}
 
 	pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
@@ -1933,7 +2069,12 @@  VOID RTMPIoctlGetMacTable(
 		DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __func__));
 	}
 
-	msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
+	msg = kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
+	if (msg == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __func__));
+		return;
+	}
 	memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
 	sprintf(msg,"%s","\n");
 	sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
@@ -1968,12 +2109,14 @@  VOID RTMPIoctlGetMacTable(
 	kfree(msg);
 }
 
+
 INT	Set_BASetup_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
     UCHAR mac[6], tid;
-	char *token, sepValue[] = ":", DASH = '-';
+	PSTRING token;
+	STRING sepValue[] = ":", DASH = '-';
 	INT i;
     MAC_TABLE_ENTRY *pEntry;
 
@@ -1982,6 +2125,7 @@  INT	Set_BASetup_Proc(
 		=>The six 2 digit hex-decimal number previous are the Mac address,
 		=>The seventh decimal number is the tid value.
 */
+	//DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
 
 	if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
 		return FALSE;
@@ -1989,7 +2133,7 @@  INT	Set_BASetup_Proc(
 	token = strchr(arg, DASH);
 	if ((token != NULL) && (strlen(token)>1))
 	{
-		tid = simple_strtol((token+1), 0, 10);
+		tid = (UCHAR) simple_strtol((token+1), 0, 10);
 		if (tid > 15)
 			return FALSE;
 
@@ -1998,18 +2142,18 @@  INT	Set_BASetup_Proc(
 		{
 			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
 				return FALSE;
-			AtoH(token, (PUCHAR)(&mac[i]), 1);
+			AtoH(token, (&mac[i]), 1);
 		}
 		if(i != 6)
 			return FALSE;
 
-		printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1],
-				mac[2], mac[3], mac[4], mac[5], tid);
+		DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n",
+								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
 
-	    pEntry = MacTableLookup(pAd, mac);
+	    pEntry = MacTableLookup(pAd, (PUCHAR) mac);
 
     	if (pEntry) {
-        	printk("\nSetup BA Session: Tid = %d\n", tid);
+		DBGPRINT(RT_DEBUG_OFF, ("\nSetup BA Session: Tid = %d\n", tid));
 	        BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
     	}
 
@@ -2022,7 +2166,7 @@  INT	Set_BASetup_Proc(
 
 INT	Set_BADecline_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG bBADecline;
 
@@ -2048,13 +2192,15 @@  INT	Set_BADecline_Proc(
 
 INT	Set_BAOriTearDown_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
     UCHAR mac[6], tid;
-	char *token, sepValue[] = ":", DASH = '-';
+	PSTRING token;
+	STRING sepValue[] = ":", DASH = '-';
 	INT i;
     MAC_TABLE_ENTRY *pEntry;
 
+    //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
 /*
 	The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
 		=>The six 2 digit hex-decimal number previous are the Mac address,
@@ -2075,18 +2221,18 @@  INT	Set_BAOriTearDown_Proc(
 		{
 			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
 				return FALSE;
-			AtoH(token, (PUCHAR)(&mac[i]), 1);
+			AtoH(token, (&mac[i]), 1);
 		}
 		if(i != 6)
 			return FALSE;
 
-	    printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
-	           mac[2], mac[3], mac[4], mac[5], tid);
+	    DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
+								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
 
-	    pEntry = MacTableLookup(pAd, mac);
+	    pEntry = MacTableLookup(pAd, (PUCHAR) mac);
 
 	    if (pEntry) {
-	        printk("\nTear down Ori BA Session: Tid = %d\n", tid);
+	        DBGPRINT(RT_DEBUG_OFF, ("\nTear down Ori BA Session: Tid = %d\n", tid));
         BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
 	    }
 
@@ -2099,14 +2245,15 @@  INT	Set_BAOriTearDown_Proc(
 
 INT	Set_BARecTearDown_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
     UCHAR mac[6], tid;
-	char *token, sepValue[] = ":", DASH = '-';
+	PSTRING token;
+	STRING sepValue[] = ":", DASH = '-';
 	INT i;
     MAC_TABLE_ENTRY *pEntry;
 
-    //printk("\n%s\n", arg);
+    //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
 /*
 	The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
 		=>The six 2 digit hex-decimal number previous are the Mac address,
@@ -2127,18 +2274,18 @@  INT	Set_BARecTearDown_Proc(
 		{
 			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
 				return FALSE;
-			AtoH(token, (PUCHAR)(&mac[i]), 1);
+			AtoH(token, (&mac[i]), 1);
 		}
 		if(i != 6)
 			return FALSE;
 
-		printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
-		       mac[2], mac[3], mac[4], mac[5], tid);
+		DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
+								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
 
-		pEntry = MacTableLookup(pAd, mac);
+		pEntry = MacTableLookup(pAd, (PUCHAR) mac);
 
 		if (pEntry) {
-		    printk("\nTear down Rec BA Session: Tid = %d\n", tid);
+		    DBGPRINT(RT_DEBUG_OFF, ("\nTear down Rec BA Session: Tid = %d\n", tid));
 		    BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
 		}
 
@@ -2151,7 +2298,7 @@  INT	Set_BARecTearDown_Proc(
 
 INT	Set_HtBw_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG HtBw;
 
@@ -2172,7 +2319,7 @@  INT	Set_HtBw_Proc(
 
 INT	Set_HtMcs_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG HtMcs, Mcs_tmp;
     BOOLEAN bAutoRate = FALSE;
@@ -2226,7 +2373,7 @@  INT	Set_HtMcs_Proc(
 
 INT	Set_HtGi_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG HtGi;
 
@@ -2249,7 +2396,7 @@  INT	Set_HtGi_Proc(
 
 INT	Set_HtTxBASize_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	UCHAR Size;
 
@@ -2265,10 +2412,32 @@  INT	Set_HtTxBASize_Proc(
 	return TRUE;
 }
 
+INT	Set_HtDisallowTKIP_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+	if (Value == 1)
+	{
+		pAd->CommonCfg.HT_DisallowTKIP = TRUE;
+	}
+	else
+	{
+		pAd->CommonCfg.HT_DisallowTKIP = FALSE;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtDisallowTKIP_Proc ::%s\n",
+				(pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "enabled" : "disabled"));
+
+	return TRUE;
+}
 
 INT	Set_HtOpMode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 
 	ULONG Value;
@@ -2292,7 +2461,7 @@  INT	Set_HtOpMode_Proc(
 
 INT	Set_HtStbc_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 
 	ULONG Value;
@@ -2315,7 +2484,7 @@  INT	Set_HtStbc_Proc(
 
 INT	Set_HtHtc_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 
 	ULONG Value;
@@ -2335,7 +2504,7 @@  INT	Set_HtHtc_Proc(
 
 INT	Set_HtExtcha_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 
 	ULONG Value;
@@ -2358,7 +2527,7 @@  INT	Set_HtExtcha_Proc(
 
 INT	Set_HtMpduDensity_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2378,7 +2547,7 @@  INT	Set_HtMpduDensity_Proc(
 
 INT	Set_HtBaWinSize_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2405,7 +2574,7 @@  INT	Set_HtBaWinSize_Proc(
 
 INT	Set_HtRdg_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2430,7 +2599,7 @@  INT	Set_HtRdg_Proc(
 
 INT	Set_HtLinkAdapt_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2452,7 +2621,7 @@  INT	Set_HtLinkAdapt_Proc(
 
 INT	Set_HtAmsdu_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2473,7 +2642,7 @@  INT	Set_HtAmsdu_Proc(
 
 INT	Set_HtAutoBa_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2504,7 +2673,7 @@  INT	Set_HtAutoBa_Proc(
 
 INT	Set_HtProtect_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2523,14 +2692,15 @@  INT	Set_HtProtect_Proc(
 
 INT	Set_SendPSMPAction_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
     UCHAR mac[6], mode;
-	char *token, sepValue[] = ":", DASH = '-';
+	PSTRING token;
+	STRING sepValue[] = ":", DASH = '-';
 	INT i;
     MAC_TABLE_ENTRY *pEntry;
 
-    //printk("\n%s\n", arg);
+    //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg));
 /*
 	The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
 		=>The six 2 digit hex-decimal number previous are the Mac address,
@@ -2551,18 +2721,18 @@  INT	Set_SendPSMPAction_Proc(
 		{
 			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
 				return FALSE;
-			AtoH(token, (PUCHAR)(&mac[i]), 1);
+			AtoH(token, (&mac[i]), 1);
 		}
 		if(i != 6)
 			return FALSE;
 
-		printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
-		       mac[2], mac[3], mac[4], mac[5], mode);
+		DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
+								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mode));
 
 		pEntry = MacTableLookup(pAd, mac);
 
 		if (pEntry) {
-		    printk("\nSendPSMPAction MIPS mode = %d\n", mode);
+		    DBGPRINT(RT_DEBUG_OFF, ("\nSendPSMPAction MIPS mode = %d\n", mode));
 		    SendPSMPAction(pAd, pEntry->Aid, mode);
 		}
 
@@ -2576,7 +2746,7 @@  INT	Set_SendPSMPAction_Proc(
 
 INT	Set_HtMIMOPSmode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2597,7 +2767,7 @@  INT	Set_HtMIMOPSmode_Proc(
 
 INT	Set_ForceShortGI_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2620,7 +2790,7 @@  INT	Set_ForceShortGI_Proc(
 
 INT	Set_ForceGF_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2641,7 +2811,7 @@  INT	Set_ForceGF_Proc(
 
 INT	Set_HtMimoPs_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	ULONG Value;
 
@@ -2682,7 +2852,7 @@  INT	SetCommonHT(
 
 INT	Set_FixedTxMode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	UCHAR	fix_tx_mode = FIXED_TXMODE_HT;
 
@@ -2702,8 +2872,57 @@  INT	Set_FixedTxMode_Proc(
 	return TRUE;
 }
 
+#if defined(RT305x)||defined(RT3070)
+INT Set_HiPower_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg)
+{
+	pAdapter->CommonCfg.HighPowerPatchDisabled = !(simple_strtol(arg, 0, 10));
+
+	if (pAdapter->CommonCfg.HighPowerPatchDisabled != 0)
+	{
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R82, 0x62);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R67, 0x20);
+#ifdef RT3070
+		if ((IS_RT3070(pAdapter) && ((pAdapter->MACVersion & 0xffff) < 0x0201)))
+#endif // RT3070 //
+		RT30xxWriteRFRegister(pAdapter, RF_R27, 0x23);
+	}
+	return TRUE;
+}
+#endif
+
+INT Set_LongRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PSTRING			arg)
+{
+	TX_RTY_CFG_STRUC	tx_rty_cfg;
+	UCHAR				LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+	tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
+	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+	return TRUE;
+}
+
+INT Set_ShortRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PSTRING			arg)
+{
+	TX_RTY_CFG_STRUC	tx_rty_cfg;
+	UCHAR				ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+	tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
+	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+	return TRUE;
+}
+
+
 /////////////////////////////////////////////////////////////////////////
-PCHAR   RTMPGetRalinkAuthModeStr(
+PSTRING RTMPGetRalinkAuthModeStr(
     IN  NDIS_802_11_AUTHENTICATION_MODE authMode)
 {
 	switch(authMode)
@@ -2731,14 +2950,11 @@  PCHAR   RTMPGetRalinkAuthModeStr(
 	}
 }
 
-PCHAR   RTMPGetRalinkEncryModeStr(
+PSTRING RTMPGetRalinkEncryModeStr(
     IN  USHORT encryMode)
 {
 	switch(encryMode)
 	{
-#if defined(RT2860) || defined(RT30xx)
-	    default:
-#endif
 		case Ndis802_11WEPDisabled:
 			return "NONE";
 		case Ndis802_11WEPEnabled:
@@ -2749,17 +2965,15 @@  PCHAR   RTMPGetRalinkEncryModeStr(
 			return "AES";
         case Ndis802_11Encryption4Enabled:
 			return "TKIPAES";
-#if !defined(RT2860) && !defined(RT30xx)
 		default:
 			return "UNKNOW";
-#endif
 	}
 }
 
 INT RTMPShowCfgValue(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pName,
-	IN	PUCHAR			pBuf)
+	IN	PSTRING			pName,
+	IN	PSTRING			pBuf)
 {
 	INT	Status = 0;
 
@@ -2785,7 +2999,7 @@  INT RTMPShowCfgValue(
 
 INT	Show_SSID_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
 	return 0;
@@ -2793,7 +3007,7 @@  INT	Show_SSID_Proc(
 
 INT	Show_WirelessMode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	switch(pAd->CommonCfg.PhyMode)
 	{
@@ -2843,7 +3057,7 @@  INT	Show_WirelessMode_Proc(
 
 INT	Show_TxBurst_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
 	return 0;
@@ -2851,7 +3065,7 @@  INT	Show_TxBurst_Proc(
 
 INT	Show_TxPreamble_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	switch(pAd->CommonCfg.TxPreamble)
 	{
@@ -2874,7 +3088,7 @@  INT	Show_TxPreamble_Proc(
 
 INT	Show_TxPower_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
 	return 0;
@@ -2882,7 +3096,7 @@  INT	Show_TxPower_Proc(
 
 INT	Show_Channel_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
 	return 0;
@@ -2890,7 +3104,7 @@  INT	Show_Channel_Proc(
 
 INT	Show_BGProtection_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	switch(pAd->CommonCfg.UseBGProtection)
 	{
@@ -2912,7 +3126,7 @@  INT	Show_BGProtection_Proc(
 
 INT	Show_RTSThreshold_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
 	return 0;
@@ -2920,7 +3134,7 @@  INT	Show_RTSThreshold_Proc(
 
 INT	Show_FragThreshold_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
 	return 0;
@@ -2928,7 +3142,7 @@  INT	Show_FragThreshold_Proc(
 
 INT	Show_HtBw_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
 	{
@@ -2943,7 +3157,7 @@  INT	Show_HtBw_Proc(
 
 INT	Show_HtMcs_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
 	return 0;
@@ -2951,7 +3165,7 @@  INT	Show_HtMcs_Proc(
 
 INT	Show_HtGi_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
 	{
@@ -2970,7 +3184,7 @@  INT	Show_HtGi_Proc(
 
 INT	Show_HtOpMode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
 	{
@@ -2989,7 +3203,7 @@  INT	Show_HtOpMode_Proc(
 
 INT	Show_HtExtcha_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
 	{
@@ -3009,7 +3223,7 @@  INT	Show_HtExtcha_Proc(
 
 INT	Show_HtMpduDensity_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
 	return 0;
@@ -3017,7 +3231,7 @@  INT	Show_HtMpduDensity_Proc(
 
 INT	Show_HtBaWinSize_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
 	return 0;
@@ -3025,7 +3239,7 @@  INT	Show_HtBaWinSize_Proc(
 
 INT	Show_HtRdg_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
 	return 0;
@@ -3033,7 +3247,7 @@  INT	Show_HtRdg_Proc(
 
 INT	Show_HtAmsdu_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
 	return 0;
@@ -3041,7 +3255,7 @@  INT	Show_HtAmsdu_Proc(
 
 INT	Show_HtAutoBa_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
 	return 0;
@@ -3049,7 +3263,7 @@  INT	Show_HtAutoBa_Proc(
 
 INT	Show_CountryRegion_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
 	return 0;
@@ -3057,7 +3271,7 @@  INT	Show_CountryRegion_Proc(
 
 INT	Show_CountryRegionABand_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
 	return 0;
@@ -3065,7 +3279,7 @@  INT	Show_CountryRegionABand_Proc(
 
 INT	Show_CountryCode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
 	return 0;
@@ -3074,7 +3288,7 @@  INT	Show_CountryCode_Proc(
 #ifdef AGGREGATION_SUPPORT
 INT	Show_PktAggregate_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
 	return 0;
@@ -3084,7 +3298,7 @@  INT	Show_PktAggregate_Proc(
 #ifdef WMM_SUPPORT
 INT	Show_WmmCapable_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
 
@@ -3094,7 +3308,7 @@  INT	Show_WmmCapable_Proc(
 
 INT	Show_IEEE80211H_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
 	return 0;
@@ -3102,7 +3316,7 @@  INT	Show_IEEE80211H_Proc(
 
 INT	Show_NetworkType_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	switch(pAd->StaCfg.BssType)
 	{
@@ -3125,9 +3339,11 @@  INT	Show_NetworkType_Proc(
 	return 0;
 }
 
+
+
 INT	Show_AuthMode_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	NDIS_802_11_AUTHENTICATION_MODE	AuthMode = Ndis802_11AuthModeOpen;
 
@@ -3144,7 +3360,7 @@  INT	Show_AuthMode_Proc(
 
 INT	Show_EncrypType_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	NDIS_802_11_WEP_STATUS	WepStatus = Ndis802_11WEPDisabled;
 
@@ -3161,7 +3377,7 @@  INT	Show_EncrypType_Proc(
 
 INT	Show_DefaultKeyID_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	UCHAR DefaultKeyId = 0;
 
@@ -3175,7 +3391,7 @@  INT	Show_DefaultKeyID_Proc(
 INT	Show_WepKey_Proc(
 	IN	PRTMP_ADAPTER	pAd,
 	IN  INT				KeyIdx,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	UCHAR   Key[16] = {0}, KeyLength = 0;
 	INT		index = BSS0;
@@ -3184,7 +3400,7 @@  INT	Show_WepKey_Proc(
 	NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
 
 	//check key string is ASCII or not
-    if (RTMPCheckStrPrintAble(Key, KeyLength))
+    if (RTMPCheckStrPrintAble((PCHAR)Key, KeyLength))
         sprintf(pBuf, "\t%s", Key);
     else
     {
@@ -3198,7 +3414,7 @@  INT	Show_WepKey_Proc(
 
 INT	Show_Key1_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	Show_WepKey_Proc(pAd, 0, pBuf);
 	return 0;
@@ -3206,7 +3422,7 @@  INT	Show_Key1_Proc(
 
 INT	Show_Key2_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	Show_WepKey_Proc(pAd, 1, pBuf);
 	return 0;
@@ -3214,7 +3430,7 @@  INT	Show_Key2_Proc(
 
 INT	Show_Key3_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	Show_WepKey_Proc(pAd, 2, pBuf);
 	return 0;
@@ -3222,7 +3438,7 @@  INT	Show_Key3_Proc(
 
 INT	Show_Key4_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	Show_WepKey_Proc(pAd, 3, pBuf);
 	return 0;
@@ -3230,7 +3446,7 @@  INT	Show_Key4_Proc(
 
 INT	Show_WPAPSK_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	OUT	PUCHAR			pBuf)
+	OUT	PSTRING			pBuf)
 {
 	INT 	idx;
 	UCHAR	PMK[32] = {0};
diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c
new file mode 100644
index 0000000..5aa6944
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_mac_pci.c
@@ -0,0 +1,1504 @@ 
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * 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.,                                       *
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+
+#ifdef RTMP_MAC_PCI
+#include	"../rt_config.h"
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Allocate DMA memory blocks for send, receive
+
+	Arguments:
+		Adapter		Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS
+		NDIS_STATUS_FAILURE
+		NDIS_STATUS_RESOURCES
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS	RTMPAllocTxRxRingMemory(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
+	ULONG			RingBasePaHigh;
+	ULONG			RingBasePaLow;
+	PVOID			RingBaseVa;
+	INT				index, num;
+	PTXD_STRUC		pTxD;
+	PRXD_STRUC		pRxD;
+	ULONG			ErrorValue = 0;
+	PRTMP_TX_RING	pTxRing;
+	PRTMP_DMABUF	pDmaBuf;
+	PNDIS_PACKET	pPacket;
+//	PRTMP_REORDERBUF	pReorderBuf;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
+	do
+	{
+		//
+		// Allocate all ring descriptors, include TxD, RxD, MgmtD.
+		// Although each size is different, to prevent cacheline and alignment
+		// issue, I intentional set them all to 64 bytes.
+		//
+		for (num=0; num<NUM_OF_TX_RING; num++)
+		{
+			ULONG  BufBasePaHigh;
+			ULONG  BufBasePaLow;
+			PVOID  BufBaseVa;
+
+			//
+			// Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
+			//
+			pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
+			RTMP_AllocateTxDescMemory(
+				pAd,
+				num,
+				pAd->TxDescRing[num].AllocSize,
+				FALSE,
+				&pAd->TxDescRing[num].AllocVa,
+				&pAd->TxDescRing[num].AllocPa);
+
+			if (pAd->TxDescRing[num].AllocVa == NULL)
+			{
+				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+
+			// Zero init this memory block
+			NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);
+
+			// Save PA & VA for further operation
+			RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
+			RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
+			RingBaseVa     = pAd->TxDescRing[num].AllocVa;
+
+			//
+			// Allocate all 1st TXBuf's memory for this TxRing
+			//
+			pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
+			RTMP_AllocateFirstTxBuffer(
+				pAd,
+				num,
+				pAd->TxBufSpace[num].AllocSize,
+				FALSE,
+				&pAd->TxBufSpace[num].AllocVa,
+				&pAd->TxBufSpace[num].AllocPa);
+
+			if (pAd->TxBufSpace[num].AllocVa == NULL)
+			{
+				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+
+			// Zero init this memory block
+			NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);
+
+			// Save PA & VA for further operation
+			BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
+			BufBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
+			BufBaseVa     = pAd->TxBufSpace[num].AllocVa;
+
+			//
+			// Initialize Tx Ring Descriptor and associated buffer memory
+			//
+			pTxRing = &pAd->TxRing[num];
+			for (index = 0; index < TX_RING_SIZE; index++)
+			{
+				pTxRing->Cell[index].pNdisPacket = NULL;
+				pTxRing->Cell[index].pNextNdisPacket = NULL;
+				// Init Tx Ring Size, Va, Pa variables
+				pTxRing->Cell[index].AllocSize = TXD_SIZE;
+				pTxRing->Cell[index].AllocVa = RingBaseVa;
+				RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
+				RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);
+
+				// Setup Tx Buffer size & address. only 802.11 header will store in this space
+				pDmaBuf = &pTxRing->Cell[index].DmaBuf;
+				pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
+				pDmaBuf->AllocVa = BufBaseVa;
+				RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
+				RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);
+
+				// link the pre-allocated TxBuf to TXD
+				pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
+				pTxD->SDPtr0 = BufBasePaLow;
+				// advance to next ring descriptor address
+				pTxD->DMADONE = 1;
+				RingBasePaLow += TXD_SIZE;
+				RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
+
+				// advance to next TxBuf address
+				BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
+				BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
+		}
+		if (Status == NDIS_STATUS_RESOURCES)
+			break;
+
+		//
+		// Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler
+		//
+		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
+		RTMP_AllocateMgmtDescMemory(
+			pAd,
+			pAd->MgmtDescRing.AllocSize,
+			FALSE,
+			&pAd->MgmtDescRing.AllocVa,
+			&pAd->MgmtDescRing.AllocPa);
+
+		if (pAd->MgmtDescRing.AllocVa == NULL)
+		{
+			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+			Status = NDIS_STATUS_RESOURCES;
+			break;
+		}
+
+		// Zero init this memory block
+		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
+
+		// Save PA & VA for further operation
+		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
+		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
+		RingBaseVa     = pAd->MgmtDescRing.AllocVa;
+
+		//
+		// Initialize MGMT Ring and associated buffer memory
+		//
+		for (index = 0; index < MGMT_RING_SIZE; index++)
+		{
+			pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
+			pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
+			// Init MGMT Ring Size, Va, Pa variables
+			pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
+			pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
+			RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
+			RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);
+
+			// Offset to next ring descriptor address
+			RingBasePaLow += TXD_SIZE;
+			RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
+
+			// link the pre-allocated TxBuf to TXD
+			pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
+			pTxD->DMADONE = 1;
+
+			// no pre-allocated buffer required in MgmtRing for scatter-gather case
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));
+
+		//
+		// Allocate RX ring descriptor's memory except Tx ring which allocated eariler
+		//
+		pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
+		RTMP_AllocateRxDescMemory(
+			pAd,
+			pAd->RxDescRing.AllocSize,
+			FALSE,
+			&pAd->RxDescRing.AllocVa,
+			&pAd->RxDescRing.AllocPa);
+
+		if (pAd->RxDescRing.AllocVa == NULL)
+		{
+			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+			Status = NDIS_STATUS_RESOURCES;
+			break;
+		}
+
+		// Zero init this memory block
+		NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);
+
+
+		DBGPRINT(RT_DEBUG_OFF,
+					("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize));
+
+		// Save PA & VA for further operation
+		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
+		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
+		RingBaseVa     = pAd->RxDescRing.AllocVa;
+
+		//
+		// Initialize Rx Ring and associated buffer memory
+		//
+		for (index = 0; index < RX_RING_SIZE; index++)
+		{
+			// Init RX Ring Size, Va, Pa variables
+			pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
+			pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
+			RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
+			RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);
+
+			//NdisZeroMemory(RingBaseVa, RXD_SIZE);
+
+			// Offset to next ring descriptor address
+			RingBasePaLow += RXD_SIZE;
+			RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;
+
+			// Setup Rx associated Buffer size & allocate share memory
+			pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
+			pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
+			pPacket = RTMP_AllocateRxPacketBuffer(
+				pAd,
+				pDmaBuf->AllocSize,
+				FALSE,
+				&pDmaBuf->AllocVa,
+				&pDmaBuf->AllocPa);
+
+			/* keep allocated rx packet */
+			pAd->RxRing.Cell[index].pNdisPacket = pPacket;
+
+			// Error handling
+			if (pDmaBuf->AllocVa == NULL)
+			{
+				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+				DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+
+			// Zero init this memory block
+			NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
+
+			// Write RxD buffer address & allocated buffer length
+			pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
+			pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
+			pRxD->DDONE = 0;
+
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));
+
+	}	while (FALSE);
+
+
+	NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
+	pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+
+	if (pAd->FragFrame.pFragPacket == NULL)
+	{
+		Status = NDIS_STATUS_RESOURCES;
+	}
+
+	if (Status != NDIS_STATUS_SUCCESS)
+	{
+		// Log error inforamtion
+		NdisWriteErrorLogEntry(
+			pAd->AdapterHandle,
+			NDIS_ERROR_CODE_OUT_OF_RESOURCES,
+			1,
+			ErrorValue);
+	}
+
+	// Following code segment get from original func:NICInitTxRxRingAndBacklogQueue(), now should integrate it to here.
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTxRxRingAndBacklogQueue\n"));
+
+/*
+		// Disable DMA.
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		GloCfg.word &= 0xff0;
+		GloCfg.field.EnTXWriteBackDDONE =1;
+		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+*/
+
+		// Initialize all transmit related software queues
+		for(index = 0; index < NUM_OF_TX_RING; index++)
+		{
+			InitializeQueueHeader(&pAd->TxSwQueue[index]);
+			// Init TX rings index pointer
+			pAd->TxRing[index].TxSwFreeIdx = 0;
+			pAd->TxRing[index].TxCpuIdx = 0;
+			//RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) ,  pAd->TxRing[i].TX_CTX_IDX);
+		}
+
+		// Init RX Ring index pointer
+		pAd->RxRing.RxSwReadIdx = 0;
+		pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
+		//RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RX_CRX_IDX0);
+
+
+		// init MGMT ring index pointer
+		pAd->MgmtRing.TxSwFreeIdx = 0;
+		pAd->MgmtRing.TxCpuIdx = 0;
+
+		pAd->PrivateInfo.TxRingFullCnt = 0;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTxRxRingAndBacklogQueue\n"));
+	}
+
+	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
+	return Status;
+}
+
+
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		Reset NIC to initial state AS IS system boot up time.
+
+	========================================================================
+*/
+VOID	RTMPRingCleanUp(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			RingType)
+{
+	PTXD_STRUC		pTxD;
+	PRXD_STRUC		pRxD;
+	PQUEUE_ENTRY	pEntry;
+	PNDIS_PACKET	pPacket;
+	int				i;
+	PRTMP_TX_RING	pTxRing;
+	unsigned long	IrqFlags;
+	//UINT32			RxSwReadIdx;
+
+
+	DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount));
+	switch (RingType)
+	{
+		case QID_AC_BK:
+		case QID_AC_BE:
+		case QID_AC_VI:
+		case QID_AC_VO:
+		case QID_HCCA:
+
+			pTxRing = &pAd->TxRing[RingType];
+
+			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+			// We have to clean all descriptors in case some error happened with reset
+			for (i=0; i<TX_RING_SIZE; i++) // We have to scan all TX ring
+			{
+				pTxD  = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
+
+				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket;
+				// release scatter-and-gather NDIS_PACKET
+				if (pPacket)
+				{
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+					pTxRing->Cell[i].pNdisPacket = NULL;
+				}
+
+				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket;
+				// release scatter-and-gather NDIS_PACKET
+				if (pPacket)
+				{
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+					pTxRing->Cell[i].pNextNdisPacket = NULL;
+				}
+			}
+
+			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx);
+			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
+			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
+			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx);
+
+			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+			while (pAd->TxSwQueue[RingType].Head != NULL)
+			{
+				pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
+				pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+				DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n"));
+			}
+			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+			break;
+
+		case QID_MGMT:
+			// We have to clean all descriptors in case some error happened with reset
+			NdisAcquireSpinLock(&pAd->MgmtRingLock);
+
+			for (i=0; i<MGMT_RING_SIZE; i++)
+			{
+				pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa;
+
+				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket;
+				// rlease scatter-and-gather NDIS_PACKET
+				if (pPacket)
+				{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+				}
+				pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
+
+				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket;
+				// release scatter-and-gather NDIS_PACKET
+				if (pPacket)
+				{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+			}
+				pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
+
+			}
+
+			RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
+			pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
+			pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
+			RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
+
+			NdisReleaseSpinLock(&pAd->MgmtRingLock);
+			pAd->RalinkCounters.MgmtRingFullCount = 0;
+			break;
+
+		case QID_RX:
+			// We have to clean all descriptors in case some error happened with reset
+			NdisAcquireSpinLock(&pAd->RxRingLock);
+
+			for (i=0; i<RX_RING_SIZE; i++)
+			{
+				pRxD  = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa;
+                pRxD->DDONE = 0 ;
+			}
+
+			RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
+			pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
+			pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1));
+			RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+
+			NdisReleaseSpinLock(&pAd->RxRingLock);
+			break;
+
+		default:
+			break;
+	}
+}
+
+
+VOID RTMPFreeTxRxRingMemory(
+    IN  PRTMP_ADAPTER   pAd)
+{
+	int index, num , j;
+	PRTMP_TX_RING pTxRing;
+	PTXD_STRUC	  pTxD;
+	PNDIS_PACKET  pPacket;
+	unsigned int  IrqFlags;
+
+	//POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
+
+	// Free TxSwQueue Packet
+	for (index=0; index <NUM_OF_TX_RING; index++)
+	{
+		PQUEUE_ENTRY pEntry;
+		PNDIS_PACKET pPacket;
+		PQUEUE_HEADER   pQueue;
+
+		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+		pQueue = &pAd->TxSwQueue[index];
+		while (pQueue->Head)
+		{
+			pEntry = RemoveHeadQueue(pQueue);
+			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+		}
+		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+	}
+
+	// Free Tx Ring Packet
+	for (index=0;index< NUM_OF_TX_RING;index++)
+	{
+		pTxRing = &pAd->TxRing[index];
+
+		for (j=0; j< TX_RING_SIZE; j++)
+		{
+			pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa);
+			pPacket = pTxRing->Cell[j].pNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+			//Always assign pNdisPacket as NULL after clear
+			pTxRing->Cell[j].pNdisPacket = NULL;
+
+			pPacket = pTxRing->Cell[j].pNextNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+			//Always assign pNextNdisPacket as NULL after clear
+			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
+
+		}
+	}
+
+	for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
+	{
+		if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket))
+		{
+			PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
+			RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS);
+		}
+	}
+	NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
+
+	if (pAd->RxDescRing.AllocVa)
+    {
+		RTMP_FreeDescMemory(pAd, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa);
+    }
+    NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF));
+
+	if (pAd->MgmtDescRing.AllocVa)
+	{
+		RTMP_FreeDescMemory(pAd, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa);
+	}
+	NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF));
+
+	for (num = 0; num < NUM_OF_TX_RING; num++)
+	{
+	if (pAd->TxBufSpace[num].AllocVa)
+		{
+			RTMP_FreeFirstTxBuffer(pAd, pAd->TxBufSpace[num].AllocSize, FALSE, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa);
+	    }
+	    NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF));
+
+	if (pAd->TxDescRing[num].AllocVa)
+		{
+			RTMP_FreeDescMemory(pAd, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa);
+	    }
+	    NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF));
+	}
+
+	if (pAd->FragFrame.pFragPacket)
+		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
+}
+
+
+/***************************************************************************
+  *
+  *	register related procedures.
+  *
+  **************************************************************************/
+/*
+========================================================================
+Routine Description:
+    Disable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMADisable(
+	IN RTMP_ADAPTER			*pAd)
+{
+	WPDMA_GLO_CFG_STRUC     GloCfg;
+
+
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+	GloCfg.word &= 0xff0;
+	GloCfg.field.EnTXWriteBackDDONE =1;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Enable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMAEnable(
+	IN RTMP_ADAPTER			*pAd)
+{
+	WPDMA_GLO_CFG_STRUC	GloCfg;
+	int i = 0;
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
+	do
+	{
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
+			break;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
+		RTMPusecDelay(1000);
+		i++;
+	}while ( i <200);
+
+	RTMPusecDelay(50);
+
+	GloCfg.field.EnTXWriteBackDDONE = 1;
+	GloCfg.field.WPDMABurstSIZE = 2;
+	GloCfg.field.EnableRxDMA = 1;
+	GloCfg.field.EnableTxDMA = 1;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+}
+
+
+BOOLEAN AsicCheckCommanOk(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 Command)
+{
+	UINT32	CmdStatus = 0, CID = 0, i;
+	UINT32	ThisCIDMask = 0;
+
+	i = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
+		// Find where the command is. Because this is randomly specified by firmware.
+		if ((CID & CID0MASK) == Command)
+		{
+			ThisCIDMask = CID0MASK;
+			break;
+		}
+		else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
+		{
+			ThisCIDMask = CID1MASK;
+			break;
+		}
+		else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
+		{
+			ThisCIDMask = CID2MASK;
+			break;
+		}
+		else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
+		{
+			ThisCIDMask = CID3MASK;
+			break;
+		}
+
+		RTMPusecDelay(100);
+		i++;
+	}while (i < 200);
+
+	// Get CommandStatus Value
+	RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
+
+	// This command's status is at the same position as command. So AND command position's bitmask to read status.
+	if (i < 200)
+	{
+		// If Status is 1, the comamnd is success.
+		if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
+			|| ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
+			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
+			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
+			return TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
+	}
+	// Clear Command and Status.
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
+
+	return FALSE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Write Beacon buffer to Asic.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID RT28xx_UpdateBeaconToAsic(
+	IN RTMP_ADAPTER		*pAd,
+	IN INT				apidx,
+	IN ULONG			FrameLen,
+	IN ULONG			UpdatePos)
+{
+	ULONG				CapInfoPos = 0;
+	UCHAR			*ptr, *ptr_update, *ptr_capinfo;
+	UINT			i;
+	BOOLEAN			bBcnReq = FALSE;
+	UCHAR			bcn_idx = 0;
+
+
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __func__));
+		return;
+	}
+
+	//if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
+	//	|| ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL)
+	//		|| !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
+	//	)
+	if (bBcnReq == FALSE)
+	{
+		/* when the ra interface is down, do not send its beacon frame */
+		/* clear all zero */
+		for(i=0; i<TXWI_SIZE; i+=4)
+			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
+	}
+	else
+	{
+		ptr = (PUCHAR)&pAd->BeaconTxWI;
+		for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
+		{
+			UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longptr);
+			ptr += 4;
+		}
+
+		// Update CapabilityInfo in Beacon
+		for (i = CapInfoPos; i < (CapInfoPos+2); i++)
+		{
+			RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo);
+			ptr_capinfo ++;
+		}
+
+		if (FrameLen > UpdatePos)
+		{
+			for (i= UpdatePos; i< (FrameLen); i++)
+			{
+				RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update);
+				ptr_update ++;
+			}
+		}
+
+	}
+
+}
+
+
+VOID RT28xxPciStaAsicForceWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN       bFromTx)
+{
+    AUTO_WAKEUP_STRUC	AutoWakeupCfg;
+
+    if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+        return;
+
+    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
+        return;
+    }
+
+    OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+
+#ifdef RTMP_PCI_SUPPORT
+    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+    {
+        // Support PCIe Advance Power Save
+	if (bFromTx == TRUE)
+	{
+            pAd->Mlme.bPsPollTimerRunning = FALSE;
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+		RTMPusecDelay(3000);
+            DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
+	}
+
+		AutoWakeupCfg.word = 0;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+        if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
+        {
+			{
+			// end johnli
+				// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
+				if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+					&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+				{
+					// Must using 40MHz.
+					AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+				}
+				else
+				{
+					// Must using 20MHz.
+					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+				}
+			}
+        }
+    }
+    else
+#endif // RTMP_PCI_SUPPORT //
+    {
+        // PCI, 2860-PCIe
+        AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+        AutoWakeupCfg.word = 0;
+	    RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+    }
+
+    OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+    OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+    DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n"));
+}
+
+
+VOID RT28xxPciStaAsicSleepThenAutoWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TbttNumToNextWakeUp)
+{
+	BOOLEAN brc;
+
+	if (pAd->StaCfg.bRadio == FALSE)
+	{
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+		return;
+	}
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+	{
+		ULONG	Now = 0;
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+			return;
+		}
+
+		NdisGetSystemUpTime(&Now);
+		// If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM.
+		// Because Some AP can't queuing outgoing frames immediately.
+		if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now) && (pAd->Mlme.LastSendNULLpsmTime <= Now))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu :  RxCountSinceLastNULL = %lu. \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL));
+			return;
+		}
+		else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0) && ((pAd->Mlme.LastSendNULLpsmTime + pAd->CommonCfg.BeaconPeriod) >= Now))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n", Now, pAd->Mlme.LastSendNULLpsmTime,  pAd->RalinkCounters.RxCountSinceLastNULL));
+			return;
+		}
+
+		brc = RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE, TbttNumToNextWakeUp);
+		if (brc==TRUE)
+			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+	}
+	else
+	{
+		AUTO_WAKEUP_STRUC	AutoWakeupCfg;
+		// we have decided to SLEEP, so at least do it for a BEACON period.
+		if (TbttNumToNextWakeUp == 0)
+			TbttNumToNextWakeUp = 1;
+
+		//RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+
+		AutoWakeupCfg.word = 0;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
+		AutoWakeupCfg.field.EnableAutoWakeup = 1;
+		AutoWakeupCfg.field.AutoLeadTime = 5;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00);   // send POWER-SAVE command to MCU. Timeout 40us.
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+		DBGPRINT(RT_DEBUG_TRACE, ("<-- %s, TbttNumToNextWakeUp=%d \n", __func__, TbttNumToNextWakeUp));
+	}
+
+}
+
+#ifdef RTMP_PCI_SUPPORT
+VOID PsPollWakeExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	unsigned long flags;
+
+    DBGPRINT(RT_DEBUG_TRACE,("-->PsPollWakeExec \n"));
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+    if (pAd->Mlme.bPsPollTimerRunning)
+    {
+	    RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+    }
+    pAd->Mlme.bPsPollTimerRunning = FALSE;
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+VOID  RadioOnExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+	WPDMA_GLO_CFG_STRUC	DmaCfg;
+	BOOLEAN				Cancelled;
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n"));
+		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+		return;
+	}
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n"));
+		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+		return;
+	}
+	pAd->Mlme.bPsPollTimerRunning = FALSE;
+	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+	if (pAd->StaCfg.bRadio == TRUE)
+	{
+		pAd->bPCIclkOff = FALSE;
+		RTMPRingCleanUp(pAd, QID_AC_BK);
+		RTMPRingCleanUp(pAd, QID_AC_BE);
+		RTMPRingCleanUp(pAd, QID_AC_VI);
+		RTMPRingCleanUp(pAd, QID_AC_VO);
+		RTMPRingCleanUp(pAd, QID_HCCA);
+		RTMPRingCleanUp(pAd, QID_MGMT);
+		RTMPRingCleanUp(pAd, QID_RX);
+
+		// 2. Send wake up command.
+		AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
+		// 2-1. wait command ok.
+		AsicCheckCommanOk(pAd, PowerWakeCID);
+
+		// When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt.
+		//RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT));
+		RTMP_ASIC_INTERRUPT_ENABLE(pAd);
+
+		// 3. Enable Tx DMA.
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
+		DmaCfg.field.EnableTxDMA = 1;
+		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
+
+		// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
+		if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+			&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+		{
+			// Must using 40MHz.
+			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+		}
+		else
+		{
+			// Must using 20MHz.
+			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+		}
+
+		if (pChipOps->AsicReverseRfFromSleepMode)
+			pChipOps->AsicReverseRfFromSleepMode(pAd);
+
+		// Clear Radio off flag
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+		// Set LED
+		RTMPSetLED(pAd, LED_RADIO_ON);
+
+        if (pAd->StaCfg.Psm == PWR_ACTIVE)
+        {
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
+        }
+	}
+	else
+	{
+		RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
+	}
+}
+#endif // RTMP_PCI_SUPPORT //
+
+
+/*
+	==========================================================================
+	Description:
+		This routine sends command to firmware and turn our chip to wake up mode from power save mode.
+		Both RadioOn and .11 power save function needs to call this routine.
+	Input:
+		Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On.  Need to restore PCI host value.
+		Level = other value : normal wake up function.
+
+	==========================================================================
+ */
+BOOLEAN RT28xxPciAsicRadioOn(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR     Level)
+{
+    //WPDMA_GLO_CFG_STRUC	DmaCfg;
+	BOOLEAN				Cancelled;
+    //UINT32			    MACValue;
+
+	if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE)
+		return FALSE;
+
+#ifdef RTMP_PCI_SUPPORT
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+	{
+	    pAd->Mlme.bPsPollTimerRunning = FALSE;
+		RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+		if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
+			// 1. Set PCI Link Control in Configuration Space.
+			RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+			RTMPusecDelay(6000);
+		}
+	}
+#endif // RTMP_PCI_SUPPORT //
+
+    pAd->bPCIclkOff = FALSE;
+	// 2. Send wake up command.
+	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
+    pAd->bPCIclkOff = FALSE;
+	// 2-1. wait command ok.
+	AsicCheckCommanOk(pAd, PowerWakeCID);
+	RTMP_ASIC_INTERRUPT_ENABLE(pAd);
+
+
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+	if (Level == GUI_IDLE_POWER_SAVE)
+	{
+			{
+			// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
+				{
+				if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+					&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+				{
+					// Must using 40MHz.
+					AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+				}
+				else
+				{
+					// Must using 20MHz.
+					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+				}
+				}
+
+			}
+	}
+        return TRUE;
+
+}
+