Prechádzať zdrojové kódy

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>
Bartlomiej Zolnierkiewicz 15 rokov pred
rodič
commit
ca97b83888
100 zmenil súbory, kde vykonal 29352 pridanie a 21393 odobranie
  1. 0 1319
      drivers/staging/rt2860/2860_main_dev.c
  2. 18 8
      drivers/staging/rt2860/Makefile
  3. 0 210
      drivers/staging/rt2860/aironet.h
  4. 7 5
      drivers/staging/rt2860/ap.h
  5. 365 0
      drivers/staging/rt2860/chip/mac_pci.h
  6. 365 0
      drivers/staging/rt2860/chip/mac_usb.h
  7. 56 0
      drivers/staging/rt2860/chip/rt2860.h
  8. 47 0
      drivers/staging/rt2860/chip/rt2870.h
  9. 68 0
      drivers/staging/rt2860/chip/rt3070.h
  10. 48 0
      drivers/staging/rt2860/chip/rt30xx.h
  11. 200 411
      drivers/staging/rt2860/chip/rtmp_mac.h
  12. 405 0
      drivers/staging/rt2860/chip/rtmp_phy.h
  13. 185 0
      drivers/staging/rt2860/chips/rt3070.c
  14. 525 0
      drivers/staging/rt2860/chips/rt30xx.c
  15. 53 1170
      drivers/staging/rt2860/chlist.h
  16. 0 897
      drivers/staging/rt2860/common/2860_rtmp_init.c
  17. 9 3
      drivers/staging/rt2860/common/action.c
  18. 64 83
      drivers/staging/rt2860/common/ba_action.c
  19. 543 572
      drivers/staging/rt2860/common/cmm_aes.c
  20. 2531 0
      drivers/staging/rt2860/common/cmm_asic.c
  21. 290 0
      drivers/staging/rt2860/common/cmm_cfg.c
  22. 160 652
      drivers/staging/rt2860/common/cmm_data.c
  23. 1153 0
      drivers/staging/rt2860/common/cmm_data_pci.c
  24. 144 112
      drivers/staging/rt2860/common/cmm_data_usb.c
  25. 358 214
      drivers/staging/rt2860/common/cmm_info.c
  26. 1504 0
      drivers/staging/rt2860/common/cmm_mac_pci.c
  27. 1216 0
      drivers/staging/rt2860/common/cmm_mac_usb.c
  28. 1736 0
      drivers/staging/rt2860/common/cmm_profile.c
  29. 222 11
      drivers/staging/rt2860/common/cmm_sanity.c
  30. 47 23
      drivers/staging/rt2860/common/cmm_sync.c
  31. 8 712
      drivers/staging/rt2860/common/cmm_tkip.c
  32. 12 10
      drivers/staging/rt2860/common/cmm_wep.c
  33. 2487 349
      drivers/staging/rt2860/common/cmm_wpa.c
  34. 194 0
      drivers/staging/rt2860/common/crypt_hmac.c
  35. 352 0
      drivers/staging/rt2860/common/crypt_md5.c
  36. 535 0
      drivers/staging/rt2860/common/crypt_sha2.c
  37. 42 24
      drivers/staging/rt2860/common/dfs.c
  38. 1525 0
      drivers/staging/rt2860/common/ee_efuse.c
  39. 270 0
      drivers/staging/rt2860/common/ee_prom.c
  40. 42 1418
      drivers/staging/rt2860/common/eeprom.c
  41. 1 1
      drivers/staging/rt2860/common/firmware.h
  42. 517 0
      drivers/staging/rt2860/common/firmware_3070.h
  43. 475 344
      drivers/staging/rt2860/common/mlme.c
  44. 1280 0
      drivers/staging/rt2860/common/rt_channel.c
  45. 194 0
      drivers/staging/rt2860/common/rt_rf.c
  46. 101 687
      drivers/staging/rt2860/common/rtmp_init.c
  47. 233 0
      drivers/staging/rt2860/common/rtmp_mcu.c
  48. 323 0
      drivers/staging/rt2860/common/rtmp_timer.c
  49. 397 63
      drivers/staging/rt2860/common/spectrum.c
  50. 0 241
      drivers/staging/rt2860/config.mk
  51. 82 0
      drivers/staging/rt2860/crypt_hmac.h
  52. 80 0
      drivers/staging/rt2860/crypt_md5.h
  53. 109 0
      drivers/staging/rt2860/crypt_sha2.h
  54. 30 2
      drivers/staging/rt2860/dfs.h
  55. 93 0
      drivers/staging/rt2860/eeprom.h
  56. 83 0
      drivers/staging/rt2860/iface/rtmp_pci.h
  57. 200 0
      drivers/staging/rt2860/iface/rtmp_usb.h
  58. 0 107
      drivers/staging/rt2860/md5.h
  59. 13 76
      drivers/staging/rt2860/mlme.h
  60. 93 42
      drivers/staging/rt2860/oid.h
  61. 873 0
      drivers/staging/rt2860/pci_main_dev.c
  62. 0 333
      drivers/staging/rt2860/rt2860.h
  63. 20 12
      drivers/staging/rt2860/rt_config.h
  64. 555 60
      drivers/staging/rt2860/rt_linux.c
  65. 456 354
      drivers/staging/rt2860/rt_linux.h
  66. 236 514
      drivers/staging/rt2860/rt_main_dev.c
  67. 877 0
      drivers/staging/rt2860/rt_pci_rbus.c
  68. 36 1803
      drivers/staging/rt2860/rt_profile.c
  69. 828 0
      drivers/staging/rt2860/rt_usb.c
  70. 122 704
      drivers/staging/rt2860/rtmp.h
  71. 265 0
      drivers/staging/rt2860/rtmp_chip.h
  72. 144 145
      drivers/staging/rt2860/rtmp_def.h
  73. 102 0
      drivers/staging/rt2860/rtmp_dot11.h
  74. 84 0
      drivers/staging/rt2860/rtmp_iface.h
  75. 55 0
      drivers/staging/rt2860/rtmp_mcu.h
  76. 98 0
      drivers/staging/rt2860/rtmp_os.h
  77. 156 0
      drivers/staging/rt2860/rtmp_timer.h
  78. 54 1
      drivers/staging/rt2860/rtmp_type.h
  79. 189 0
      drivers/staging/rt2860/rtusb_io.h
  80. 56 113
      drivers/staging/rt2860/spectrum.h
  81. 139 9
      drivers/staging/rt2860/spectrum_def.h
  82. 0 1312
      drivers/staging/rt2860/sta/aironet.c
  83. 58 269
      drivers/staging/rt2860/sta/assoc.c
  84. 84 54
      drivers/staging/rt2860/sta/auth.c
  85. 10 6
      drivers/staging/rt2860/sta/auth_rsp.c
  86. 227 259
      drivers/staging/rt2860/sta/connect.c
  87. 145 112
      drivers/staging/rt2860/sta/rtmp_data.c
  88. 2 42
      drivers/staging/rt2860/sta/sanity.c
  89. 106 292
      drivers/staging/rt2860/sta/sync.c
  90. 1 1807
      drivers/staging/rt2860/sta/wpa.c
  91. 258 155
      drivers/staging/rt2860/sta_ioctl.c
  92. 897 0
      drivers/staging/rt2860/usb_main_dev.c
  93. 102 2
      drivers/staging/rt2860/wpa.h
  94. 0 1530
      drivers/staging/rt2870/2870_main_dev.c
  95. 23 9
      drivers/staging/rt2870/Makefile
  96. 1 0
      drivers/staging/rt2870/chips/rt3070.c
  97. 1 0
      drivers/staging/rt2870/chips/rt30xx.c
  98. 0 1730
      drivers/staging/rt2870/common/2870_rtmp_init.c
  99. 1 0
      drivers/staging/rt2870/common/acction.c
  100. 1 0
      drivers/staging/rt2870/common/cmm_aes.c

+ 0 - 1319
drivers/staging/rt2860/2860_main_dev.c

@@ -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);
-
-}
-

+ 18 - 8
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

+ 0 - 210
drivers/staging/rt2860/aironet.h

@@ -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__

+ 7 - 5
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);
 

+ 365 - 0
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__ //

+ 365 - 0
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__ //

+ 56 - 0
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__ //

+ 47 - 0
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__ //

+ 68 - 0
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__ //

+ 48 - 0
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__ //

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 200 - 411
drivers/staging/rt2860/chip/rtmp_mac.h


+ 405 - 0
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__ //

+ 185 - 0
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 //

+ 525 - 0
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 //

+ 53 - 1170
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__
 

+ 0 - 897
drivers/staging/rt2860/common/2860_rtmp_init.c

@@ -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 */
-

+ 9 - 3
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);
 		}
 	}

+ 64 - 83
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);

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 543 - 572
drivers/staging/rt2860/common/cmm_aes.c


+ 2531 - 0
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));
+}

+ 290 - 0
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;
+}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 160 - 652
drivers/staging/rt2860/common/cmm_data.c


+ 1153 - 0
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;
+}

+ 144 - 112
drivers/staging/rt2870/common/cmm_data_2870.c → drivers/staging/rt2860/common/cmm_data_usb.c

@@ -24,12 +24,17 @@
  *                                                                       *
  *************************************************************************
 */
+
 /*
    All functions in this file must be USB-depended, or you should out your function
 	in other files.
 
 */
-#include "../rt_config.h"
+
+#ifdef RTMP_MAC_USB
+
+
+#include	"../rt_config.h"
 
 
 /*
@@ -41,7 +46,7 @@
 static inline NDIS_STATUS RtmpUSBCanDoWrite(
 	IN RTMP_ADAPTER		*pAd,
 	IN UCHAR			QueIdx,
-	IN HT_TX_CONTEXT 	*pHTTXContext)
+	IN HT_TX_CONTEXT	*pHTTXContext)
 {
 	NDIS_STATUS	canWrite = NDIS_STATUS_RESOURCES;
 
@@ -292,7 +297,6 @@ USHORT RtmpUSB_WriteSingleTxResource(
 		pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
 
 		// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
-		//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
 		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
 
 		if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
@@ -583,11 +587,11 @@ VOID RtmpUSBDataKickOut(
 	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 RTMP_ADAPTER		*pAd,
+	IN UCHAR			QueIdx,
 	IN PNDIS_PACKET		pPacket,
 	IN PUCHAR			pSrcBufVA,
-	IN UINT 			SrcBufLen)
+	IN UINT				SrcBufLen)
 {
 	PTXINFO_STRUC	pTxInfo;
 	ULONG			BulkOutSize;
@@ -679,6 +683,7 @@ VOID RtmpUSBNullFrameKickOut(
 		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;
 
@@ -693,6 +698,109 @@ VOID RtmpUSBNullFrameKickOut(
 
 }
 
+
+/*
+========================================================================
+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;
+}
+
+
 /*
 	========================================================================
 
@@ -775,6 +883,11 @@ NDIS_STATUS	RTMPCheckRxError(
 	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
 		//
@@ -801,14 +914,32 @@ NDIS_STATUS	RTMPCheckRxError(
 	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)
 {
-    AUTO_WAKEUP_STRUC	AutoWakeupCfg;
+	BOOLEAN	Canceled;
 
-	AutoWakeupCfg.word = 0;
-	RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+	if (pAd->Mlme.AutoWakeupTimerRunning)
+		RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled);
 
 	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
 
@@ -819,19 +950,14 @@ VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
 	IN PRTMP_ADAPTER pAd,
 	IN USHORT TbttNumToNextWakeUp)
 {
-	AUTO_WAKEUP_STRUC	AutoWakeupCfg;
+
 
 	// we have decided to SLEEP, so at least do it for a BEACON period.
 	if (TbttNumToNextWakeUp == 0)
 		TbttNumToNextWakeUp = 1;
 
-	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);
+	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.
 
@@ -839,98 +965,4 @@ VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
 
 }
 
-VOID RT28xxUsbMlmeRadioOn(
-	IN PRTMP_ADAPTER pAd)
-{
-    DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
-
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-    	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-		RTMPusecDelay(10000);
-
-	NICResetFromError(pAd);
-
-	// Enable Tx/Rx
-	RTMPEnableRxTx(pAd);
-
-#ifdef RT3070
-	if (IS_RT3071(pAd))
-	{
-		RT30xxReverseRFSleepModeSetup(pAd);
-	}
-#endif // RT3070 //
-
-	// Clear Radio off flag
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-	RTUSBBulkReceive(pAd);
-
-	// Set LED
-	RTMPSetLED(pAd, LED_RADIO_ON);
-}
-
-VOID RT28xxUsbMlmeRadioOFF(
-	IN PRTMP_ADAPTER pAd)
-{
-	WPDMA_GLO_CFG_STRUC	GloCfg;
-	UINT32	Value, i;
-
-	DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-	// Set LED
-	RTMPSetLED(pAd, LED_RADIO_OFF);
-	// Set Radio off flag
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-	{
-		// Link down first if any association exists
-		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
-			LinkDown(pAd, FALSE);
-		RTMPusecDelay(10000);
-
-		//==========================================
-		// Clean up old bss table
-		BssTableInit(&pAd->ScanTab);
-	}
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
-	{
-		// Must using 40MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
-	}
-	else
-	{
-		// Must using 20MHz.
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
-	}
-
-	// Disable Tx/Rx DMA
-	RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word);	   // disable DMA
-	GloCfg.field.EnableTxDMA = 0;
-	GloCfg.field.EnableRxDMA = 0;
-	RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word);	   // abort all TX rings
-
-	// Waiting for DMA idle
-	i = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		RTMPusecDelay(1000);
-	}while (i++ < 100);
-
-	// Disable MAC Tx/Rx
-	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-	Value &= (0xfffffff3);
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-	AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
-}
-
+#endif // RTMP_MAC_USB //

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 358 - 214
drivers/staging/rt2860/common/cmm_info.c


+ 1504 - 0
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;
+
+}
+
+
+/*
+	==========================================================================
+	Description:
+		This routine sends command to firmware and turn our chip to power save mode.
+		Both RadioOff and .11 power save function needs to call this routine.
+	Input:
+		Level = GUIRADIO_OFF  : GUI Radio Off mode
+		Level = DOT11POWERSAVE  : 802.11 power save mode
+		Level = RTMP_HALT  : When Disable device.
+
+	==========================================================================
+ */
+BOOLEAN RT28xxPciAsicRadioOff(
+	IN PRTMP_ADAPTER    pAd,
+	IN UCHAR            Level,
+	IN USHORT           TbttNumToNextWakeUp)
+{
+	WPDMA_GLO_CFG_STRUC	DmaCfg;
+	UCHAR		i, tempBBP_R3 = 0;
+	BOOLEAN		brc = FALSE, Cancelled;
+    UINT32		TbTTTime = 0;
+	UINT32		PsPollTime = 0/*, MACValue*/;
+    ULONG		BeaconPeriodTime;
+    UINT32		RxDmaIdx, RxCpuIdx;
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> Lv= %d, TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n", Level,pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx, pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx));
+
+	if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE)
+		return FALSE;
+
+    // Check Rx DMA busy status, if more than half is occupied, give up this radio off.
+	RTMP_IO_READ32(pAd, RX_DRX_IDX , &RxDmaIdx);
+	RTMP_IO_READ32(pAd, RX_CRX_IDX , &RxCpuIdx);
+	if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE/3))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return1. RxDmaIdx = %d ,  RxCpuIdx = %d. \n", RxDmaIdx, RxCpuIdx));
+		return FALSE;
+	}
+	else if ((RxCpuIdx >= RxDmaIdx) && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE/3))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return2.  RxCpuIdx = %d. RxDmaIdx = %d ,  \n", RxCpuIdx, RxDmaIdx));
+		return FALSE;
+	}
+
+    // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops.
+	pAd->bPCIclkOffDisableTx = TRUE;
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE) && pAd->OpMode == OPMODE_STA)
+	{
+		printk("==>fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE\n");
+	    RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
+	    RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+
+	    if (Level == DOT11POWERSAVE)
+		{
+			RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime);
+			TbTTTime &= 0x1ffff;
+			// 00. check if need to do sleep in this DTIM period.   If next beacon will arrive within 30ms , ...doesn't necessarily sleep.
+			// TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms
+	        if  (((64*TbTTTime) <((LEAD_TIME*1024) + 40000)) && (TbttNumToNextWakeUp == 0))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime));
+	            OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+	            pAd->bPCIclkOffDisableTx = FALSE;
+				return FALSE;
+			}
+			else
+			{
+				PsPollTime = (64*TbTTTime- LEAD_TIME*1024)/1000;
+				PsPollTime -= 3;
+
+	            BeaconPeriodTime = pAd->CommonCfg.BeaconPeriod*102/100;
+				if (TbttNumToNextWakeUp > 0)
+					PsPollTime += ((TbttNumToNextWakeUp -1) * BeaconPeriodTime);
+
+	            pAd->Mlme.bPsPollTimerRunning = TRUE;
+				RTMPSetTimer(&pAd->Mlme.PsPollTimer, PsPollTime);
+			}
+		}
+	}
+
+    RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+
+    // Set to 1R.
+	if (pAd->Antenna.field.RxPath > 1 && pAd->OpMode == OPMODE_STA)
+	{
+	tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
+	}
+
+	// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
+	if ((INFRA_ON(pAd) || pAd->OpMode == OPMODE_AP) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+		&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+	{
+		// Must using 40MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+	}
+	else
+	{
+		// Must using 20MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+	}
+
+	if (Level != RTMP_HALT)
+	{
+		// Change Interrupt bitmask.
+    // When PCI clock is off, don't want to service interrupt.
+	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+	}
+	else
+	{
+		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
+	}
+
+
+	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+	//  2. Send Sleep command
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
+	// send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power
+	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
+	//  2-1. Wait command success
+	// Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task.
+	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
+
+	//  3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe.
+	// If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem.
+	if ((Level == DOT11POWERSAVE) && (brc == TRUE))
+	{
+		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00);	// lowbyte = 0 means to do power safe, NOT turn off radio.
+		//  3-1. Wait command success
+		AsicCheckCommanOk(pAd, PowerRadioOffCID);
+	}
+	else if (brc == TRUE)
+	{
+		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00);	// lowbyte = 0 means to do power safe, NOT turn off radio.
+		//  3-1. Wait command success
+		AsicCheckCommanOk(pAd, PowerRadioOffCID);
+	}
+
+	// 1. Wait DMA not busy
+	i = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
+		if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0))
+			break;
+		RTMPusecDelay(20);
+		i++;
+	}while(i < 50);
+
+	/*
+	if (i >= 50)
+	{
+		pAd->CheckDmaBusyCount++;
+		DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy.  return on AsicRadioOff () CheckDmaBusyCount = %d \n", pAd->CheckDmaBusyCount));
+	}
+	else
+	{
+		pAd->CheckDmaBusyCount = 0;
+	}
+	*/
+
+	if (Level == DOT11POWERSAVE)
+	{
+		AUTO_WAKEUP_STRUC	AutoWakeupCfg;
+		//RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90);
+
+		// we have decided to SLEEP, so at least do it for a BEACON period.
+		if (TbttNumToNextWakeUp == 0)
+			TbttNumToNextWakeUp = 1;
+
+		AutoWakeupCfg.word = 0;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+		// 1. Set auto wake up timer.
+		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
+		AutoWakeupCfg.field.EnableAutoWakeup = 1;
+		AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+	}
+
+#ifdef RTMP_PCI_SUPPORT
+	//  4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value.
+	if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA)
+	{
+		if ((brc == TRUE) && (i < 50))
+			RTMPPCIeLinkCtrlSetting(pAd, 1);
+	}
+	//  4. Set PCI configuration Space Link Comtrol fields.  Only Radio Off needs to call this function
+	else if (pAd->OpMode == OPMODE_STA)
+	{
+		if ((brc == TRUE) && (i < 50))
+			RTMPPCIeLinkCtrlSetting(pAd, 3);
+	}
+#endif // RTMP_PCI_SUPPORT //
+
+    pAd->bPCIclkOffDisableTx = FALSE;
+	return TRUE;
+}
+
+
+
+
+VOID RT28xxPciMlmeRadioOn(
+	IN PRTMP_ADAPTER pAd)
+{
+    if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+    DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__));
+
+    if ((pAd->OpMode == OPMODE_AP) ||
+        ((pAd->OpMode == OPMODE_STA) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))))
+    {
+	if (pAd->OpMode == OPMODE_AP)
+			RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+
+		//NICResetFromError(pAd);
+
+	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);
+
+		if (pAd->OpMode == OPMODE_STA)
+		{
+			AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+			RTMPusecDelay(10000);
+		}
+
+	// Enable Tx/Rx
+	RTMPEnableRxTx(pAd);
+
+	// Clear Radio off flag
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+	    // Set LED
+	    RTMPSetLED(pAd, LED_RADIO_ON);
+    }
+
+#ifdef RTMP_PCI_SUPPORT
+    if ((pAd->OpMode == OPMODE_STA) &&
+        (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)))
+    {
+        BOOLEAN		Cancelled;
+
+	RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+
+        pAd->Mlme.bPsPollTimerRunning = FALSE;
+	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+	RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
+	RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+    }
+#endif // RTMP_PCI_SUPPORT //
+}
+
+
+VOID RT28xxPciMlmeRadioOFF(
+	IN PRTMP_ADAPTER pAd)
+{
+	BOOLEAN brc=TRUE;
+
+    if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+	return;
+
+	// Link down first if any association exists
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+	{
+		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+		{
+			MLME_DISASSOC_REQ_STRUCT DisReq;
+			MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+			if (pMsgElem)
+			{
+				COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid);
+				DisReq.Reason =  REASON_DISASSOC_STA_LEAVING;
+
+				pMsgElem->Machine = ASSOC_STATE_MACHINE;
+				pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+				pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+				NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+				MlmeDisassocReqAction(pAd, pMsgElem);
+				kfree(pMsgElem);
+
+				RTMPusecDelay(1000);
+			}
+		}
+	}
+
+    DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__));
+
+	// Set Radio off flag
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+    {
+	BOOLEAN		Cancelled;
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+	{
+			RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+	}
+
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+        {
+            BOOLEAN Cancelled;
+            pAd->Mlme.bPsPollTimerRunning = FALSE;
+            RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+	        RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
+        }
+
+        // Link down first if any association exists
+        if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+            LinkDown(pAd, FALSE);
+        RTMPusecDelay(10000);
+        //==========================================
+        // Clean up old bss table
+        BssTableInit(&pAd->ScanTab);
+
+        if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+        {
+            RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+            return;
+        }
+    }
+
+	// Set LED
+	RTMPSetLED(pAd, LED_RADIO_OFF);
+
+	if (pAd->OpMode == OPMODE_AP)
+		brc=RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
+
+	if (brc==FALSE)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __func__));
+	}
+
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE) &&
+		(pAd->OpMode == OPMODE_STA))
+		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
+}
+
+#endif // RTMP_MAC_PCI //

+ 1216 - 0
drivers/staging/rt2860/common/cmm_mac_usb.c

@@ -0,0 +1,1216 @@
+/*
+ *************************************************************************
+ * 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_USB
+
+
+#include	"../rt_config.h"
+
+
+/*
+========================================================================
+Routine Description:
+    Initialize receive data structures.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_RESOURCES
+
+Note:
+	Initialize all receive releated private buffer, include those define
+	in RTMP_ADAPTER structure and all private data structures. The mahor
+	work is to allocate buffer for each packet and chain buffer to
+	NDIS packet descriptor.
+========================================================================
+*/
+NDIS_STATUS	NICInitRecv(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	UCHAR				i;
+	NDIS_STATUS			Status = NDIS_STATUS_SUCCESS;
+	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
+	pObj = pObj;
+
+	//InterlockedExchange(&pAd->PendingRx, 0);
+	pAd->PendingRx = 0;
+	pAd->NextRxBulkInReadIndex	= 0;	// Next Rx Read index
+	pAd->NextRxBulkInIndex		= 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
+	pAd->NextRxBulkInPosition	= 0;
+
+	for (i = 0; i < (RX_RING_SIZE); i++)
+	{
+		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+
+		//Allocate URB
+		pRxContext->pUrb = RTUSB_ALLOC_URB(0);
+		if (pRxContext->pUrb == NULL)
+		{
+			Status = NDIS_STATUS_RESOURCES;
+			goto out1;
+		}
+
+		// Allocate transfer buffer
+		pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
+		if (pRxContext->TransferBuffer == NULL)
+		{
+			Status = NDIS_STATUS_RESOURCES;
+			goto out1;
+		}
+
+		NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
+
+		pRxContext->pAd	= pAd;
+		pRxContext->pIrp = NULL;
+		pRxContext->InUse		= FALSE;
+		pRxContext->IRPPending	= FALSE;
+		pRxContext->Readable	= FALSE;
+		//pRxContext->ReorderInUse = FALSE;
+		pRxContext->bRxHandling = FALSE;
+		pRxContext->BulkInOffset = 0;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
+	return Status;
+
+out1:
+	for (i = 0; i < (RX_RING_SIZE); i++)
+	{
+		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+
+		if (NULL != pRxContext->TransferBuffer)
+		{
+			RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
+								pRxContext->TransferBuffer, pRxContext->data_dma);
+			pRxContext->TransferBuffer = NULL;
+		}
+
+		if (NULL != pRxContext->pUrb)
+		{
+			RTUSB_UNLINK_URB(pRxContext->pUrb);
+			RTUSB_FREE_URB(pRxContext->pUrb);
+			pRxContext->pUrb = NULL;
+		}
+	}
+
+	return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Initialize transmit data structures.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS	NICInitTransmit(
+	IN	PRTMP_ADAPTER	pAd)
+{
+#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2)	\
+	Context->pUrb = RTUSB_ALLOC_URB(0);		\
+	if (Context->pUrb == NULL) {			\
+		DBGPRINT(RT_DEBUG_ERROR, msg1);		\
+		Status = NDIS_STATUS_RESOURCES;		\
+		goto err1; }						\
+											\
+	Context->TransferBuffer =				\
+		(TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma);	\
+	if (Context->TransferBuffer == NULL) {	\
+		DBGPRINT(RT_DEBUG_ERROR, msg2);		\
+		Status = NDIS_STATUS_RESOURCES;		\
+		goto err2; }
+
+#define LM_URB_FREE(pObj, Context, BufferSize)				\
+	if (NULL != Context->pUrb) {							\
+		RTUSB_UNLINK_URB(Context->pUrb);					\
+		RTUSB_FREE_URB(Context->pUrb);						\
+		Context->pUrb = NULL; }								\
+	if (NULL != Context->TransferBuffer) {				\
+		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
+								Context->TransferBuffer,	\
+								Context->data_dma);			\
+		Context->TransferBuffer = NULL; }
+
+	UCHAR			i, acidx;
+	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
+	PTX_CONTEXT		pNullContext   = &(pAd->NullContext);
+	PTX_CONTEXT		pPsPollContext = &(pAd->PsPollContext);
+	PTX_CONTEXT		pRTSContext    = &(pAd->RTSContext);
+	PTX_CONTEXT		pMLMEContext = NULL;
+//	PHT_TX_CONTEXT	pHTTXContext = NULL;
+	POS_COOKIE		pObj = (POS_COOKIE) pAd->OS_Cookie;
+	PVOID			RingBaseVa;
+//	RTMP_TX_RING	*pTxRing;
+	RTMP_MGMT_RING  *pMgmtRing;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
+	pObj = pObj;
+
+	// Init 4 set of Tx parameters
+	for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
+	{
+		// Initialize all Transmit releated queues
+		InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
+
+		// Next Local tx ring pointer waiting for buck out
+		pAd->NextBulkOutIndex[acidx] = acidx;
+		pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
+		//pAd->DataBulkDoneIdx[acidx] = 0;
+	}
+
+	//pAd->NextMLMEIndex	= 0;
+	//pAd->PushMgmtIndex	= 0;
+	//pAd->PopMgmtIndex	= 0;
+	//InterlockedExchange(&pAd->MgmtQueueSize, 0);
+	//InterlockedExchange(&pAd->TxCount, 0);
+
+	//pAd->PrioRingFirstIndex	= 0;
+	//pAd->PrioRingTxCnt		= 0;
+
+	do
+	{
+		//
+		// TX_RING_SIZE, 4 ACs
+		//
+		for(acidx=0; acidx<4; acidx++)
+		{
+			PHT_TX_CONTEXT	pHTTXContext = &(pAd->TxContext[acidx]);
+
+			NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
+			//Allocate URB
+			LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
+							("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
+							done,
+							("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
+							out1);
+
+			NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
+			pHTTXContext->pAd = pAd;
+			pHTTXContext->pIrp = NULL;
+			pHTTXContext->IRPPending = FALSE;
+			pHTTXContext->NextBulkOutPosition = 0;
+			pHTTXContext->ENextBulkOutPosition = 0;
+			pHTTXContext->CurWritePosition = 0;
+			pHTTXContext->CurWriteRealPos = 0;
+			pHTTXContext->BulkOutSize = 0;
+			pHTTXContext->BulkOutPipeId = acidx;
+			pHTTXContext->bRingEmpty = TRUE;
+			pHTTXContext->bCopySavePad = FALSE;
+			pAd->BulkOutPending[acidx] = FALSE;
+		}
+
+
+		//
+		// MGMT_RING_SIZE
+		//
+
+		// Allocate MGMT ring descriptor's memory
+		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
+		os_alloc_mem(pAd, (PUCHAR *)(&pAd->MgmtDescRing.AllocVa), pAd->MgmtDescRing.AllocSize);
+		if (pAd->MgmtDescRing.AllocVa == NULL)
+		{
+			DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
+			Status = NDIS_STATUS_RESOURCES;
+			goto out1;
+		}
+		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
+		RingBaseVa     = pAd->MgmtDescRing.AllocVa;
+
+		// Initialize MGMT Ring and associated buffer memory
+		pMgmtRing = &pAd->MgmtRing;
+		for (i = 0; i < MGMT_RING_SIZE; i++)
+		{
+			// link the pre-allocated Mgmt buffer to MgmtRing.Cell
+			pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
+			pMgmtRing->Cell[i].AllocVa = RingBaseVa;
+			pMgmtRing->Cell[i].pNdisPacket = NULL;
+			pMgmtRing->Cell[i].pNextNdisPacket = NULL;
+
+			//Allocate URB for MLMEContext
+			pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
+			pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
+			if (pMLMEContext->pUrb == NULL)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
+				Status = NDIS_STATUS_RESOURCES;
+				goto out2;
+			}
+			pMLMEContext->pAd = pAd;
+			pMLMEContext->pIrp = NULL;
+			pMLMEContext->TransferBuffer = NULL;
+			pMLMEContext->InUse = FALSE;
+			pMLMEContext->IRPPending = FALSE;
+			pMLMEContext->bWaitingBulkOut = FALSE;
+			pMLMEContext->BulkOutSize = 0;
+			pMLMEContext->SelfIdx = i;
+
+			// Offset to next ring descriptor address
+			RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
+
+		//pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
+		pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
+		pAd->MgmtRing.TxCpuIdx = 0;
+		pAd->MgmtRing.TxDmaIdx = 0;
+
+		//
+		// BEACON_RING_SIZE
+		//
+		for(i=0; i<BEACON_RING_SIZE; i++) // 2
+		{
+			PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
+
+
+			NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
+
+			//Allocate URB
+			LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+							("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
+							out2,
+							("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
+							out3);
+
+			pBeaconContext->pAd = pAd;
+			pBeaconContext->pIrp = NULL;
+			pBeaconContext->InUse = FALSE;
+			pBeaconContext->IRPPending = FALSE;
+		}
+
+		//
+		// NullContext
+		//
+		NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
+
+		//Allocate URB
+		LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+						("<-- ERROR in Alloc TX NullContext urb!! \n"),
+						out3,
+						("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
+						out4);
+
+		pNullContext->pAd = pAd;
+		pNullContext->pIrp = NULL;
+		pNullContext->InUse = FALSE;
+		pNullContext->IRPPending = FALSE;
+
+		//
+		// RTSContext
+		//
+		NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
+
+		//Allocate URB
+		LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+						("<-- ERROR in Alloc TX RTSContext urb!! \n"),
+						out4,
+						("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
+						out5);
+
+		pRTSContext->pAd = pAd;
+		pRTSContext->pIrp = NULL;
+		pRTSContext->InUse = FALSE;
+		pRTSContext->IRPPending = FALSE;
+
+		//
+		// PsPollContext
+		//
+		//NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
+		//Allocate URB
+		LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+						("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
+						out5,
+						("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
+						out6);
+
+		pPsPollContext->pAd = pAd;
+		pPsPollContext->pIrp = NULL;
+		pPsPollContext->InUse = FALSE;
+		pPsPollContext->IRPPending = FALSE;
+		pPsPollContext->bAggregatible = FALSE;
+		pPsPollContext->LastOne = TRUE;
+
+	}   while (FALSE);
+
+
+done:
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
+
+	return Status;
+
+	/* --------------------------- ERROR HANDLE --------------------------- */
+out6:
+	LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
+
+out5:
+	LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
+
+out4:
+	LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
+
+out3:
+	for(i=0; i<BEACON_RING_SIZE; i++)
+	{
+		PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
+		if (pBeaconContext)
+			LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
+	}
+
+out2:
+	if (pAd->MgmtDescRing.AllocVa)
+	{
+		pMgmtRing = &pAd->MgmtRing;
+		for(i=0; i<MGMT_RING_SIZE; i++)
+		{
+			pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
+			if (pMLMEContext)
+				LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
+		}
+		os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
+		pAd->MgmtDescRing.AllocVa = NULL;
+	}
+
+out1:
+	for (acidx = 0; acidx < 4; acidx++)
+	{
+		PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
+		if (pTxContext)
+			LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
+	}
+
+	// Here we didn't have any pre-allocated memory need to free.
+
+	return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Allocate DMA memory blocks for send, receive.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_FAILURE
+	NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS	RTMPAllocTxRxRingMemory(
+	IN	PRTMP_ADAPTER	pAd)
+{
+//	COUNTER_802_11	pCounter = &pAd->WlanCounters;
+	NDIS_STATUS		Status;
+	INT				num;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
+
+
+	do
+	{
+		// Init the CmdQ and CmdQLock
+		NdisAllocateSpinLock(&pAd->CmdQLock);
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		RTUSBInitializeCmdQ(&pAd->CmdQ);
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+
+
+		NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
+		//NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
+		NdisAllocateSpinLock(&pAd->BulkInLock);
+
+		for (num = 0; num < NUM_OF_TX_RING; num++)
+		{
+			NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
+		}
+
+
+//		NdisAllocateSpinLock(&pAd->MemLock);	// Not used in RT28XX
+
+//		NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
+//		NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
+
+//		for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
+//		{
+//			NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
+//		}
+
+		//
+		// Init Mac Table
+		//
+//		MacTableInitialize(pAd);
+
+		//
+		// Init send data structures and related parameters
+		//
+		Status = NICInitTransmit(pAd);
+		if (Status != NDIS_STATUS_SUCCESS)
+			break;
+
+		//
+		// Init receive data structures and related parameters
+		//
+		Status = NICInitRecv(pAd);
+		if (Status != NDIS_STATUS_SUCCESS)
+			break;
+
+		pAd->PendingIoCount = 1;
+
+	} 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;
+	}
+
+	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
+	return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+	Calls USB_InterfaceStop and frees memory allocated for the URBs
+    calls NdisMDeregisterDevice and frees the memory
+    allocated in VNetInitialize for the Adapter Object
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID	RTMPFreeTxRxRingMemory(
+	IN	PRTMP_ADAPTER	pAd)
+{
+#define LM_URB_FREE(pObj, Context, BufferSize)				\
+	if (NULL != Context->pUrb) {							\
+		RTUSB_UNLINK_URB(Context->pUrb);					\
+		RTUSB_FREE_URB(Context->pUrb);						\
+		Context->pUrb = NULL; }								\
+	if (NULL != Context->TransferBuffer) {					\
+		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
+								Context->TransferBuffer,	\
+								Context->data_dma);			\
+		Context->TransferBuffer = NULL; }
+
+
+	UINT                i, acidx;
+	PTX_CONTEXT			pNullContext   = &pAd->NullContext;
+	PTX_CONTEXT			pPsPollContext = &pAd->PsPollContext;
+	PTX_CONTEXT			pRTSContext    = &pAd->RTSContext;
+//	PHT_TX_CONTEXT		pHTTXContext;
+	//PRTMP_REORDERBUF	pReorderBuf;
+	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
+//	RTMP_TX_RING		*pTxRing;
+
+	DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
+	pObj = pObj;
+
+	// Free all resources for the RECEIVE buffer queue.
+	for(i=0; i<(RX_RING_SIZE); i++)
+	{
+		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+		if (pRxContext)
+			LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
+	}
+
+	// Free PsPoll frame resource
+	LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
+
+	// Free NULL frame resource
+	LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
+
+	// Free RTS frame resource
+	LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
+
+
+	// Free beacon frame resource
+	for(i=0; i<BEACON_RING_SIZE; i++)
+	{
+		PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
+		if (pBeaconContext)
+			LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
+	}
+
+
+	// Free mgmt frame resource
+	for(i = 0; i < MGMT_RING_SIZE; i++)
+	{
+		PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
+		//LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
+		if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
+		{
+			RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
+			pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
+			pMLMEContext->TransferBuffer = NULL;
+		}
+
+		if (pMLMEContext)
+		{
+			if (NULL != pMLMEContext->pUrb)
+			{
+				RTUSB_UNLINK_URB(pMLMEContext->pUrb);
+				RTUSB_FREE_URB(pMLMEContext->pUrb);
+				pMLMEContext->pUrb = NULL;
+			}
+		}
+	}
+	if (pAd->MgmtDescRing.AllocVa)
+		os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
+
+
+	// Free Tx frame resource
+	for (acidx = 0; acidx < 4; acidx++)
+		{
+		PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
+			if (pHTTXContext)
+				LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
+		}
+
+	if (pAd->FragFrame.pFragPacket)
+		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
+
+	for(i=0; i<6; i++)
+	{
+		NdisFreeSpinLock(&pAd->BulkOutLock[i]);
+	}
+
+	NdisFreeSpinLock(&pAd->BulkInLock);
+	NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
+
+	NdisFreeSpinLock(&pAd->CmdQLock);
+	// Clear all pending bulk-out request flags.
+	RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
+
+//	NdisFreeSpinLock(&pAd->MacTabLock);
+
+//	for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
+//	{
+//		NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
+//	}
+
+	DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Write WLAN MAC address to USB 2870.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+
+Note:
+========================================================================
+*/
+NDIS_STATUS	RTUSBWriteHWMACAddress(
+	IN	PRTMP_ADAPTER		pAd)
+{
+	MAC_DW0_STRUC	StaMacReg0;
+	MAC_DW1_STRUC	StaMacReg1;
+	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
+	LARGE_INTEGER	NOW;
+
+
+	// initialize the random number generator
+	RTMP_GetCurrentSystemTime(&NOW);
+
+	if (pAd->bLocalAdminMAC != TRUE)
+	{
+		pAd->CurrentAddress[0] = pAd->PermanentAddress[0];
+		pAd->CurrentAddress[1] = pAd->PermanentAddress[1];
+		pAd->CurrentAddress[2] = pAd->PermanentAddress[2];
+		pAd->CurrentAddress[3] = pAd->PermanentAddress[3];
+		pAd->CurrentAddress[4] = pAd->PermanentAddress[4];
+		pAd->CurrentAddress[5] = pAd->PermanentAddress[5];
+	}
+	// Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC
+	StaMacReg0.field.Byte0 = pAd->CurrentAddress[0];
+	StaMacReg0.field.Byte1 = pAd->CurrentAddress[1];
+	StaMacReg0.field.Byte2 = pAd->CurrentAddress[2];
+	StaMacReg0.field.Byte3 = pAd->CurrentAddress[3];
+	StaMacReg1.field.Byte4 = pAd->CurrentAddress[4];
+	StaMacReg1.field.Byte5 = pAd->CurrentAddress[5];
+	StaMacReg1.field.U2MeMask = 0xff;
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("Local MAC = %02x:%02x:%02x:%02x:%02x:%02x\n",
+			pAd->CurrentAddress[0], pAd->CurrentAddress[1], pAd->CurrentAddress[2],
+			pAd->CurrentAddress[3], pAd->CurrentAddress[4], pAd->CurrentAddress[5]));
+
+	RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
+	RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
+	return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Disable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMADisable(
+	IN RTMP_ADAPTER			*pAd)
+{
+	// no use
+}
+
+
+/*
+========================================================================
+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;
+	USB_DMA_CFG_STRUC	UsbCfg;
+	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.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);
+
+	UsbCfg.word = 0;
+	UsbCfg.field.phyclear = 0;
+	/* usb version is 1.1,do not use bulk in aggregation */
+	if (pAd->BulkInMaxPacketSize == 512)
+			UsbCfg.field.RxBulkAggEn = 1;
+	/* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
+	UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
+	UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
+	UsbCfg.field.RxBulkEn = 1;
+	UsbCfg.field.TxBulkEn = 1;
+
+	RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
+
+}
+
+/********************************************************************
+  *
+  *	2870 Beacon Update Related functions.
+  *
+  ********************************************************************/
+
+/*
+========================================================================
+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)
+{
+	PUCHAR		pBeaconFrame = NULL;
+	UCHAR			*ptr;
+	UINT			i, padding;
+	BEACON_SYNC_STRUCT	*pBeaconSync = pAd->CommonCfg.pBeaconSync;
+	UINT32			longValue;
+//	USHORT			shortValue;
+	BOOLEAN			bBcnReq = FALSE;
+	UCHAR			bcn_idx = 0;
+
+
+	if (pBeaconFrame == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
+		return;
+	}
+
+	if (pBeaconSync == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
+		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);
+		}
+		pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+		NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
+	}
+	else
+	{
+		ptr = (PUCHAR)&pAd->BeaconTxWI;
+		if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
+		{	// If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
+			pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+			NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
+		}
+
+		if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
+		{
+			for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
+			{
+				longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
+				ptr += 4;
+			}
+		}
+
+		ptr = pBeaconSync->BeaconBuf[bcn_idx];
+		padding = (FrameLen & 0x01);
+		NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
+		FrameLen += padding;
+		for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
+		{
+			if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
+			{
+				NdisMoveMemory(ptr, pBeaconFrame, 2);
+				//shortValue = *ptr + (*(ptr+1)<<8);
+				//RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
+				RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
+			}
+			ptr +=2;
+			pBeaconFrame += 2;
+		}
+
+		pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
+
+		// For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
+}
+
+}
+
+
+VOID RTUSBBssBeaconStop(
+	IN RTMP_ADAPTER *pAd)
+{
+	BEACON_SYNC_STRUCT	*pBeaconSync;
+	int i, offset;
+	BOOLEAN	Cancelled = TRUE;
+
+	pBeaconSync = pAd->CommonCfg.pBeaconSync;
+	if (pBeaconSync && pBeaconSync->EnableBeacon)
+	{
+		INT NumOfBcn;
+
+		{
+			NumOfBcn = MAX_MESH_NUM;
+		}
+
+		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+
+		for(i=0; i<NumOfBcn; i++)
+		{
+			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+
+			for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
+				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
+
+			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+			pBeaconSync->TimIELocationInBeacon[i] = 0;
+		}
+		pBeaconSync->BeaconBitMap = 0;
+		pBeaconSync->DtimBitOn = 0;
+	}
+}
+
+
+VOID RTUSBBssBeaconStart(
+	IN RTMP_ADAPTER *pAd)
+{
+	int apidx;
+	BEACON_SYNC_STRUCT	*pBeaconSync;
+//	LARGE_INTEGER	tsfTime, deltaTime;
+
+	pBeaconSync = pAd->CommonCfg.pBeaconSync;
+	if (pBeaconSync && pBeaconSync->EnableBeacon)
+	{
+		INT NumOfBcn;
+
+		{
+			NumOfBcn = MAX_MESH_NUM;
+		}
+
+		for(apidx=0; apidx<NumOfBcn; apidx++)
+		{
+			UCHAR CapabilityInfoLocationInBeacon = 0;
+			UCHAR TimIELocationInBeacon = 0;
+
+
+			NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
+			pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
+			pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
+		}
+		pBeaconSync->BeaconBitMap = 0;
+		pBeaconSync->DtimBitOn = 0;
+		pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
+
+		pAd->CommonCfg.BeaconAdjust = 0;
+		pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
+		pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
+		DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
+									pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain));
+		RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, 10 /*pAd->CommonCfg.BeaconPeriod*/);
+
+	}
+}
+
+
+VOID RTUSBBssBeaconInit(
+	IN RTMP_ADAPTER *pAd)
+{
+	BEACON_SYNC_STRUCT	*pBeaconSync;
+	int i;
+
+	os_alloc_mem(pAd, (PUCHAR *)(&pAd->CommonCfg.pBeaconSync), sizeof(BEACON_SYNC_STRUCT));
+	//NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
+	if (pAd->CommonCfg.pBeaconSync)
+	{
+		pBeaconSync = pAd->CommonCfg.pBeaconSync;
+		NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
+		for(i=0; i < HW_BEACON_MAX_COUNT; i++)
+		{
+			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+			pBeaconSync->TimIELocationInBeacon[i] = 0;
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+		}
+		pBeaconSync->BeaconBitMap = 0;
+
+		//RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
+		pBeaconSync->EnableBeacon = TRUE;
+	}
+}
+
+
+VOID RTUSBBssBeaconExit(
+	IN RTMP_ADAPTER *pAd)
+{
+	BEACON_SYNC_STRUCT	*pBeaconSync;
+	BOOLEAN	Cancelled = TRUE;
+	int i;
+
+	if (pAd->CommonCfg.pBeaconSync)
+	{
+		pBeaconSync = pAd->CommonCfg.pBeaconSync;
+		pBeaconSync->EnableBeacon = FALSE;
+		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+		pBeaconSync->BeaconBitMap = 0;
+
+		for(i=0; i<HW_BEACON_MAX_COUNT; i++)
+		{
+			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+			pBeaconSync->TimIELocationInBeacon[i] = 0;
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+		}
+
+		os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
+		pAd->CommonCfg.pBeaconSync = NULL;
+	}
+}
+
+
+/*
+    ========================================================================
+    Routine Description:
+        For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
+        to update the beacon context in each Beacon interval. Here we use a periodical timer
+        to simulate the TBTT interrupt to handle the beacon context update.
+
+    Arguments:
+        SystemSpecific1         - Not used.
+        FunctionContext         - Pointer to our Adapter context.
+        SystemSpecific2         - Not used.
+        SystemSpecific3         - Not used.
+
+    Return Value:
+        None
+
+    ========================================================================
+*/
+VOID BeaconUpdateExec(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3)
+{
+	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)FunctionContext;
+	LARGE_INTEGER	tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
+	UINT32			delta, delta2MS, period2US, remain, remain_low, remain_high;
+//	BOOLEAN			positive;
+
+	if (pAd->CommonCfg.IsUpdateBeacon==TRUE)
+	{
+		ReSyncBeaconTime(pAd);
+
+
+	}
+
+	RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
+	RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
+
+
+	//positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
+	period2US = (pAd->CommonCfg.BeaconPeriod << 10);
+	remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
+	remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
+	remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
+	delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
+
+	delta2MS = (delta>>10);
+	if (delta2MS > 150)
+	{
+		pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
+		pAd->CommonCfg.IsUpdateBeacon=FALSE;
+	}
+	else
+	{
+		pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
+		pAd->CommonCfg.IsUpdateBeacon=TRUE;
+	}
+
+}
+
+
+/********************************************************************
+  *
+  *	2870 Radio on/off Related functions.
+  *
+  ********************************************************************/
+VOID RT28xxUsbMlmeRadioOn(
+	IN PRTMP_ADAPTER pAd)
+{
+	RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+
+    DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
+
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+	{
+		AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+		RTMPusecDelay(10000);
+	}
+	//NICResetFromError(pAd);
+
+	// Enable Tx/Rx
+	RTMPEnableRxTx(pAd);
+
+	if (pChipOps->AsicReverseRfFromSleepMode)
+		pChipOps->AsicReverseRfFromSleepMode(pAd);
+
+	// Clear Radio off flag
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+		RTUSBBulkReceive(pAd);
+
+	// Set LED
+	RTMPSetLED(pAd, LED_RADIO_ON);
+}
+
+
+VOID RT28xxUsbMlmeRadioOFF(
+	IN PRTMP_ADAPTER pAd)
+{
+	WPDMA_GLO_CFG_STRUC	GloCfg;
+	UINT32	Value, i;
+
+	DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+	// Clear PMKID cache.
+	pAd->StaCfg.SavedPMKNum = 0;
+	RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(BSSID_INFO)));
+
+	// Link down first if any association exists
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+	{
+		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+		{
+			MLME_DISASSOC_REQ_STRUCT DisReq;
+			MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+			if (pMsgElem)
+			{
+				COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid);
+				DisReq.Reason =  REASON_DISASSOC_STA_LEAVING;
+
+				pMsgElem->Machine = ASSOC_STATE_MACHINE;
+				pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+				pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+				NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+				MlmeDisassocReqAction(pAd, pMsgElem);
+				kfree(pMsgElem);
+
+				RTMPusecDelay(1000);
+			}
+		}
+	}
+
+	// Set Radio off flag
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+	{
+		// Link down first if any association exists
+		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+			LinkDown(pAd, FALSE);
+		RTMPusecDelay(10000);
+
+		//==========================================
+		// Clean up old bss table
+		BssTableInit(&pAd->ScanTab);
+	}
+
+	// Set LED
+	RTMPSetLED(pAd, LED_RADIO_OFF);
+
+
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+	{
+		// Must using 40MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+	}
+	else
+	{
+		// Must using 20MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+	}
+
+	// Disable Tx/Rx DMA
+	RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word);	   // disable DMA
+	GloCfg.field.EnableTxDMA = 0;
+	GloCfg.field.EnableRxDMA = 0;
+	RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word);	   // abort all TX rings
+
+	// Waiting for DMA idle
+	i = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
+			break;
+
+		RTMPusecDelay(1000);
+	}while (i++ < 100);
+
+	// Disable MAC Tx/Rx
+	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+	Value &= (0xfffffff3);
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+	{
+		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
+	}
+}
+
+#endif // RTMP_MAC_USB //

+ 1736 - 0
drivers/staging/rt2860/common/cmm_profile.c

@@ -0,0 +1,1736 @@
+/*
+ *************************************************************************
+ * 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.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+#include "../rt_config.h"
+
+
+#define ETH_MAC_ADDR_STR_LEN 17  // in format of xx:xx:xx:xx:xx:xx
+
+// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
+BOOLEAN rtstrmactohex(PSTRING s1, PSTRING s2)
+{
+	int i = 0;
+	PSTRING ptokS = s1, ptokE = s1;
+
+	if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
+		return FALSE;
+
+	while((*ptokS) != '\0')
+	{
+		if((ptokE = strchr(ptokS, ':')) != NULL)
+			*ptokE++ = '\0';
+		if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
+			break; // fail
+		AtoH(ptokS, (PUCHAR)&s2[i++], 1);
+		ptokS = ptokE;
+		if (i == 6)
+			break; // parsing finished
+	}
+
+	return ( i == 6 ? TRUE : FALSE);
+
+}
+
+
+// we assume the s1 and s2 both are strings.
+BOOLEAN rtstrcasecmp(PSTRING s1, PSTRING s2)
+{
+	PSTRING p1 = s1, p2 = s2;
+
+	if (strlen(s1) != strlen(s2))
+		return FALSE;
+
+	while(*p1 != '\0')
+	{
+		if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
+			return FALSE;
+		p1++;
+		p2++;
+	}
+
+	return TRUE;
+}
+
+// we assume the s1 (buffer) and s2 (key) both are strings.
+PSTRING rtstrstruncasecmp(PSTRING s1, PSTRING s2)
+{
+	INT l1, l2, i;
+	char temp1, temp2;
+
+	l2 = strlen(s2);
+	if (!l2)
+		return (char *) s1;
+
+	l1 = strlen(s1);
+
+	while (l1 >= l2)
+	{
+		l1--;
+
+		for(i=0; i<l2; i++)
+		{
+			temp1 = *(s1+i);
+			temp2 = *(s2+i);
+
+			if (('a' <= temp1) && (temp1 <= 'z'))
+				temp1 = 'A'+(temp1-'a');
+			if (('a' <= temp2) && (temp2 <= 'z'))
+				temp2 = 'A'+(temp2-'a');
+
+			if (temp1 != temp2)
+				break;
+		}
+
+		if (i == l2)
+			return (char *) s1;
+
+		s1++;
+	}
+
+	return NULL; // not found
+}
+
+//add by kathy
+
+ /**
+  * strstr - Find the first substring in a %NUL terminated string
+  * @s1: The string to be searched
+  * @s2: The string to search for
+  */
+PSTRING rtstrstr(PSTRING s1,const PSTRING s2)
+{
+	INT l1, l2;
+
+	l2 = strlen(s2);
+	if (!l2)
+		return s1;
+
+	l1 = strlen(s1);
+
+	while (l1 >= l2)
+	{
+		l1--;
+		if (!memcmp(s1,s2,l2))
+			return s1;
+		s1++;
+	}
+
+	return NULL;
+}
+
+/**
+ * rstrtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
+ */
+PSTRING __rstrtok;
+PSTRING rstrtok(PSTRING s,const PSTRING ct)
+{
+	PSTRING sbegin, send;
+
+	sbegin  = s ? s : __rstrtok;
+	if (!sbegin)
+	{
+		return NULL;
+	}
+
+	sbegin += strspn(sbegin,ct);
+	if (*sbegin == '\0')
+	{
+		__rstrtok = NULL;
+		return( NULL );
+	}
+
+	send = strpbrk( sbegin, ct);
+	if (send && *send != '\0')
+		*send++ = '\0';
+
+	__rstrtok = send;
+
+	return (sbegin);
+}
+
+/**
+ * delimitcnt - return the count of a given delimiter in a given string.
+ * @s: The string to be searched.
+ * @ct: The delimiter to search for.
+ * Notice : We suppose the delimiter is a single-char string(for example : ";").
+ */
+INT delimitcnt(PSTRING s,PSTRING ct)
+{
+	INT count = 0;
+	/* point to the beginning of the line */
+	PSTRING token = s;
+
+	for ( ;; )
+	{
+		token = strpbrk(token, ct); /* search for delimiters */
+
+        if ( token == NULL )
+		{
+			/* advanced to the terminating null character */
+			break;
+		}
+		/* skip the delimiter */
+	    ++token;
+
+		/*
+		 * Print the found text: use len with %.*s to specify field width.
+		 */
+
+		/* accumulate delimiter count */
+	    ++count;
+	}
+    return count;
+}
+
+/*
+  * converts the Internet host address from the standard numbers-and-dots notation
+  * into binary data.
+  * returns nonzero if the address is valid, zero if not.
+  */
+int rtinet_aton(PSTRING cp, unsigned int *addr)
+{
+	unsigned int	val;
+	int		base, n;
+	STRING		c;
+	unsigned int    parts[4];
+	unsigned int    *pp = parts;
+
+	for (;;)
+    {
+         /*
+          * Collect number up to ``.''.
+          * Values are specified as for C:
+          *	0x=hex, 0=octal, other=decimal.
+          */
+         val = 0;
+         base = 10;
+         if (*cp == '0')
+         {
+             if (*++cp == 'x' || *cp == 'X')
+                 base = 16, cp++;
+             else
+                 base = 8;
+         }
+         while ((c = *cp) != '\0')
+         {
+             if (isdigit((unsigned char) c))
+             {
+                 val = (val * base) + (c - '0');
+                 cp++;
+                 continue;
+             }
+             if (base == 16 && isxdigit((unsigned char) c))
+             {
+                 val = (val << 4) +
+                     (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
+                 cp++;
+                 continue;
+             }
+             break;
+         }
+         if (*cp == '.')
+         {
+             /*
+              * Internet format: a.b.c.d a.b.c   (with c treated as 16-bits)
+              * a.b     (with b treated as 24 bits)
+              */
+             if (pp >= parts + 3 || val > 0xff)
+                 return 0;
+             *pp++ = val, cp++;
+         }
+         else
+             break;
+     }
+
+     /*
+      * Check for trailing junk.
+      */
+     while (*cp)
+         if (!isspace((unsigned char) *cp++))
+             return 0;
+
+     /*
+      * Concoct the address according to the number of parts specified.
+      */
+     n = pp - parts + 1;
+     switch (n)
+     {
+
+         case 1:         /* a -- 32 bits */
+             break;
+
+         case 2:         /* a.b -- 8.24 bits */
+             if (val > 0xffffff)
+                 return 0;
+             val |= parts[0] << 24;
+             break;
+
+         case 3:         /* a.b.c -- 8.8.16 bits */
+             if (val > 0xffff)
+                 return 0;
+             val |= (parts[0] << 24) | (parts[1] << 16);
+             break;
+
+         case 4:         /* a.b.c.d -- 8.8.8.8 bits */
+             if (val > 0xff)
+                 return 0;
+             val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+             break;
+     }
+
+     *addr = htonl(val);
+     return 1;
+
+}
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Find key section for Get key parameter.
+
+    Arguments:
+        buffer                      Pointer to the buffer to start find the key section
+        section                     the key of the secion to be find
+
+    Return Value:
+        NULL                        Fail
+        Others                      Success
+    ========================================================================
+*/
+PSTRING RTMPFindSection(
+    IN  PSTRING   buffer)
+{
+    STRING temp_buf[32];
+    PSTRING  ptr;
+
+    strcpy(temp_buf, "Default");
+
+    if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
+            return (ptr+strlen("\n"));
+        else
+            return NULL;
+}
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Get key parameter.
+
+    Arguments:
+	key			Pointer to key string
+	dest			Pointer to destination
+	destsize		The datasize of the destination
+	buffer		Pointer to the buffer to start find the key
+	bTrimSpace	Set true if you want to strip the space character of the result pattern
+
+    Return Value:
+        TRUE                        Success
+        FALSE                       Fail
+
+    Note:
+	This routine get the value with the matched key (case case-sensitive)
+	For SSID and security key related parameters, we SHALL NOT trim the space(' ') character.
+    ========================================================================
+*/
+INT RTMPGetKeyParameter(
+    IN PSTRING key,
+    OUT PSTRING dest,
+    IN INT destsize,
+    IN PSTRING buffer,
+    IN BOOLEAN bTrimSpace)
+{
+	PSTRING pMemBuf, temp_buf1 = NULL, temp_buf2 = NULL;
+	PSTRING start_ptr, end_ptr;
+	PSTRING ptr;
+	PSTRING offset = NULL;
+	INT  len, keyLen;
+
+
+	keyLen = strlen(key);
+	os_alloc_mem(NULL, (PUCHAR *)&pMemBuf, MAX_PARAM_BUFFER_SIZE  * 2);
+	if (pMemBuf == NULL)
+		return (FALSE);
+
+	memset(pMemBuf, 0, MAX_PARAM_BUFFER_SIZE * 2);
+	temp_buf1 = pMemBuf;
+	temp_buf2 = (PSTRING)(pMemBuf + MAX_PARAM_BUFFER_SIZE);
+
+
+	//find section
+	if((offset = RTMPFindSection(buffer)) == NULL)
+	{
+		os_free_mem(NULL, (PUCHAR)pMemBuf);
+		return (FALSE);
+	}
+
+	strcpy(temp_buf1, "\n");
+	strcat(temp_buf1, key);
+	strcat(temp_buf1, "=");
+
+	//search key
+	if((start_ptr=rtstrstr(offset, temp_buf1)) == NULL)
+	{
+		os_free_mem(NULL, (PUCHAR)pMemBuf);
+		return (FALSE);
+	}
+
+	start_ptr += strlen("\n");
+	if((end_ptr = rtstrstr(start_ptr, "\n"))==NULL)
+		end_ptr = start_ptr+strlen(start_ptr);
+
+	if (end_ptr<start_ptr)
+	{
+		os_free_mem(NULL, (PUCHAR)pMemBuf);
+		return (FALSE);
+	}
+
+	NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+	temp_buf2[end_ptr-start_ptr]='\0';
+	if((start_ptr=rtstrstr(temp_buf2, "=")) == NULL)
+	{
+		os_free_mem(NULL, (PUCHAR)pMemBuf);
+		return (FALSE);
+	}
+	ptr = (start_ptr +1);
+	//trim special characters, i.e.,  TAB or space
+	while(*start_ptr != 0x00)
+	{
+		if( ((*ptr == ' ') && bTrimSpace) || (*ptr == '\t') )
+			ptr++;
+		else
+			break;
+	}
+	len = strlen(start_ptr);
+
+	memset(dest, 0x00, destsize);
+	strncpy(dest, ptr, ((len >= destsize) ? destsize: len));
+
+	os_free_mem(NULL, (PUCHAR)pMemBuf);
+
+	return TRUE;
+}
+
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Get multiple key parameter.
+
+    Arguments:
+        key                         Pointer to key string
+        dest                        Pointer to destination
+        destsize                    The datasize of the destination
+        buffer                      Pointer to the buffer to start find the key
+
+    Return Value:
+        TRUE                        Success
+        FALSE                       Fail
+
+    Note:
+        This routine get the value with the matched key (case case-sensitive)
+    ========================================================================
+*/
+INT RTMPGetKeyParameterWithOffset(
+    IN  PSTRING   key,
+    OUT PSTRING   dest,
+    OUT	USHORT	*end_offset,
+    IN  INT     destsize,
+    IN  PSTRING   buffer,
+    IN	BOOLEAN	bTrimSpace)
+{
+    PSTRING temp_buf1 = NULL;
+    PSTRING temp_buf2 = NULL;
+    PSTRING start_ptr;
+    PSTRING end_ptr;
+    PSTRING ptr;
+    PSTRING offset = 0;
+    INT  len;
+
+	if (*end_offset >= MAX_INI_BUFFER_SIZE)
+		return (FALSE);
+
+	os_alloc_mem(NULL, (PUCHAR *)&temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+	if(temp_buf1 == NULL)
+        return (FALSE);
+
+	os_alloc_mem(NULL, (PUCHAR *)&temp_buf2, MAX_PARAM_BUFFER_SIZE);
+	if(temp_buf2 == NULL)
+	{
+		os_free_mem(NULL, (PUCHAR)temp_buf1);
+        return (FALSE);
+	}
+
+    //find section
+	if(*end_offset == 0)
+    {
+		if ((offset = RTMPFindSection(buffer)) == NULL)
+		{
+			os_free_mem(NULL, (PUCHAR)temp_buf1);
+		os_free_mem(NULL, (PUCHAR)temp_buf2);
+	    return (FALSE);
+		}
+    }
+	else
+		offset = buffer + (*end_offset);
+
+    strcpy(temp_buf1, "\n");
+    strcat(temp_buf1, key);
+    strcat(temp_buf1, "=");
+
+    //search key
+    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+    {
+		os_free_mem(NULL, (PUCHAR)temp_buf1);
+	os_free_mem(NULL, (PUCHAR)temp_buf2);
+        return (FALSE);
+    }
+
+    start_ptr+=strlen("\n");
+    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+       end_ptr=start_ptr+strlen(start_ptr);
+
+    if (end_ptr<start_ptr)
+    {
+		os_free_mem(NULL, (PUCHAR)temp_buf1);
+	os_free_mem(NULL, (PUCHAR)temp_buf2);
+        return (FALSE);
+    }
+
+	*end_offset = end_ptr - buffer;
+
+    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+    temp_buf2[end_ptr-start_ptr]='\0';
+    len = strlen(temp_buf2);
+    strcpy(temp_buf1, temp_buf2);
+    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+    {
+		os_free_mem(NULL, (PUCHAR)temp_buf1);
+	os_free_mem(NULL, (PUCHAR)temp_buf2);
+        return (FALSE);
+    }
+
+    strcpy(temp_buf2, start_ptr+1);
+    ptr = temp_buf2;
+    //trim space or tab
+    while(*ptr != 0x00)
+    {
+        if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
+            ptr++;
+        else
+           break;
+    }
+
+    len = strlen(ptr);
+    memset(dest, 0x00, destsize);
+    strncpy(dest, ptr, len >= destsize ?  destsize: len);
+
+	os_free_mem(NULL, (PUCHAR)temp_buf1);
+    os_free_mem(NULL, (PUCHAR)temp_buf2);
+    return TRUE;
+}
+
+
+static int rtmp_parse_key_buffer_from_file(IN  PRTMP_ADAPTER pAd,IN  PSTRING buffer,IN  ULONG KeyType,IN  INT BSSIdx,IN  INT KeyIdx)
+{
+	PSTRING		keybuff;
+	//INT			i = BSSIdx, idx = KeyIdx, retVal;
+	ULONG		KeyLen;
+	//UCHAR		CipherAlg = CIPHER_WEP64;
+	CIPHER_KEY	*pSharedKey;
+
+	keybuff = buffer;
+	KeyLen = strlen(keybuff);
+	pSharedKey = &pAd->SharedKey[BSSIdx][KeyIdx];
+
+	if(((KeyType != 0) && (KeyType != 1)) ||
+	    ((KeyType == 0) && (KeyLen != 10) && (KeyLen != 26)) ||
+	    ((KeyType== 1) && (KeyLen != 5) && (KeyLen != 13)))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length(%ld) or Type(%ld)\n",
+								KeyIdx+1, KeyLen, KeyType));
+		return FALSE;
+	}
+	else
+	{
+		return RT_CfgSetWepKey(pAd, buffer, pSharedKey, KeyIdx);
+	}
+
+}
+
+
+static void rtmp_read_key_parms_from_file(IN  PRTMP_ADAPTER pAd, PSTRING tmpbuf, PSTRING buffer)
+{
+	STRING		tok_str[16];
+	PSTRING		macptr;
+	INT			i = 0, idx;
+	ULONG		KeyType[MAX_MBSSID_NUM];
+	ULONG		KeyIdx;
+
+	NdisZeroMemory(KeyType, sizeof(KeyType));
+
+	//DefaultKeyID
+	if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer, TRUE))
+	{
+		{
+			KeyIdx = simple_strtol(tmpbuf, 0, 10);
+			if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+				pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
+			else
+				pAd->StaCfg.DefaultKeyId = 0;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
+		}
+	}
+
+
+	for (idx = 0; idx < 4; idx++)
+	{
+		sprintf(tok_str, "Key%dType", idx + 1);
+		//Key1Type
+		if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, TRUE))
+		{
+		    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+		    {
+				/*
+					do sanity check for KeyType length;
+					or in station mode, the KeyType length > 1,
+					the code will overwrite the stack of caller
+					(RTMPSetProfileParameters) and cause srcbuf = NULL
+				*/
+				if (i < MAX_MBSSID_NUM)
+					KeyType[i] = simple_strtol(macptr, 0, 10);
+		    }
+
+			{
+				sprintf(tok_str, "Key%dStr", idx + 1);
+				if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE))
+				{
+					rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
+				}
+			}
+		}
+	}
+}
+
+
+
+static void rtmp_read_sta_wmm_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
+{
+	PSTRING					macptr;
+	INT						i=0;
+	BOOLEAN					bWmmEnable = FALSE;
+
+	//WmmCapable
+	if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer, TRUE))
+	{
+		if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+		{
+			pAd->CommonCfg.bWmmCapable = TRUE;
+			bWmmEnable = TRUE;
+		}
+		else //Disable
+		{
+			pAd->CommonCfg.bWmmCapable = FALSE;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
+	}
+
+
+	//AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
+	if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer, TRUE))
+	{
+		for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+		{
+			pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
+
+			DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
+		}
+	}
+
+	if (bWmmEnable)
+	{
+		//APSDCapable
+		if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer, TRUE))
+		{
+			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
+				pAd->CommonCfg.bAPSDCapable = TRUE;
+			else
+				pAd->CommonCfg.bAPSDCapable = FALSE;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
+		}
+
+		//MaxSPLength
+		if(RTMPGetKeyParameter("MaxSPLength", tmpbuf, 10, buffer, TRUE))
+		{
+			pAd->CommonCfg.MaxSPLength = simple_strtol(tmpbuf, 0, 10);
+
+			DBGPRINT(RT_DEBUG_TRACE, ("MaxSPLength=%d\n", pAd->CommonCfg.MaxSPLength));
+		}
+
+		//APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
+		if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer, TRUE))
+		{
+			BOOLEAN apsd_ac[4];
+
+			for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+			{
+				apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
+
+				DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d  %d\n", i,  apsd_ac[i]));
+			}
+
+			pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
+			pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
+			pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
+			pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
+
+			pAd->CommonCfg.bACMAPSDTr[0] = apsd_ac[0];
+			pAd->CommonCfg.bACMAPSDTr[1] = apsd_ac[1];
+			pAd->CommonCfg.bACMAPSDTr[2] = apsd_ac[2];
+			pAd->CommonCfg.bACMAPSDTr[3] = apsd_ac[3];
+		}
+	}
+
+}
+
+
+static void HTParametersHook(
+	IN	PRTMP_ADAPTER pAd,
+	IN	PSTRING		  pValueStr,
+	IN	PSTRING		  pInput)
+{
+
+	long Value;
+
+    if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput, TRUE))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.bHTProtect = FALSE;
+        }
+        else
+        {
+            pAd->CommonCfg.bHTProtect = TRUE;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+    if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput, TRUE))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.bMIMOPSEnable = FALSE;
+        }
+        else
+        {
+            pAd->CommonCfg.bMIMOPSEnable = TRUE;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+
+    if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput, TRUE))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value > MMPS_ENABLE)
+        {
+			pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+        }
+        else
+        {
+            //TODO: add mimo power saving mechanism
+            pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+			//pAd->CommonCfg.BACapability.field.MMPSmode = Value;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode  = %d\n", (INT) Value));
+    }
+
+    if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput, TRUE))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.bBADecline = FALSE;
+        }
+        else
+        {
+            pAd->CommonCfg.bBADecline = TRUE;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+
+    if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput, TRUE))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.bDisableReordering = FALSE;
+        }
+        else
+        {
+            pAd->CommonCfg.bDisableReordering = TRUE;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+    if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput, TRUE))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+			pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+        }
+        else
+        {
+            pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+			pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+        }
+        pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+	// Tx_+HTC frame
+    if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->HTCEnable = FALSE;
+		}
+		else
+		{
+            pAd->HTCEnable = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
+	}
+
+	// Enable HT Link Adaptation Control
+	if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->bLinkAdapt = FALSE;
+		}
+		else
+		{
+			pAd->HTCEnable = TRUE;
+			pAd->bLinkAdapt = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
+	}
+
+	// Reverse Direction Mechanism
+    if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->CommonCfg.bRdg = FALSE;
+		}
+		else
+		{
+			pAd->HTCEnable = TRUE;
+            pAd->CommonCfg.bRdg = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
+	}
+
+
+
+
+	// Tx A-MSUD ?
+    if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
+		}
+		else
+		{
+            pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
+	}
+
+	// MPDU Density
+    if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value <=7 && Value >= 0)
+		{
+			pAd->CommonCfg.BACapability.field.MpduDensity = Value;
+			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", (INT) Value));
+		}
+		else
+		{
+			pAd->CommonCfg.BACapability.field.MpduDensity = 4;
+			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
+		}
+	}
+
+	// Max Rx BA Window Size
+    if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value >=1 && Value <= 64)
+		{
+			pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
+			pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
+			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", (INT) Value));
+		}
+		else
+		{
+            pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
+			pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
+			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
+		}
+
+	}
+
+	// Guard Interval
+	if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == GI_400)
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
+		}
+		else
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
+	}
+
+	// HT Operation Mode : Mixed Mode , Green Field
+	if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == HTMODE_GF)
+		{
+
+			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_GF;
+		}
+		else
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_MM;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
+	}
+
+	// Fixed Tx mode : CCK, OFDM
+	if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput, TRUE))
+	{
+		UCHAR	fix_tx_mode;
+
+		{
+			fix_tx_mode = FIXED_TXMODE_HT;
+
+			if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
+			{
+				fix_tx_mode = FIXED_TXMODE_OFDM;
+			}
+			else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
+			{
+		        fix_tx_mode = FIXED_TXMODE_CCK;
+			}
+			else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
+			{
+		        fix_tx_mode = FIXED_TXMODE_HT;
+		}
+		else
+		{
+				Value = simple_strtol(pValueStr, 0, 10);
+				// 1 : CCK
+				// 2 : OFDM
+				// otherwise : HT
+				if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
+					fix_tx_mode = Value;
+				else
+					fix_tx_mode = FIXED_TXMODE_HT;
+		}
+
+			pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
+			DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
+
+		}
+	}
+
+
+	// Channel Width
+	if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == BW_40)
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_40;
+		}
+		else
+		{
+            pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
+	}
+
+	if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == 0)
+		{
+
+			pAd->CommonCfg.RegTransmitSetting.field.EXTCHA  = EXTCHA_BELOW;
+		}
+		else
+		{
+            pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
+	}
+
+	// MSC
+	if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput, TRUE))
+	{
+		{
+			Value = simple_strtol(pValueStr, 0, 10);
+
+//			if ((Value >= 0 && Value <= 15) || (Value == 32))
+			if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
+		{
+				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = Value;
+				pAd->StaCfg.bAutoTxRateSwitch = FALSE;
+				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
+		}
+		else
+		{
+				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = MCS_AUTO;
+				pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
+		}
+	}
+	}
+
+	// STBC
+    if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == STBC_USE)
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
+		}
+		else
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
+	}
+
+	// 40_Mhz_Intolerant
+	if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
+		}
+		else
+		{
+			pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
+	}
+	//HT_TxStream
+	if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput, TRUE))
+	{
+		switch (simple_strtol(pValueStr, 0, 10))
+		{
+			case 1:
+				pAd->CommonCfg.TxStream = 1;
+				break;
+			case 2:
+				pAd->CommonCfg.TxStream = 2;
+				break;
+			case 3: // 3*3
+			default:
+				pAd->CommonCfg.TxStream = 3;
+
+				if (pAd->MACVersion < RALINK_2883_VERSION)
+					pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
+				break;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
+	}
+	//HT_RxStream
+	if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput, TRUE))
+	{
+		switch (simple_strtol(pValueStr, 0, 10))
+		{
+			case 1:
+				pAd->CommonCfg.RxStream = 1;
+				break;
+			case 2:
+				pAd->CommonCfg.RxStream = 2;
+				break;
+			case 3:
+			default:
+				pAd->CommonCfg.RxStream = 3;
+
+				if (pAd->MACVersion < RALINK_2883_VERSION)
+					pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
+				break;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
+	}
+	//2008/11/05: KH add to support Antenna power-saving of AP<--
+	//Green AP
+	if(RTMPGetKeyParameter("GreenAP", pValueStr, 10, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->CommonCfg.bGreenAPEnable = FALSE;
+		}
+		else
+		{
+			pAd->CommonCfg.bGreenAPEnable = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Green AP= %d\n", pAd->CommonCfg.bGreenAPEnable));
+	}
+
+	// HT_DisallowTKIP
+	if (RTMPGetKeyParameter("HT_DisallowTKIP", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == 1)
+		{
+			pAd->CommonCfg.HT_DisallowTKIP = TRUE;
+		}
+		else
+		{
+			pAd->CommonCfg.HT_DisallowTKIP = FALSE;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Disallow TKIP mode = %s\n", (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "ON" : "OFF" ));
+	}
+
+
+	//2008/11/05:KH add to support Antenna power-saving of AP-->
+}
+
+
+NDIS_STATUS	RTMPSetProfileParameters(
+	IN RTMP_ADAPTER *pAd,
+	IN PSTRING	pBuffer)
+{
+	PSTRING					tmpbuf;
+	ULONG					RtsThresh;
+	ULONG					FragThresh;
+	PSTRING					macptr;
+	INT						i = 0, retval;
+	tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	if(tmpbuf == NULL)
+		return NDIS_STATUS_FAILURE;
+
+	do
+	{
+		// set file parameter to portcfg
+		//CountryRegion
+		if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, pBuffer, TRUE))
+		{
+			retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_24G);
+			DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
+		}
+		//CountryRegionABand
+		if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, pBuffer, TRUE))
+		{
+			retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_5G);
+			DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
+		}
+#ifdef RTMP_EFUSE_SUPPORT
+#ifdef RT30xx
+		//EfuseBufferMode
+		if(RTMPGetKeyParameter("EfuseBufferMode", tmpbuf, 25, pBuffer, TRUE))
+		{
+			pAd->bEEPROMFile = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+			DBGPRINT(RT_DEBUG_TRACE, ("EfuseBufferMode=%d\n", pAd->bUseEfuse));
+		}
+#endif // RT30xx //
+#endif // RTMP_EFUSE_SUPPORT //
+		//CountryCode
+		if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, pBuffer, TRUE))
+		{
+			NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
+			if (strlen((PSTRING) pAd->CommonCfg.CountryCode) != 0)
+			{
+				pAd->CommonCfg.bCountryFlag = TRUE;
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
+		}
+		//ChannelGeography
+		if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, pBuffer, TRUE))
+		{
+			UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+			if (Geography <= BOTH)
+			{
+				pAd->CommonCfg.Geography = Geography;
+				pAd->CommonCfg.CountryCode[2] =
+					(pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
+				DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
+			}
+		}
+		else
+		{
+			pAd->CommonCfg.Geography = BOTH;
+			pAd->CommonCfg.CountryCode[2] = ' ';
+		}
+
+		{
+			//SSID
+			if (RTMPGetKeyParameter("SSID", tmpbuf, 256, pBuffer, FALSE))
+			{
+				if (strlen(tmpbuf) <= 32)
+				{
+						pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
+					NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
+					NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
+					pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
+					NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
+					NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
+					pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
+					NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
+					NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
+					DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __func__, tmpbuf));
+				}
+			}
+		}
+
+		{
+			//NetworkType
+			if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, pBuffer, TRUE))
+			{
+				pAd->bConfigChanged = TRUE;
+				if (strcmp(tmpbuf, "Adhoc") == 0)
+					pAd->StaCfg.BssType = BSS_ADHOC;
+				else //Default Infrastructure mode
+					pAd->StaCfg.BssType = BSS_INFRA;
+				// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+				pAd->StaCfg.WpaState = SS_NOTUSE;
+				DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __func__, pAd->StaCfg.BssType));
+			}
+		}
+		//Channel
+		if(RTMPGetKeyParameter("Channel", tmpbuf, 10, pBuffer, TRUE))
+		{
+			pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+			DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
+		}
+		//WirelessMode
+		if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, pBuffer, TRUE))
+		{
+			RT_CfgSetWirelessMode(pAd, tmpbuf);
+			DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
+		}
+	    //BasicRate
+		if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, pBuffer, TRUE))
+		{
+			pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
+			DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
+		}
+		//BeaconPeriod
+		if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, pBuffer, TRUE))
+		{
+			pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
+			DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
+		}
+	    //TxPower
+		if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, pBuffer, TRUE))
+		{
+			pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
+				pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
+			DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
+		}
+		//BGProtection
+		if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, pBuffer, TRUE))
+		{
+	//#if 0	//#ifndef WIFI_TEST
+	//		pAd->CommonCfg.UseBGProtection = 2;// disable b/g protection for throughput test
+	//#else
+			switch (simple_strtol(tmpbuf, 0, 10))
+			{
+				case 1: //Always On
+					pAd->CommonCfg.UseBGProtection = 1;
+					break;
+				case 2: //Always OFF
+					pAd->CommonCfg.UseBGProtection = 2;
+					break;
+				case 0: //AUTO
+				default:
+					pAd->CommonCfg.UseBGProtection = 0;
+					break;
+			}
+	//#endif
+			DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
+		}
+		//OLBCDetection
+		if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, pBuffer, TRUE))
+		{
+			switch (simple_strtol(tmpbuf, 0, 10))
+			{
+				case 1: //disable OLBC Detection
+					pAd->CommonCfg.DisableOLBCDetect = 1;
+					break;
+				case 0: //enable OLBC Detection
+					pAd->CommonCfg.DisableOLBCDetect = 0;
+					break;
+				default:
+					pAd->CommonCfg.DisableOLBCDetect= 0;
+					break;
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
+		}
+		//TxPreamble
+		if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, pBuffer, TRUE))
+		{
+			switch (simple_strtol(tmpbuf, 0, 10))
+			{
+				case Rt802_11PreambleShort:
+					pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
+					break;
+				case Rt802_11PreambleLong:
+				default:
+					pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
+					break;
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
+		}
+		//RTSThreshold
+		if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, pBuffer, TRUE))
+		{
+			RtsThresh = simple_strtol(tmpbuf, 0, 10);
+			if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
+				pAd->CommonCfg.RtsThreshold  = (USHORT)RtsThresh;
+			else
+				pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
+		}
+		//FragThreshold
+		if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, pBuffer, TRUE))
+		{
+			FragThresh = simple_strtol(tmpbuf, 0, 10);
+			pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+
+			if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+			{ //illegal FragThresh so we set it to default
+				pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+				pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
+			}
+			else if (FragThresh % 2 == 1)
+			{
+				// The length of each fragment shall always be an even number of octets, except for the last fragment
+				// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
+				pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
+			}
+			else
+			{
+				pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+			}
+			//pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
+			DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
+		}
+		//TxBurst
+		if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, pBuffer, TRUE))
+		{
+	//#ifdef WIFI_TEST
+	//						pAd->CommonCfg.bEnableTxBurst = FALSE;
+	//#else
+			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
+				pAd->CommonCfg.bEnableTxBurst = TRUE;
+			else //Disable
+				pAd->CommonCfg.bEnableTxBurst = FALSE;
+	//#endif
+			DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
+		}
+
+#ifdef AGGREGATION_SUPPORT
+		//PktAggregate
+		if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, pBuffer, TRUE))
+		{
+			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
+				pAd->CommonCfg.bAggregationCapable = TRUE;
+			else //Disable
+				pAd->CommonCfg.bAggregationCapable = FALSE;
+#ifdef PIGGYBACK_SUPPORT
+			pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
+#endif // PIGGYBACK_SUPPORT //
+			DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
+		}
+#else
+		pAd->CommonCfg.bAggregationCapable = FALSE;
+		pAd->CommonCfg.bPiggyBackCapable = FALSE;
+#endif // AGGREGATION_SUPPORT //
+
+		// WmmCapable
+
+			rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, pBuffer);
+
+		//ShortSlot
+		if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, pBuffer, TRUE))
+		{
+			RT_CfgSetShortSlot(pAd, tmpbuf);
+			DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
+		}
+		//IEEE80211H
+		if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, pBuffer, TRUE))
+		{
+		    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+		    {
+				if(simple_strtol(macptr, 0, 10) != 0)  //Enable
+					pAd->CommonCfg.bIEEE80211H = TRUE;
+				else //Disable
+					pAd->CommonCfg.bIEEE80211H = FALSE;
+
+				DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
+		    }
+		}
+		//CSPeriod
+		if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, pBuffer, TRUE))
+		{
+		    if(simple_strtol(tmpbuf, 0, 10) != 0)
+				pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
+			else
+				pAd->CommonCfg.RadarDetect.CSPeriod = 0;
+
+				DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
+		}
+
+		//RDRegion
+		if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, pBuffer, TRUE))
+		{
+						RADAR_DETECT_STRUCT	*pRadarDetect = &pAd->CommonCfg.RadarDetect;
+			if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
+			{
+							pRadarDetect->RDDurRegion = JAP_W53;
+							pRadarDetect->DfsSessionTime = 15;
+			}
+			else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
+			{
+							pRadarDetect->RDDurRegion = JAP_W56;
+							pRadarDetect->DfsSessionTime = 13;
+			}
+			else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
+			{
+							pRadarDetect->RDDurRegion = JAP;
+							pRadarDetect->DfsSessionTime = 5;
+			}
+			else  if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
+			{
+							pRadarDetect->RDDurRegion = FCC;
+							pRadarDetect->DfsSessionTime = 5;
+			}
+			else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
+			{
+							pRadarDetect->RDDurRegion = CE;
+							pRadarDetect->DfsSessionTime = 13;
+			}
+			else
+			{
+							pRadarDetect->RDDurRegion = CE;
+							pRadarDetect->DfsSessionTime = 13;
+			}
+
+						DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pRadarDetect->RDDurRegion));
+		}
+		else
+		{
+			pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+			pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+		}
+
+		//WirelessEvent
+		if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, pBuffer, TRUE))
+		{
+		    if(simple_strtol(tmpbuf, 0, 10) != 0)
+				pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
+			else
+				pAd->CommonCfg.bWirelessEvent = 0;	// disable
+				DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
+		}
+		if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, pBuffer, TRUE))
+		{
+		    if(simple_strtol(tmpbuf, 0, 10) != 0)
+				pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
+			else
+				pAd->CommonCfg.bWiFiTest = 0;	// disable
+
+				DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
+		}
+		//AuthMode
+		if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, pBuffer, TRUE))
+		{
+			{
+				if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
+	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
+	                        else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
+	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+	                        else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
+	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+	                        else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
+	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+	                        else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
+							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+							else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
+			                    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+							else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
+							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+	                        else
+	                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+
+	                        pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+				DBGPRINT(RT_DEBUG_TRACE, ("%s::(AuthMode=%d)\n", __func__, pAd->StaCfg.AuthMode));
+			}
+		}
+		//EncrypType
+		if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, pBuffer, TRUE))
+		{
+			{
+				if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
+					pAd->StaCfg.WepStatus	= Ndis802_11WEPEnabled;
+				else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
+					pAd->StaCfg.WepStatus	= Ndis802_11Encryption2Enabled;
+				else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
+					pAd->StaCfg.WepStatus	= Ndis802_11Encryption3Enabled;
+				else
+					pAd->StaCfg.WepStatus	= Ndis802_11WEPDisabled;
+
+				// Update all wepstatus related
+				pAd->StaCfg.PairCipher		= pAd->StaCfg.WepStatus;
+				pAd->StaCfg.GroupCipher		= pAd->StaCfg.WepStatus;
+				pAd->StaCfg.OrigWepStatus	= pAd->StaCfg.WepStatus;
+				pAd->StaCfg.bMixCipher		= FALSE;
+
+				//RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+				DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
+			}
+		}
+
+		{
+			if(RTMPGetKeyParameter("WPAPSK", tmpbuf, 512, pBuffer, FALSE))
+			{
+				int     ret = TRUE;
+
+				tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
+
+				if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+					(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+					(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+					)
+				{
+					ret = FALSE;
+				}
+				else
+				{
+					ret = RT_CfgSetWPAPSKKey(pAd, tmpbuf, (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->StaCfg.PMK);
+				}
+
+				if (ret == TRUE)
+				{
+			RTMPZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
+			RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, tmpbuf, strlen(tmpbuf));
+					pAd->StaCfg.WpaPassPhraseLen= strlen(tmpbuf);
+
+					if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+						(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+					{
+						// Start STA supplicant state machine
+						pAd->StaCfg.WpaState = SS_START;
+					}
+					else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+					{
+						pAd->StaCfg.WpaState = SS_NOTUSE;
+					}
+					DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __func__, tmpbuf));
+				}
+			}
+		}
+
+		//DefaultKeyID, KeyType, KeyStr
+		rtmp_read_key_parms_from_file(pAd, tmpbuf, pBuffer);
+
+
+		//HSCounter
+		/*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, pBuffer, TRUE))
+		{
+			switch (simple_strtol(tmpbuf, 0, 10))
+			{
+				case 1: //Enable
+					pAd->CommonCfg.bEnableHSCounter = TRUE;
+					break;
+				case 0: //Disable
+				default:
+					pAd->CommonCfg.bEnableHSCounter = FALSE;
+					break;
+			}
+			DBGPRINT(RT_DEBUG_TRACE, "HSCounter=%d\n", pAd->CommonCfg.bEnableHSCounter);
+		}*/
+
+		HTParametersHook(pAd, tmpbuf, pBuffer);
+
+		{
+			//PSMode
+			if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, pBuffer, TRUE))
+			{
+				if (pAd->StaCfg.BssType == BSS_INFRA)
+				{
+					if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
+					{
+						// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+						// to exclude certain situations.
+						//	   MlmeSetPsm(pAd, PWR_SAVE);
+						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+						if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+							pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
+						pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
+						pAd->StaCfg.DefaultListenCount = 5;
+					}
+					else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
+						|| (strcmp(tmpbuf, "FAST_PSP") == 0))
+					{
+						// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+						// to exclude certain situations.
+						//	   RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
+						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+						if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+							pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
+						pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
+						pAd->StaCfg.DefaultListenCount = 3;
+					}
+					else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
+						|| (strcmp(tmpbuf, "LEGACY_PSP") == 0))
+					{
+						// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+						// to exclude certain situations.
+						//	   RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
+						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+						if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+							pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
+						pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
+						pAd->StaCfg.DefaultListenCount = 3;
+					}
+					else
+					{ //Default Ndis802_11PowerModeCAM
+						// clear PSM bit immediately
+						RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
+						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+						if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+							pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+						pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+					}
+					DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
+				}
+			}
+			// AutoRoaming by RSSI
+			if (RTMPGetKeyParameter("AutoRoaming", tmpbuf, 32, pBuffer, TRUE))
+			{
+				if (simple_strtol(tmpbuf, 0, 10) == 0)
+					pAd->StaCfg.bAutoRoaming = FALSE;
+				else
+					pAd->StaCfg.bAutoRoaming = TRUE;
+
+				DBGPRINT(RT_DEBUG_TRACE, ("AutoRoaming=%d\n", pAd->StaCfg.bAutoRoaming));
+			}
+			// RoamThreshold
+			if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, pBuffer, TRUE))
+			{
+				long lInfo = simple_strtol(tmpbuf, 0, 10);
+
+				if (lInfo > 90 || lInfo < 60)
+					pAd->StaCfg.dBmToRoam = -70;
+				else
+					pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
+
+				DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d  dBm\n", pAd->StaCfg.dBmToRoam));
+			}
+
+			if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, pBuffer, TRUE))
+			{
+				if(simple_strtol(tmpbuf, 0, 10) == 0)
+					pAd->StaCfg.bTGnWifiTest = FALSE;
+				else
+					pAd->StaCfg.bTGnWifiTest = TRUE;
+					DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
+			}
+
+			// Beacon Lost Time
+			if (RTMPGetKeyParameter("BeaconLostTime", tmpbuf, 32, pBuffer, TRUE))
+			{
+				ULONG lInfo = (ULONG)simple_strtol(tmpbuf, 0, 10);
+
+				if ((lInfo != 0) && (lInfo <= 60))
+					pAd->StaCfg.BeaconLostTime = (lInfo * OS_HZ);
+				DBGPRINT(RT_DEBUG_TRACE, ("BeaconLostTime=%ld \n", pAd->StaCfg.BeaconLostTime));
+			}
+
+
+		}
+
+
+
+
+	}while(0);
+
+
+	kfree(tmpbuf);
+
+	return NDIS_STATUS_SUCCESS;
+
+}

+ 222 - 11
drivers/staging/rt2860/common/cmm_sanity.c

@@ -283,8 +283,8 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
     OUT USHORT *LengthVIE,
     OUT	PNDIS_802_11_VARIABLE_IEs pVIE)
 {
-    CHAR				*Ptr;
-	CHAR 				TimLen;
+    UCHAR				*Ptr;
+	UCHAR				TimLen;
     PFRAME_802_11		pFrame;
     PEID_STRUCT         pEid;
     UCHAR				SubType;
@@ -529,10 +529,9 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
             case IE_TIM:
                 if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
                 {
-                    GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
+                    GetTimBit((PCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
                 }
                 break;
-
             case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
                 if(pEid->Len == 3)
                 {
@@ -545,6 +544,26 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
             // Wifi WMM use the same IE vale, need to parse that too
             // case IE_WPA:
             case IE_VENDOR_SPECIFIC:
+                // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE.
+                // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
+                /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
+                {
+			if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
+			{
+				{
+					NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
+					*pHtCapabilityLen = SIZE_HT_CAP_IE;	// Nnow we only support 26 bytes.
+				}
+			}
+			if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
+			{
+				{
+					NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
+					*AddHtInfoLen = SIZE_ADD_HT_INFO_IE;	// Nnow we only support 26 bytes.
+				}
+			}
+                }
+				*/
                 // Check the OUI version, filter out non-standard usage
                 if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
                 {
@@ -638,6 +657,8 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
                     pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
                     pEdcaParm->Txop[QID_AC_VO]  = 48;   // AC_VO: 48*32us ~= 1.5ms
                 }
+
+
                 break;
 
             case IE_EXT_SUPP_RATES:
@@ -718,7 +739,7 @@ BOOLEAN PeerBeaconAndProbeRspSanity(
 
 	if (Sanity != 0x7)
 	{
-		DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
+		DBGPRINT(RT_DEBUG_LOUD, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
 		return FALSE;
 	}
 	else
@@ -755,8 +776,6 @@ BOOLEAN MlmeScanReqSanity(
 
 	if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
 		&& (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
-		|| *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
-		|| *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
 		))
 	{
 		return TRUE;
@@ -837,8 +856,7 @@ BOOLEAN PeerAuthSanity(
     NdisMoveMemory(pSeq,    &pFrame->Octet[2], 2);
     NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
 
-    if ((*pAlg == Ndis802_11AuthModeOpen)
-      )
+    if (*pAlg == AUTH_MODE_OPEN)
     {
         if (*pSeq == 1 || *pSeq == 2)
         {
@@ -850,7 +868,7 @@ BOOLEAN PeerAuthSanity(
             return FALSE;
         }
     }
-    else if (*pAlg == Ndis802_11AuthModeShared)
+    else if (*pAlg == AUTH_MODE_KEY)
     {
         if (*pSeq == 1 || *pSeq == 4)
         {
@@ -897,7 +915,7 @@ BOOLEAN MlmeAuthReqSanity(
     *pTimeout = pInfo->Timeout;
     *pAlg = pInfo->Alg;
 
-    if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
+    if (((*pAlg == AUTH_MODE_KEY) ||(*pAlg == AUTH_MODE_OPEN)
      	) &&
         ((*pAddr & 0x01) == 0))
     {
@@ -1052,3 +1070,196 @@ NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
 
 	return NetWorkType;
 }
+
+/*
+    ==========================================================================
+    Description:
+        Check the validity of the received EAPoL frame
+    Return:
+        TRUE if all parameters are OK,
+        FALSE otherwise
+    ==========================================================================
+ */
+BOOLEAN PeerWpaMessageSanity(
+    IN	PRTMP_ADAPTER		pAd,
+    IN	PEAPOL_PACKET		pMsg,
+    IN	ULONG				MsgLen,
+    IN	UCHAR				MsgType,
+    IN	MAC_TABLE_ENTRY		*pEntry)
+{
+	UCHAR			mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
+	BOOLEAN			bReplayDiff = FALSE;
+	BOOLEAN			bWPA2 = FALSE;
+	KEY_INFO		EapolKeyInfo;
+	UCHAR			GroupKeyIndex = 0;
+
+
+	NdisZeroMemory(mic, sizeof(mic));
+	NdisZeroMemory(digest, sizeof(digest));
+	NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
+	NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
+
+	NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+	*((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
+
+	// Choose WPA2 or not
+	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+		bWPA2 = TRUE;
+
+	// 0. Check MsgType
+	if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
+		return FALSE;
+	}
+
+	// 1. Replay counter check
+	if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)	// For supplicant
+    {
+	// First validate replay counter, only accept message with larger replay counter.
+		// Let equal pass, some AP start with all zero replay counter
+		UCHAR	ZeroReplay[LEN_KEY_DESC_REPLAY];
+
+        NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+		if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
+			(RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+	{
+			bReplayDiff = TRUE;
+	}
+	}
+	else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)	// For authenticator
+	{
+		// check Replay Counter coresponds to MSG from authenticator, otherwise discard
+	if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
+	{
+			bReplayDiff = TRUE;
+	}
+	}
+
+	// Replay Counter different condition
+	if (bReplayDiff)
+	{
+		// send wireless event - for replay counter different
+		if (pAd->CommonCfg.bWirelessEvent)
+			RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+		if (MsgType < EAPOL_GROUP_MSG_1)
+		{
+		DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
+		}
+
+		hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+		hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
+        return FALSE;
+	}
+
+	// 2. Verify MIC except Pairwise Msg1
+	if (MsgType != EAPOL_PAIR_MSG_1)
+	{
+		UCHAR			rcvd_mic[LEN_KEY_DESC_MIC];
+
+		// Record the received MIC for check later
+		NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+		NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+        if (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP)	// TKIP
+        {
+            HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic, MD5_DIGEST_SIZE);
+        }
+        else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)	// AES
+        {
+            HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, digest, SHA1_DIGEST_SIZE);
+            NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+        }
+
+        if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
+        {
+			// send wireless event - for MIC different
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+			if (MsgType < EAPOL_GROUP_MSG_1)
+			{
+		DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
+			}
+
+			hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
+			hex_dump("Desired  MIC", mic, LEN_KEY_DESC_MIC);
+
+			return FALSE;
+        }
+	}
+
+	// 1. Decrypt the Key Data field if GTK is included.
+	// 2. Extract the context of the Key Data field if it exist.
+	// The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear.
+	// The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
+	if (CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen) > 0)
+	{
+		// Decrypt this field
+		if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
+		{
+			if(
+				(EapolKeyInfo.KeyDescVer == DESC_TYPE_AES))
+			{
+				// AES
+				AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA,
+									CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen),
+									pMsg->KeyDesc.KeyData);
+			}
+			else
+			{
+				INT	i;
+				UCHAR   Key[32];
+				// Decrypt TKIP GTK
+				// Construct 32 bytes RC4 Key
+				NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
+				NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
+				ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+				//discard first 256 bytes
+				for(i = 0; i < 256; i++)
+					ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+				// Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+				ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA,
+								pMsg->KeyDesc.KeyData,
+								CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen));
+			}
+
+			if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
+				GroupKeyIndex = EapolKeyInfo.KeyIndex;
+
+		}
+		else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
+		{
+			NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen));
+		}
+		else
+		{
+
+			return TRUE;
+		}
+
+		// Parse Key Data field to
+		// 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
+		// 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
+		// 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
+		if (!RTMPParseEapolKeyData(pAd, KEYDATA,
+								  CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen),
+								  GroupKeyIndex, MsgType, bWPA2, pEntry))
+		{
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+
+}

+ 47 - 23
drivers/staging/rt2860/common/cmm_sync.c

@@ -25,7 +25,7 @@
  *************************************************************************
 
 	Module Name:
-	sync.c
+	cmm_sync.c
 
 	Abstract:
 
@@ -64,11 +64,16 @@ UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
 UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
 UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
 UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
-UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173};
 UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
 UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
 UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
 UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
+UCHAR A_BAND_REGION_12_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+UCHAR A_BAND_REGION_13_CHANNEL_LIST[]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161};
+UCHAR A_BAND_REGION_14_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_15_CHANNEL_LIST[]={149, 153, 157, 161, 165, 169, 173};
+
 
 //BaSizeArray follows the 802.11n definition as MaxRxFactor.  2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
 UCHAR BaSizeArray[4] = {8,16,32,64};
@@ -200,7 +205,22 @@ VOID BuildChannelList(
 				num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
 				pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
 				break;
-
+			case REGION_12_A_BAND:
+				num = sizeof(A_BAND_REGION_12_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
+				break;
+			case REGION_13_A_BAND:
+				num = sizeof(A_BAND_REGION_13_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
+				break;
+			case REGION_14_A_BAND:
+				num = sizeof(A_BAND_REGION_14_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
+				break;
+			case REGION_15_A_BAND:
+				num = sizeof(A_BAND_REGION_15_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
+				break;
 			default:            // Error. should never happen
 				DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
 				break;
@@ -383,8 +403,11 @@ VOID ScanNextChannel(
 	PHEADER_802_11  pHdr80211;
 	UINT			ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
 
+	{
 	if (MONITOR_ON(pAd))
 		return;
+	}
+
 
 	if (pAd->MlmeAux.Channel == 0)
 	{
@@ -409,6 +432,19 @@ VOID ScanNextChannel(
 		}
 
 		{
+#ifdef RT2860
+			/*
+				If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp.
+				In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux.
+				To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here.
+			*/
+			if (ADHOC_ON(pAd))
+			{
+				NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+				pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
+				NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen);
+			}
+#endif // RT2860 //
 			//
 			// To prevent data lost.
 			// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
@@ -438,29 +474,26 @@ VOID ScanNextChannel(
 			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
 		}
 
+
 		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
 	}
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 	else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
 	{
 		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 		MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
 	}
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
 	else
 	{
 		{
 		// BBP and RF are not accessible in PS mode, we has to wake them up first
 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
-				AsicForceWakeup(pAd, FROM_TX);
-#endif
-#ifdef RT2870
 			AsicForceWakeup(pAd, TRUE);
-#endif
+
 			// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
 			if (pAd->StaCfg.Psm == PWR_SAVE)
-				MlmeSetPsmBit(pAd, PWR_ACTIVE);
+				RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
 		}
 
 		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
@@ -487,16 +520,6 @@ VOID ScanNextChannel(
 		// Chnage the channel scan time for CISCO stuff based on its IAPP announcement
 		if (ScanType == FAST_SCAN_ACTIVE)
 			RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
-		else if (((ScanType == SCAN_CISCO_ACTIVE) ||
-				(ScanType == SCAN_CISCO_PASSIVE) ||
-				(ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
-				(ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
-		{
-			if (pAd->StaCfg.CCXScanTime < 25)
-				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
-			else
-				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
-		}
 		else // must be SCAN_PASSIVE or SCAN_ACTIVE
 		{
 			if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
@@ -512,8 +535,9 @@ VOID ScanNextChannel(
 				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
 		}
 
-		if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
-			(ScanType == SCAN_CISCO_ACTIVE))
+		if ((ScanType == SCAN_ACTIVE)
+			|| (ScanType == FAST_SCAN_ACTIVE)
+			)
 		{
 			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
 			if (NStatus != NDIS_STATUS_SUCCESS)

+ 8 - 712
drivers/staging/rt2860/common/rtmp_tkip.c → drivers/staging/rt2860/common/cmm_tkip.c

@@ -25,7 +25,7 @@
  *************************************************************************
 
 	Module Name:
-	rtmp_tkip.c
+	cmm_tkip.c
 
 	Abstract:
 
@@ -35,7 +35,7 @@
 	Paul Wu		02-25-02		Initial
 */
 
-#include "../rt_config.h"
+#include	"../rt_config.h"
 
 // Rotation functions on 32 bit values
 #define ROL32( A, n ) \
@@ -114,74 +114,6 @@ UINT Tkip_Sbox_Upper[256] =
 	0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
 };
 
-/*****************************/
-/******** 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);
-
-VOID xor_128(
-	IN  PUCHAR              a,
-	IN  PUCHAR              b,
-	OUT PUCHAR              out);
-
-VOID next_key(
-	IN  PUCHAR              key,
-	IN  INT                 round);
-
-VOID byte_sub(
-	IN  PUCHAR              in,
-	OUT PUCHAR              out);
-
-VOID shift_row(
-	IN  PUCHAR              in,
-	OUT PUCHAR              out);
-
-VOID mix_column(
-	IN  PUCHAR              in,
-	OUT PUCHAR              out);
-
-UCHAR RTMPCkipSbox(
-	IN  UCHAR               a);
 //
 // Expanded IV for TKIP function.
 //
@@ -330,7 +262,7 @@ VOID RTMPTkipSetMICKey(
 */
 VOID	RTMPTkipAppendByte(
 	IN	PTKIP_KEY_INFO	pTkip,
-	IN	UCHAR 			uChar)
+	IN	UCHAR			uChar)
 {
 	// Append the byte to our word-sized buffer
 	pTkip->M |= (uChar << (8* pTkip->nBytesInM));
@@ -464,6 +396,7 @@ VOID	RTMPInitTkipEngine(
 	tkipIv.IV16.field.rc2 = *pTSC;
 	tkipIv.IV16.field.CONTROL.field.ExtIV = 1;  // 0: non-extended IV, 1: an extended IV
 	tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
+//	tkipIv.IV32 = *(PULONG)(pTSC + 2);
 	NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4);   // Copy IV
 
 	*pIV16 = tkipIv.IV16.word;
@@ -577,75 +510,6 @@ BOOLEAN	RTMPTkipCompareMICValue(
 	return (TRUE);
 }
 
-/*
-	========================================================================
-
-	Routine	Description:
-		Compare MIC value of received MSDU
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pLLC		LLC header
-		pSrc        Pointer to the received Plain text data
-		pDA			Pointer to DA address
-		pSA			Pointer to SA address
-		pMICKey		pointer to MIC Key
-		Len         the length of the received plain text data exclude MIC value
-
-	Return Value:
-		TRUE        MIC value matched
-		FALSE       MIC value mismatched
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN	RTMPTkipCompareMICValueWithLLC(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pLLC,
-	IN	PUCHAR			pSrc,
-	IN	PUCHAR			pDA,
-	IN	PUCHAR			pSA,
-	IN	PUCHAR			pMICKey,
-	IN	UINT			Len)
-{
-	UCHAR	OldMic[8];
-	ULONG	Priority = 0;
-
-	// Init MIC value calculation
-	RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
-	// DA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
-	// SA
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
-	// Priority + 3 bytes of 0
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
-
-	// Start with LLC header
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
-
-	// Calculate MIC value from plain text data
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
-
-	// Get MIC valude from received frame
-	NdisMoveMemory(OldMic, pSrc + Len, 8);
-
-	// Get MIC value from decrypted plain data
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
-
-	// Move MIC value from MSDU, this steps should move to data path.
-	// Since the MIC value might cross MPDUs.
-	if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
-	{
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n"));  //MIC error.
-
-
-		return (FALSE);
-	}
-	return (TRUE);
-}
 /*
 	========================================================================
 
@@ -865,209 +729,6 @@ VOID RTMPTkipMixKey(
 }
 
 
-/************************************************/
-/* 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);
-
-}
-
-
-
-/************************************/
-/* 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 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);
-
-}
-
-
 //
 // TRUE: Success!
 // FALSE: Decrypt Error!
@@ -1102,12 +763,13 @@ BOOLEAN RTMPSoftDecryptTKIP(
 	ULONG			pnh;/* Most significant 32 bits of PN */
 	UINT			num_blocks;
 	UINT			payload_remainder;
-	ARCFOURCONTEXT 	ArcFourContext;
+	ARCFOURCONTEXT	ArcFourContext;
 	UINT			crc32 = 0;
 	UINT			trailfcs = 0;
 	UCHAR			MIC[8];
 	UCHAR			TrailMIC[8];
 
+
 	fc0 = *pData;
 	fc1 = *(pData + 1);
 
@@ -1211,376 +873,10 @@ BOOLEAN RTMPSoftDecryptTKIP(
 	if (!NdisEqualMemory(MIC, TrailMIC, 8))
 	{
 		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n"));	 //MIC error.
+		//RTMPReportMicError(pAd, &pWpaKey[KeyID]);	// marked by AlbertY @ 20060630
 		return (FALSE);
 	}
 
+	//DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");
 	return TRUE;
 }
-
-
-
-
-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;
-}
-
-/****************************************/
-/* aes128k128d()                        */
-/* Performs a 128 bit AES encrypt with  */
-/* 128 bit data.                        */
-/****************************************/
-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];
-	}
-}
-
-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 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 byte_sub(
-	IN  PUCHAR  in,
-	OUT PUCHAR  out)
-{
-	INT i;
-
-	for (i=0; i< 16; i++)
-	{
-		out[i] = RTMPCkipSbox(in[i]);
-	}
-}
-
-UCHAR RTMPCkipSbox(
-	IN  UCHAR   a)
-{
-	return SboxTable[(int)a];
-}
-
-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);
-}
-

+ 12 - 10
drivers/staging/rt2860/common/rtmp_wep.c → drivers/staging/rt2860/common/cmm_wep.c

@@ -35,7 +35,7 @@
 	Paul Wu		10-28-02		Initial
 */
 
-#include "../rt_config.h"
+#include	"../rt_config.h"
 
 UINT FCSTAB_32[256] =
 {
@@ -105,6 +105,15 @@ UINT FCSTAB_32[256] =
 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
 };
 
+/*
+UCHAR   WEPKEY[] = {
+		//IV
+		0x00, 0x11, 0x22,
+		//WEP KEY
+		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+	};
+ */
+
 /*
 	========================================================================
 
@@ -144,12 +153,6 @@ VOID	RTMPInitWepEngine(
 
 	pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.
 
-    if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
-    {
-        ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen);  //INIT SBOX, KEYLEN+3(IV)
-        NdisMoveMemory(pDest, pKey, 3);  //Append Init Vector
-    }
-    else
     {
 		NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
 
@@ -215,7 +218,7 @@ VOID	RTMPEncryptData(
 	========================================================================
 */
 BOOLEAN	RTMPSoftDecryptWEP(
-	IN PRTMP_ADAPTER 	pAd,
+	IN PRTMP_ADAPTER	pAd,
 	IN PUCHAR			pData,
 	IN ULONG			DataByteCnt,
 	IN PCIPHER_KEY		pGroupKey)
@@ -229,7 +232,7 @@ BOOLEAN	RTMPSoftDecryptWEP(
 		//WEP KEY
 		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
 	};
-	UCHAR 	*pPayload = (UCHAR *)pData + LENGTH_802_11;
+	UCHAR	*pPayload = (UCHAR *)pData + LENGTH_802_11;
 	ULONG	payload_len = DataByteCnt - LENGTH_802_11;
 
 	NdisMoveMemory(WEPKEY, pPayload, 3);    //Get WEP IV
@@ -494,4 +497,3 @@ VOID	RTMPSetICV(
 
 	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
 }
-

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 2487 - 349
drivers/staging/rt2860/common/cmm_wpa.c


+ 194 - 0
drivers/staging/rt2860/common/crypt_hmac.c

@@ -0,0 +1,194 @@
+/*
+ *************************************************************************
+ * 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.             *
+ *                                                                       *
+ *************************************************************************/
+
+#include "../crypt_hmac.h"
+
+
+#ifdef HMAC_SHA1_SUPPORT
+/*
+========================================================================
+Routine Description:
+    HMAC using SHA1 hash function
+
+Arguments:
+    key             Secret key
+    key_len         The length of the key in bytes
+    message         Message context
+    message_len     The length of message in bytes
+    macLen          Request the length of message authentication code
+
+Return Value:
+    mac             Message authentication code
+
+Note:
+    None
+========================================================================
+*/
+VOID HMAC_SHA1 (
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen)
+{
+    SHA1_CTX_STRUC sha_ctx1;
+    SHA1_CTX_STRUC sha_ctx2;
+    UINT8 K0[SHA1_BLOCK_SIZE];
+    UINT8 Digest[SHA1_DIGEST_SIZE];
+    UINT index;
+
+    NdisZeroMemory(&sha_ctx1, sizeof(SHA1_CTX_STRUC));
+    NdisZeroMemory(&sha_ctx2, sizeof(SHA1_CTX_STRUC));
+    /*
+     * If the length of K = B(Block size): K0 = K.
+     * If the length of K > B: hash K to obtain an L byte string,
+     * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+     * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+     */
+    NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
+    if (KeyLen <= SHA1_BLOCK_SIZE)
+        NdisMoveMemory(K0, Key, KeyLen);
+    else
+        RT_SHA1(Key, KeyLen, K0);
+    /* End of if */
+
+    /* Exclusive-Or K0 with ipad */
+    /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
+    for (index = 0; index < SHA1_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36;
+        /* End of for */
+
+    RT_SHA1_Init(&sha_ctx1);
+    /* H(K0^ipad) */
+    SHA1_Append(&sha_ctx1, K0, sizeof(K0));
+    /* H((K0^ipad)||text) */
+    SHA1_Append(&sha_ctx1, Message, MessageLen);
+    SHA1_End(&sha_ctx1, Digest);
+
+    /* Exclusive-Or K0 with opad and remove ipad */
+    /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
+    for (index = 0; index < SHA1_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36^0x5c;
+        /* End of for */
+
+    RT_SHA1_Init(&sha_ctx2);
+    /* H(K0^opad) */
+    SHA1_Append(&sha_ctx2, K0, sizeof(K0));
+    /* H( (K0^opad) || H((K0^ipad)||text) ) */
+    SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
+    SHA1_End(&sha_ctx2, Digest);
+
+    if (MACLen > SHA1_DIGEST_SIZE)
+        NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
+    else
+        NdisMoveMemory(MAC, Digest, MACLen);
+} /* End of HMAC_SHA1 */
+#endif /* HMAC_SHA1_SUPPORT */
+
+#ifdef HMAC_MD5_SUPPORT
+/*
+========================================================================
+Routine Description:
+    HMAC using MD5 hash function
+
+Arguments:
+    key             Secret key
+    key_len         The length of the key in bytes
+    message         Message context
+    message_len     The length of message in bytes
+    macLen          Request the length of message authentication code
+
+Return Value:
+    mac             Message authentication code
+
+Note:
+    None
+========================================================================
+*/
+VOID HMAC_MD5(
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen)
+{
+    MD5_CTX_STRUC md5_ctx1;
+    MD5_CTX_STRUC md5_ctx2;
+    UINT8 K0[MD5_BLOCK_SIZE];
+    UINT8 Digest[MD5_DIGEST_SIZE];
+    UINT index;
+
+    NdisZeroMemory(&md5_ctx1, sizeof(MD5_CTX_STRUC));
+    NdisZeroMemory(&md5_ctx2, sizeof(MD5_CTX_STRUC));
+    /*
+     * If the length of K = B(Block size): K0 = K.
+     * If the length of K > B: hash K to obtain an L byte string,
+     * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+     * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+     */
+    NdisZeroMemory(K0, MD5_BLOCK_SIZE);
+    if (KeyLen <= MD5_BLOCK_SIZE) {
+        NdisMoveMemory(K0, Key, KeyLen);
+    } else {
+        RT_MD5(Key, KeyLen, K0);
+    }
+
+    /* Exclusive-Or K0 with ipad */
+    /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
+    for (index = 0; index < MD5_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36;
+        /* End of for */
+
+    MD5_Init(&md5_ctx1);
+    /* H(K0^ipad) */
+    MD5_Append(&md5_ctx1, K0, sizeof(K0));
+    /* H((K0^ipad)||text) */
+    MD5_Append(&md5_ctx1, Message, MessageLen);
+    MD5_End(&md5_ctx1, Digest);
+
+    /* Exclusive-Or K0 with opad and remove ipad */
+    /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
+    for (index = 0; index < MD5_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36^0x5c;
+        /* End of for */
+
+    MD5_Init(&md5_ctx2);
+    /* H(K0^opad) */
+    MD5_Append(&md5_ctx2, K0, sizeof(K0));
+    /* H( (K0^opad) || H((K0^ipad)||text) ) */
+    MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
+    MD5_End(&md5_ctx2, Digest);
+
+    if (MACLen > MD5_DIGEST_SIZE)
+        NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
+    else
+        NdisMoveMemory(MAC, Digest, MACLen);
+} /* End of HMAC_SHA256 */
+#endif /* HMAC_MD5_SUPPORT */
+
+/* End of crypt_hmac.c */

+ 352 - 0
drivers/staging/rt2860/common/crypt_md5.c

@@ -0,0 +1,352 @@
+/*
+ *************************************************************************
+ * 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.             *
+ *                                                                       *
+ *************************************************************************/
+
+#include "../crypt_md5.h"
+
+#ifdef MD5_SUPPORT
+/*
+ * F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))
+#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
+
+#define ROUND1(a, b, c, d, x, s, ac) {          \
+    (a) += F((b),(c),(d)) + (x) + (UINT32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+#define ROUND2(a, b, c, d, x, s, ac) {          \
+    (a) += G((b),(c),(d)) + (x) + (UINT32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+#define ROUND3(a, b, c, d, x, s, ac) {          \
+    (a) += H((b),(c),(d)) + (x) + (UINT32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+#define ROUND4(a, b, c, d, x, s, ac) {          \
+    (a) += I((b),(c),(d)) + (x) + (UINT32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+static const UINT32 MD5_DefaultHashValue[4] = {
+    0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
+};
+#endif /* MD5_SUPPORT */
+
+
+#ifdef MD5_SUPPORT
+/*
+========================================================================
+Routine Description:
+    Initial Md5_CTX_STRUC
+
+Arguments:
+    pMD5_CTX        Pointer to Md5_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID MD5_Init (
+    IN  MD5_CTX_STRUC *pMD5_CTX)
+{
+    NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
+        sizeof(MD5_DefaultHashValue));
+    NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
+    pMD5_CTX->BlockLen   = 0;
+    pMD5_CTX->MessageLen = 0;
+} /* End of MD5_Init */
+
+
+/*
+========================================================================
+Routine Description:
+    MD5 computation for one block (512 bits)
+
+Arguments:
+    pMD5_CTX        Pointer to Md5_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
+========================================================================
+*/
+VOID MD5_Hash (
+    IN  MD5_CTX_STRUC *pMD5_CTX)
+{
+    UINT32 X_i;
+    UINT32 X[16];
+    UINT32 a,b,c,d;
+
+    /* Prepare the message schedule, {X_i} */
+    NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
+    for (X_i = 0; X_i < 16; X_i++)
+        X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */
+        /* End of for */
+
+    /* MD5 hash computation */
+    /* Initialize the working variables */
+    a = pMD5_CTX->HashValue[0];
+    b = pMD5_CTX->HashValue[1];
+    c = pMD5_CTX->HashValue[2];
+    d = pMD5_CTX->HashValue[3];
+
+    /*
+     *  Round 1
+     *  Let [abcd k s i] denote the operation
+     *  a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
+     */
+    ROUND1(a, b, c, d, X[ 0],  7, 0xd76aa478); /* 1 */
+    ROUND1(d, a, b, c, X[ 1], 12, 0xe8c7b756); /* 2 */
+    ROUND1(c, d, a, b, X[ 2], 17, 0x242070db); /* 3 */
+    ROUND1(b, c, d, a, X[ 3], 22, 0xc1bdceee); /* 4 */
+    ROUND1(a, b, c, d, X[ 4],  7, 0xf57c0faf); /* 5 */
+    ROUND1(d, a, b, c, X[ 5], 12, 0x4787c62a); /* 6 */
+    ROUND1(c, d, a, b, X[ 6], 17, 0xa8304613); /* 7 */
+    ROUND1(b, c, d, a, X[ 7], 22, 0xfd469501); /* 8 */
+    ROUND1(a, b, c, d, X[ 8],  7, 0x698098d8); /* 9 */
+    ROUND1(d, a, b, c, X[ 9], 12, 0x8b44f7af); /* 10 */
+    ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */
+    ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */
+    ROUND1(a, b, c, d, X[12],  7, 0x6b901122); /* 13 */
+    ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */
+    ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */
+    ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */
+
+    /*
+     *  Round 2
+     *  Let [abcd k s i] denote the operation
+     *  a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
+     */
+    ROUND2(a, b, c, d, X[ 1],  5, 0xf61e2562); /* 17 */
+    ROUND2(d, a, b, c, X[ 6],  9, 0xc040b340); /* 18 */
+    ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */
+    ROUND2(b, c, d, a, X[ 0], 20, 0xe9b6c7aa); /* 20 */
+    ROUND2(a, b, c, d, X[ 5],  5, 0xd62f105d); /* 21 */
+    ROUND2(d, a, b, c, X[10],  9,  0x2441453); /* 22 */
+    ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */
+    ROUND2(b, c, d, a, X[ 4], 20, 0xe7d3fbc8); /* 24 */
+    ROUND2(a, b, c, d, X[ 9],  5, 0x21e1cde6); /* 25 */
+    ROUND2(d, a, b, c, X[14],  9, 0xc33707d6); /* 26 */
+    ROUND2(c, d, a, b, X[ 3], 14, 0xf4d50d87); /* 27 */
+    ROUND2(b, c, d, a, X[ 8], 20, 0x455a14ed); /* 28 */
+    ROUND2(a, b, c, d, X[13],  5, 0xa9e3e905); /* 29 */
+    ROUND2(d, a, b, c, X[ 2],  9, 0xfcefa3f8); /* 30 */
+    ROUND2(c, d, a, b, X[ 7], 14, 0x676f02d9); /* 31 */
+    ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */
+
+    /*
+     *  Round 3
+     *  Let [abcd k s t] denote the operation
+     *  a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
+     */
+    ROUND3(a, b, c, d, X[ 5],  4, 0xfffa3942); /* 33 */
+    ROUND3(d, a, b, c, X[ 8], 11, 0x8771f681); /* 34 */
+    ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */
+    ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */
+    ROUND3(a, b, c, d, X[ 1],  4, 0xa4beea44); /* 37 */
+    ROUND3(d, a, b, c, X[ 4], 11, 0x4bdecfa9); /* 38 */
+    ROUND3(c, d, a, b, X[ 7], 16, 0xf6bb4b60); /* 39 */
+    ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */
+    ROUND3(a, b, c, d, X[13],  4, 0x289b7ec6); /* 41 */
+    ROUND3(d, a, b, c, X[ 0], 11, 0xeaa127fa); /* 42 */
+    ROUND3(c, d, a, b, X[ 3], 16, 0xd4ef3085); /* 43 */
+    ROUND3(b, c, d, a, X[ 6], 23,  0x4881d05); /* 44 */
+    ROUND3(a, b, c, d, X[ 9],  4, 0xd9d4d039); /* 45 */
+    ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */
+    ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */
+    ROUND3(b, c, d, a, X[ 2], 23, 0xc4ac5665); /* 48 */
+
+    /*
+     *  Round 4
+     *  Let [abcd k s t] denote the operation
+     *  a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
+     */
+    ROUND4(a, b, c, d, X[ 0],  6, 0xf4292244); /* 49 */
+    ROUND4(d, a, b, c, X[ 7], 10, 0x432aff97); /* 50 */
+    ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */
+    ROUND4(b, c, d, a, X[ 5], 21, 0xfc93a039); /* 52 */
+    ROUND4(a, b, c, d, X[12],  6, 0x655b59c3); /* 53 */
+    ROUND4(d, a, b, c, X[ 3], 10, 0x8f0ccc92); /* 54 */
+    ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */
+    ROUND4(b, c, d, a, X[ 1], 21, 0x85845dd1); /* 56 */
+    ROUND4(a, b, c, d, X[ 8],  6, 0x6fa87e4f); /* 57 */
+    ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */
+    ROUND4(c, d, a, b, X[ 6], 15, 0xa3014314); /* 59 */
+    ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */
+    ROUND4(a, b, c, d, X[ 4],  6, 0xf7537e82); /* 61 */
+    ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */
+    ROUND4(c, d, a, b, X[ 2], 15, 0x2ad7d2bb); /* 63 */
+    ROUND4(b, c, d, a, X[ 9], 21, 0xeb86d391); /* 64 */
+
+    /* Compute the i^th intermediate hash value H^(i) */
+    pMD5_CTX->HashValue[0] += a;
+    pMD5_CTX->HashValue[1] += b;
+    pMD5_CTX->HashValue[2] += c;
+    pMD5_CTX->HashValue[3] += d;
+
+    NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
+    pMD5_CTX->BlockLen = 0;
+} /* End of MD5_Hash */
+
+
+/*
+========================================================================
+Routine Description:
+    The message is appended to block. If block size > 64 bytes, the MD5_Hash
+will be called.
+
+Arguments:
+    pMD5_CTX        Pointer to MD5_CTX_STRUC
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID MD5_Append (
+    IN  MD5_CTX_STRUC *pMD5_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen)
+{
+    UINT appendLen = 0;
+    UINT diffLen = 0;
+
+    while (appendLen != MessageLen) {
+        diffLen = MessageLen - appendLen;
+        if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
+            NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
+                Message + appendLen, diffLen);
+            pMD5_CTX->BlockLen += diffLen;
+            appendLen += diffLen;
+        }
+        else
+        {
+            NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
+                Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
+            appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
+            pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
+            MD5_Hash(pMD5_CTX);
+        } /* End of if */
+    } /* End of while */
+    pMD5_CTX->MessageLen += MessageLen;
+} /* End of MD5_Append */
+
+
+/*
+========================================================================
+Routine Description:
+    1. Append bit 1 to end of the message
+    2. Append the length of message in rightmost 64 bits
+    3. Transform the Hash Value to digest message
+
+Arguments:
+    pMD5_CTX        Pointer to MD5_CTX_STRUC
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID MD5_End (
+    IN  MD5_CTX_STRUC *pMD5_CTX,
+    OUT UINT8 DigestMessage[])
+{
+    UINT index;
+    UINT64 message_length_bits;
+
+    /* append 1 bits to end of the message */
+    NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
+
+    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+    if (pMD5_CTX->BlockLen > 55)
+        MD5_Hash(pMD5_CTX);
+        /* End of if */
+
+    /* Append the length of message in rightmost 64 bits */
+    message_length_bits = pMD5_CTX->MessageLen*8;
+    message_length_bits = cpu2le64(message_length_bits);
+    NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
+    MD5_Hash(pMD5_CTX);
+
+    /* Return message digest, transform the UINT32 hash value to bytes */
+    for (index = 0; index < 4;index++)
+        pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]);
+        /* End of for */
+    NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
+} /* End of MD5_End */
+
+
+/*
+========================================================================
+Routine Description:
+    MD5 algorithm
+
+Arguments:
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID RT_MD5 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[])
+{
+    MD5_CTX_STRUC md5_ctx;
+
+    NdisZeroMemory(&md5_ctx, sizeof(MD5_CTX_STRUC));
+    MD5_Init(&md5_ctx);
+    MD5_Append(&md5_ctx, Message, MessageLen);
+    MD5_End(&md5_ctx, DigestMessage);
+} /* End of RT_MD5 */
+
+#endif /* MD5_SUPPORT */
+
+/* End of crypt_md5.c */

+ 535 - 0
drivers/staging/rt2860/common/crypt_sha2.c

@@ -0,0 +1,535 @@
+/*
+ *************************************************************************
+ * 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.             *
+ *                                                                       *
+ *************************************************************************/
+
+#include "../crypt_sha2.h"
+
+/* Basic operations */
+#define SHR(x,n) (x >> n) /* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTR(x,n,w) ((x >> n) | (x << (w - n))) /* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) /* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTR32(x,n) ROTR(x,n,32) /* 32 bits word */
+#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
+
+/* Basic functions */
+#define Ch(x,y,z) ((x & y) ^ ((~x) & z))
+#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
+#define Parity(x,y,z) (x ^ y ^ z)
+
+#ifdef SHA1_SUPPORT
+/* SHA1 constants */
+#define SHA1_MASK 0x0000000f
+static const UINT32 SHA1_K[4] = {
+    0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL
+};
+static const UINT32 SHA1_DefaultHashValue[5] = {
+    0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
+};
+#endif /* SHA1_SUPPORT */
+
+
+#ifdef SHA256_SUPPORT
+/* SHA256 functions */
+#define Zsigma_256_0(x) (ROTR32(x,2) ^ ROTR32(x,13) ^ ROTR32(x,22))
+#define Zsigma_256_1(x) (ROTR32(x,6) ^ ROTR32(x,11) ^ ROTR32(x,25))
+#define Sigma_256_0(x)  (ROTR32(x,7) ^ ROTR32(x,18) ^ SHR(x,3))
+#define Sigma_256_1(x)  (ROTR32(x,17) ^ ROTR32(x,19) ^ SHR(x,10))
+/* SHA256 constants */
+static const UINT32 SHA256_K[64] = {
+    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+    0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+    0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+    0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+    0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+    0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+    0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+    0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+    0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+    0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+    0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+    0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+    0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+static const UINT32 SHA256_DefaultHashValue[8] = {
+    0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
+    0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
+};
+#endif /* SHA256_SUPPORT */
+
+
+#ifdef SHA1_SUPPORT
+/*
+========================================================================
+Routine Description:
+    Initial SHA1_CTX_STRUC
+
+Arguments:
+    pSHA_CTX        Pointer to SHA1_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID RT_SHA1_Init (
+    IN  SHA1_CTX_STRUC *pSHA_CTX)
+{
+    NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue,
+        sizeof(SHA1_DefaultHashValue));
+    NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+    pSHA_CTX->MessageLen = 0;
+    pSHA_CTX->BlockLen   = 0;
+} /* End of RT_SHA1_Init */
+
+
+/*
+========================================================================
+Routine Description:
+    SHA1 computation for one block (512 bits)
+
+Arguments:
+    pSHA_CTX        Pointer to SHA1_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA1_Hash (
+    IN  SHA1_CTX_STRUC *pSHA_CTX)
+{
+    UINT32 W_i,t,s;
+    UINT32 W[16];
+    UINT32 a,b,c,d,e,T,f_t = 0;
+
+    /* Prepare the message schedule, {W_i}, 0 < t < 15 */
+    NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+    for (W_i = 0; W_i < 16; W_i++)
+        W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
+        /* End of for */
+
+    /* SHA256 hash computation */
+    /* Initialize the working variables */
+    a = pSHA_CTX->HashValue[0];
+    b = pSHA_CTX->HashValue[1];
+    c = pSHA_CTX->HashValue[2];
+    d = pSHA_CTX->HashValue[3];
+    e = pSHA_CTX->HashValue[4];
+
+    /* 80 rounds */
+    for (t = 0;t < 80;t++) {
+        s = t & SHA1_MASK;
+        if (t > 15) { /* Prepare the message schedule, {W_i}, 16 < t < 79 */
+            W[s] = (W[(s+13) & SHA1_MASK]) ^ (W[(s+8) & SHA1_MASK]) ^ (W[(s+2) & SHA1_MASK]) ^ W[s];
+            W[s] = ROTL32(W[s],1);
+        } /* End of if */
+        switch (t / 20) {
+            case 0:
+                 f_t = Ch(b,c,d);
+                 break;
+            case 1:
+                 f_t = Parity(b,c,d);
+                 break;
+            case 2:
+                 f_t = Maj(b,c,d);
+                 break;
+            case 3:
+                 f_t = Parity(b,c,d);
+                 break;
+        } /* End of switch */
+        T = ROTL32(a,5) + f_t + e + SHA1_K[t / 20] + W[s];
+        e = d;
+        d = c;
+        c = ROTL32(b,30);
+        b = a;
+        a = T;
+     } /* End of for */
+
+     /* Compute the i^th intermediate hash value H^(i) */
+     pSHA_CTX->HashValue[0] += a;
+     pSHA_CTX->HashValue[1] += b;
+     pSHA_CTX->HashValue[2] += c;
+     pSHA_CTX->HashValue[3] += d;
+     pSHA_CTX->HashValue[4] += e;
+
+    NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+    pSHA_CTX->BlockLen = 0;
+} /* End of SHA1_Hash */
+
+
+/*
+========================================================================
+Routine Description:
+    The message is appended to block. If block size > 64 bytes, the SHA1_Hash
+will be called.
+
+Arguments:
+    pSHA_CTX        Pointer to SHA1_CTX_STRUC
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA1_Append (
+    IN  SHA1_CTX_STRUC *pSHA_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen)
+{
+    UINT appendLen = 0;
+    UINT diffLen   = 0;
+
+    while (appendLen != MessageLen) {
+        diffLen = MessageLen - appendLen;
+        if ((pSHA_CTX->BlockLen + diffLen) <  SHA1_BLOCK_SIZE) {
+            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+                Message + appendLen, diffLen);
+            pSHA_CTX->BlockLen += diffLen;
+            appendLen += diffLen;
+        }
+        else
+        {
+            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+                Message + appendLen, SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
+            appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
+            pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE;
+            SHA1_Hash(pSHA_CTX);
+        } /* End of if */
+    } /* End of while */
+    pSHA_CTX->MessageLen += MessageLen;
+} /* End of SHA1_Append */
+
+
+/*
+========================================================================
+Routine Description:
+    1. Append bit 1 to end of the message
+    2. Append the length of message in rightmost 64 bits
+    3. Transform the Hash Value to digest message
+
+Arguments:
+    pSHA_CTX        Pointer to SHA1_CTX_STRUC
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA1_End (
+    IN  SHA1_CTX_STRUC *pSHA_CTX,
+    OUT UINT8 DigestMessage[])
+{
+    UINT index;
+    UINT64 message_length_bits;
+
+    /* Append bit 1 to end of the message */
+    NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
+
+    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+    if (pSHA_CTX->BlockLen > 55)
+        SHA1_Hash(pSHA_CTX);
+        /* End of if */
+
+    /* Append the length of message in rightmost 64 bits */
+    message_length_bits = pSHA_CTX->MessageLen*8;
+    message_length_bits = cpu2be64(message_length_bits);
+    NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
+    SHA1_Hash(pSHA_CTX);
+
+    /* Return message digest, transform the UINT32 hash value to bytes */
+    for (index = 0; index < 5;index++)
+        pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
+        /* End of for */
+    NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE);
+} /* End of SHA1_End */
+
+
+/*
+========================================================================
+Routine Description:
+    SHA1 algorithm
+
+Arguments:
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID RT_SHA1 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[])
+{
+
+    SHA1_CTX_STRUC sha_ctx;
+
+    NdisZeroMemory(&sha_ctx, sizeof(SHA1_CTX_STRUC));
+    RT_SHA1_Init(&sha_ctx);
+    SHA1_Append(&sha_ctx, Message, MessageLen);
+    SHA1_End(&sha_ctx, DigestMessage);
+} /* End of RT_SHA1 */
+#endif /* SHA1_SUPPORT */
+
+
+#ifdef SHA256_SUPPORT
+/*
+========================================================================
+Routine Description:
+    Initial SHA256_CTX_STRUC
+
+Arguments:
+    pSHA_CTX    Pointer to SHA256_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA256_Init (
+    IN  SHA256_CTX_STRUC *pSHA_CTX)
+{
+    NdisMoveMemory(pSHA_CTX->HashValue, SHA256_DefaultHashValue,
+        sizeof(SHA256_DefaultHashValue));
+    NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
+    pSHA_CTX->MessageLen = 0;
+    pSHA_CTX->BlockLen   = 0;
+} /* End of SHA256_Init */
+
+
+/*
+========================================================================
+Routine Description:
+    SHA256 computation for one block (512 bits)
+
+Arguments:
+    pSHA_CTX    Pointer to SHA256_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA256_Hash (
+    IN  SHA256_CTX_STRUC *pSHA_CTX)
+{
+    UINT32 W_i,t;
+    UINT32 W[64];
+    UINT32 a,b,c,d,e,f,g,h,T1,T2;
+
+    /* Prepare the message schedule, {W_i}, 0 < t < 15 */
+    NdisMoveMemory(W, pSHA_CTX->Block, SHA256_BLOCK_SIZE);
+    for (W_i = 0; W_i < 16; W_i++)
+        W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
+        /* End of for */
+
+    /* SHA256 hash computation */
+    /* Initialize the working variables */
+    a = pSHA_CTX->HashValue[0];
+    b = pSHA_CTX->HashValue[1];
+    c = pSHA_CTX->HashValue[2];
+    d = pSHA_CTX->HashValue[3];
+    e = pSHA_CTX->HashValue[4];
+    f = pSHA_CTX->HashValue[5];
+    g = pSHA_CTX->HashValue[6];
+    h = pSHA_CTX->HashValue[7];
+
+    /* 64 rounds */
+    for (t = 0;t < 64;t++) {
+        if (t > 15) /* Prepare the message schedule, {W_i}, 16 < t < 63 */
+            W[t] = Sigma_256_1(W[t-2]) + W[t-7] + Sigma_256_0(W[t-15]) + W[t-16];
+            /* End of if */
+        T1 = h + Zsigma_256_1(e) + Ch(e,f,g) + SHA256_K[t] + W[t];
+        T2 = Zsigma_256_0(a) + Maj(a,b,c);
+        h = g;
+        g = f;
+        f = e;
+        e = d + T1;
+        d = c;
+        c = b;
+        b = a;
+        a = T1 + T2;
+     } /* End of for */
+
+     /* Compute the i^th intermediate hash value H^(i) */
+     pSHA_CTX->HashValue[0] += a;
+     pSHA_CTX->HashValue[1] += b;
+     pSHA_CTX->HashValue[2] += c;
+     pSHA_CTX->HashValue[3] += d;
+     pSHA_CTX->HashValue[4] += e;
+     pSHA_CTX->HashValue[5] += f;
+     pSHA_CTX->HashValue[6] += g;
+     pSHA_CTX->HashValue[7] += h;
+
+    NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
+    pSHA_CTX->BlockLen = 0;
+} /* End of SHA256_Hash */
+
+
+/*
+========================================================================
+Routine Description:
+    The message is appended to block. If block size > 64 bytes, the SHA256_Hash
+will be called.
+
+Arguments:
+    pSHA_CTX    Pointer to SHA256_CTX_STRUC
+    message     Message context
+    messageLen  The length of message in bytes
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA256_Append (
+    IN  SHA256_CTX_STRUC *pSHA_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen)
+{
+    UINT appendLen = 0;
+    UINT diffLen   = 0;
+
+    while (appendLen != MessageLen) {
+        diffLen = MessageLen - appendLen;
+        if ((pSHA_CTX->BlockLen + diffLen) <  SHA256_BLOCK_SIZE) {
+            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+                Message + appendLen, diffLen);
+            pSHA_CTX->BlockLen += diffLen;
+            appendLen += diffLen;
+        }
+        else
+        {
+            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+                Message + appendLen, SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
+            appendLen += (SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
+            pSHA_CTX->BlockLen = SHA256_BLOCK_SIZE;
+            SHA256_Hash(pSHA_CTX);
+        } /* End of if */
+    } /* End of while */
+    pSHA_CTX->MessageLen += MessageLen;
+} /* End of SHA256_Append */
+
+
+/*
+========================================================================
+Routine Description:
+    1. Append bit 1 to end of the message
+    2. Append the length of message in rightmost 64 bits
+    3. Transform the Hash Value to digest message
+
+Arguments:
+    pSHA_CTX        Pointer to SHA256_CTX_STRUC
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA256_End (
+    IN  SHA256_CTX_STRUC *pSHA_CTX,
+    OUT UINT8 DigestMessage[])
+{
+    UINT index;
+    UINT64 message_length_bits;
+
+    /* Append bit 1 to end of the message */
+    NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
+
+    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+    if (pSHA_CTX->BlockLen > 55)
+        SHA256_Hash(pSHA_CTX);
+        /* End of if */
+
+    /* Append the length of message in rightmost 64 bits */
+    message_length_bits = pSHA_CTX->MessageLen*8;
+    message_length_bits = cpu2be64(message_length_bits);
+    NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
+    SHA256_Hash(pSHA_CTX);
+
+    /* Return message digest, transform the UINT32 hash value to bytes */
+    for (index = 0; index < 8;index++)
+        pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
+        /* End of for */
+    NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA256_DIGEST_SIZE);
+} /* End of SHA256_End */
+
+
+/*
+========================================================================
+Routine Description:
+    SHA256 algorithm
+
+Arguments:
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID RT_SHA256 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[])
+{
+    SHA256_CTX_STRUC sha_ctx;
+
+    NdisZeroMemory(&sha_ctx, sizeof(SHA256_CTX_STRUC));
+    SHA256_Init(&sha_ctx);
+    SHA256_Append(&sha_ctx, Message, MessageLen);
+    SHA256_End(&sha_ctx, DigestMessage);
+} /* End of RT_SHA256 */
+#endif /* SHA256_SUPPORT */
+
+/* End of crypt_sha2.c */

+ 42 - 24
drivers/staging/rt2860/common/dfs.c

@@ -33,7 +33,6 @@
     Revision History:
     Who       When            What
     --------  ----------      ----------------------------------------------
-    Fonchi    03-12-2007      created
 */
 
 #include "../rt_config.h"
@@ -46,10 +45,15 @@ typedef struct _RADAR_DURATION_TABLE
 } RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
 
 
-static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
+
+UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
 {
 	{9, 250, 250, 250},		// CE
+#ifdef DFS_FCC_BW40_FIX
+	{1, 250, 250, 250},		// FCC
+#else
 	{4, 250, 250, 250},		// FCC
+#endif
 	{4, 250, 250, 250},		// JAP
 	{15, 250, 250, 250},	// JAP_W53
 	{4, 250, 250, 250}		// JAP_W56
@@ -80,11 +84,32 @@ VOID BbpRadarDetectionStart(
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
 
+#ifdef MERGE_ARCH_TEAM
+	if ((pAd->CommonCfg.RadarDetect.RDDurRegion == JAP) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56))
+	{
+		pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
+		pAd->CommonCfg.RadarDetect.RDDurRegion = JapRadarType(pAd);
+		if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56)
+		{
+			pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+		}
+		else if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53)
+		{
+			pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
+		}
+	}
+#endif // MERGE_ARCH_TEAM //
+
 	RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
 			(RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
 
+#ifdef MERGE_ARCH_TEAM
+
+
+#else // Original RT28xx source code.
 	RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
 	RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
+#endif // MERGE_ARCH_TEAM //
 
 	RadarDetectionStart(pAd, 0, RadarPeriod);
 	return;
@@ -143,6 +168,17 @@ VOID RadarDetectionStart(
 			CtsProtect = 0x03;
 			break;
 
+		case JAP:
+			{
+				UCHAR RDDurRegion;
+				RDDurRegion = JapRadarType(pAd);
+				if (RDDurRegion == JAP_W56)
+					CtsProtect = 0x03;
+				else
+					CtsProtect = 0x02;
+				break;
+			}
+
 		case CE:
 		case JAP_W53:
 		default:
@@ -210,7 +246,6 @@ BOOLEAN RadarChannelCheck(
 	IN PRTMP_ADAPTER	pAd,
 	IN UCHAR			Ch)
 {
-#if 1
 	INT		i;
 	BOOLEAN result = FALSE;
 
@@ -224,23 +259,6 @@ BOOLEAN RadarChannelCheck(
 	}
 
 	return result;
-#else
-	INT		i;
-	UCHAR	Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
-
-	for (i=0; i<15; i++)
-	{
-		if (Ch == Channel[i])
-		{
-			break;
-		}
-	}
-
-	if (i != 15)
-		return TRUE;
-	else
-		return FALSE;
-#endif
 }
 
 ULONG JapRadarType(
@@ -399,11 +417,11 @@ VOID RadarDetectPeriodic(
 */
 INT Set_ChMovingTime_Proc(
 	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg)
+	IN PSTRING arg)
 {
 	UINT8 Value;
 
-	Value = simple_strtol(arg, 0, 10);
+	Value = (UINT8) simple_strtol(arg, 0, 10);
 
 	pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
 
@@ -415,11 +433,11 @@ INT Set_ChMovingTime_Proc(
 
 INT Set_LongPulseRadarTh_Proc(
 	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg)
+	IN PSTRING arg)
 {
 	UINT8 Value;
 
-	Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
+	Value = (UINT8) simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
 
 	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
 

+ 1525 - 0
drivers/staging/rt2860/common/ee_efuse.c

@@ -0,0 +1,1525 @@
+/*
+ *************************************************************************
+ * 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:
+	ee_efuse.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+
+#include	"../rt_config.h"
+
+
+
+#define EFUSE_USAGE_MAP_START	0x2d0
+#define EFUSE_USAGE_MAP_END		0x2fc
+#define EFUSE_USAGE_MAP_SIZE	45
+
+
+
+#define EFUSE_EEPROM_DEFULT_FILE	"RT30xxEEPROM.bin"
+#define MAX_EEPROM_BIN_FILE_SIZE	1024
+
+
+
+#define EFUSE_TAG				0x2fe
+
+typedef	union	_EFUSE_CTRL_STRUC {
+	struct	{
+		UINT32            EFSROM_AOUT:6;
+		UINT32            EFSROM_MODE:2;
+		UINT32            EFSROM_LDO_OFF_TIME:6;
+		UINT32            EFSROM_LDO_ON_TIME:2;
+		UINT32            EFSROM_AIN:10;
+		UINT32            RESERVED:4;
+		UINT32            EFSROM_KICK:1;
+		UINT32            SEL_EFUSE:1;
+	}	field;
+	UINT32			word;
+}	EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
+
+static UCHAR eFuseReadRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData);
+
+static VOID eFuseReadPhysical(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUSHORT lpInBuffer,
+	IN	ULONG nInBufferSize,
+	OUT	PUSHORT lpOutBuffer,
+	IN	ULONG nOutBufferSize);
+
+static VOID eFusePhysicalWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData);
+
+static NTSTATUS eFuseWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData);
+
+static VOID eFuseWritePhysical(
+	IN	PRTMP_ADAPTER	pAd,
+	PUSHORT lpInBuffer,
+	ULONG nInBufferSize,
+	PUCHAR lpOutBuffer,
+	ULONG nOutBufferSize);
+
+
+static NTSTATUS eFuseWriteRegistersFromBin(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData);
+
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+UCHAR eFuseReadRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData)
+{
+	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
+	int	i;
+	USHORT	efuseDataOffset;
+	UINT32	data;
+
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+	//Use the eeprom logical address and covert to address to block number
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
+	eFuseCtrlStruc.field.EFSROM_MODE = 0;
+
+	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+	i = 0;
+	while(i < 500)
+	{
+		//rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+		{
+			break;
+		}
+		RTMPusecDelay(2);
+		i++;
+	}
+
+	//if EFSROM_AOUT is not found in physical address, write 0xffff
+	if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
+	{
+		for(i=0; i<Length/2; i++)
+			*(pData+2*i) = 0xffff;
+	}
+	else
+	{
+		//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
+		efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC);
+		//data hold 4 bytes data.
+		//In RTMP_IO_READ32 will automatically execute 32-bytes swapping
+		RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+		//Decide the upper 2 bytes or the bottom 2 bytes.
+		// Little-endian		S	|	S	Big-endian
+		// addr	3	2	1	0	|	0	1	2	3
+		// Ori-V	D	C	B	A	|	A	B	C	D
+		//After swapping
+		//		D	C	B	A	|	D	C	B	A
+		//Return 2-bytes
+		//The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
+		//For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
+		data = data >> (8*(Offset & 0x3));
+
+		NdisMoveMemory(pData, &data, Length);
+	}
+
+	return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
+
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+VOID eFusePhysicalReadRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData)
+{
+	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
+	int	i;
+	USHORT	efuseDataOffset;
+	UINT32	data;
+
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+	//Read in physical view
+	eFuseCtrlStruc.field.EFSROM_MODE = 1;
+
+	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+	i = 0;
+	while(i < 500)
+	{
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+			break;
+		RTMPusecDelay(2);
+		i++;
+	}
+
+	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+	//Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
+	//The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
+	//Decide which EFUSE_DATA to read
+	//590:F E D C
+	//594:B A 9 8
+	//598:7 6 5 4
+	//59C:3 2 1 0
+	efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
+
+	RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+
+	data = data >> (8*(Offset & 0x3));
+
+	NdisMoveMemory(pData, &data, Length);
+
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+static VOID eFuseReadPhysical(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUSHORT lpInBuffer,
+	IN	ULONG nInBufferSize,
+	OUT	PUSHORT lpOutBuffer,
+	IN	ULONG nOutBufferSize
+)
+{
+	USHORT* pInBuf = (USHORT*)lpInBuffer;
+	USHORT* pOutBuf = (USHORT*)lpOutBuffer;
+
+	USHORT Offset = pInBuf[0];					//addr
+	USHORT Length = pInBuf[1];					//length
+	int		i;
+
+	for(i=0; i<Length; i+=2)
+	{
+		eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
+	}
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+NTSTATUS eFuseRead(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUCHAR			pData,
+	IN	USHORT			Length)
+{
+	USHORT* pOutBuf = (USHORT*)pData;
+	NTSTATUS Status = STATUS_SUCCESS;
+	UCHAR	EFSROM_AOUT;
+	int	i;
+
+	for(i=0; i<Length; i+=2)
+	{
+		EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
+	}
+	return Status;
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+static VOID eFusePhysicalWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData)
+{
+	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
+	int	i;
+	USHORT	efuseDataOffset;
+	UINT32	data, eFuseDataBuffer[4];
+
+	//Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
+
+	/////////////////////////////////////////////////////////////////
+	//read current values of 16-byte block
+	RTMP_IO_READ32(pAd, EFUSE_CTRL,  &eFuseCtrlStruc.word);
+
+	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+	eFuseCtrlStruc.field.EFSROM_MODE = 1;
+
+	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+	i = 0;
+	while(i < 500)
+	{
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+			break;
+		RTMPusecDelay(2);
+		i++;
+	}
+
+	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+	efuseDataOffset =  EFUSE_DATA3;
+	for(i=0; i< 4; i++)
+	{
+		RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
+		efuseDataOffset -=  4;
+	}
+
+	//Update the value, the offset is multiple of 2, length is 2
+	efuseDataOffset = (Offset & 0xc) >> 2;
+	data = pData[0] & 0xffff;
+	//The offset should be 0x***10 or 0x***00
+	if((Offset % 4) != 0)
+	{
+		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
+	}
+	else
+	{
+		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
+	}
+
+	efuseDataOffset =  EFUSE_DATA3;
+	for(i=0; i< 4; i++)
+	{
+		RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
+		efuseDataOffset -= 4;
+	}
+	/////////////////////////////////////////////////////////////////
+
+	//Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	//Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
+	eFuseCtrlStruc.field.EFSROM_MODE = 3;
+
+	//Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	//Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
+	i = 0;
+
+	while(i < 500)
+	{
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+			break;
+
+		RTMPusecDelay(2);
+		i++;
+	}
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+static NTSTATUS eFuseWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData)
+{
+	USHORT	i,Loop=0;
+	USHORT	eFuseData;
+	USHORT	LogicalAddress, BlkNum = 0xffff;
+	UCHAR	EFSROM_AOUT;
+
+	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
+	USHORT buffer[8];
+	BOOLEAN		bWriteSuccess = TRUE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
+
+	//Step 0. find the entry in the mapping table
+	//The address of EEPROM is 2-bytes alignment.
+	//The last bit is used for alignment, so it must be 0.
+	tmpOffset = Offset & 0xfffe;
+	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
+
+	if( EFSROM_AOUT == 0x3f)
+	{	//find available logical address pointer
+		//the logical address does not exist, find an empty one
+		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
+		//==>48*16-3(reserved)=2FC
+		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+		{
+			//Retrive the logical block nubmer form each logical address pointer
+			//It will access two logical address pointer each time.
+			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+			if( (LogicalAddress & 0xff) == 0)
+			{//Not used logical address pointer
+				BlkNum = i-EFUSE_USAGE_MAP_START;
+				break;
+			}
+			else if(( (LogicalAddress >> 8) & 0xff) == 0)
+			{//Not used logical address pointer
+				if (i != EFUSE_USAGE_MAP_END)
+				{
+					BlkNum = i-EFUSE_USAGE_MAP_START+1;
+				}
+				break;
+			}
+		}
+	}
+	else
+	{
+		BlkNum = EFSROM_AOUT;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
+
+	if(BlkNum == 0xffff)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+		return FALSE;
+	}
+
+	//Step 1. Save data of this block	which is pointed by the avaible logical address pointer
+	// read and save the original block data
+	for(i =0; i<8; i++)
+	{
+		addr = BlkNum * 0x10 ;
+
+		InBuf[0] = addr+2*i;
+		InBuf[1] = 2;
+		InBuf[2] = 0x0;
+
+		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+		buffer[i] = InBuf[2];
+	}
+
+	//Step 2. Update the data in buffer, and write the data to Efuse
+	buffer[ (Offset >> 1) % 8] = pData[0];
+
+	do
+	{	Loop++;
+		//Step 3. Write the data to Efuse
+		if(!bWriteSuccess)
+		{
+			for(i =0; i<8; i++)
+			{
+				addr = BlkNum * 0x10 ;
+
+				InBuf[0] = addr+2*i;
+				InBuf[1] = 2;
+				InBuf[2] = buffer[i];
+
+				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+			}
+		}
+		else
+		{
+				addr = BlkNum * 0x10 ;
+
+				InBuf[0] = addr+(Offset % 16);
+				InBuf[1] = 2;
+				InBuf[2] = pData[0];
+
+				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+		}
+
+		//Step 4. Write mapping table
+		addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+		tmpaddr = addr;
+
+		if(addr % 2 != 0)
+			addr = addr -1;
+		InBuf[0] = addr;
+		InBuf[1] = 2;
+
+		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
+		tmpOffset = Offset;
+		tmpOffset >>= 4;
+		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
+		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
+
+		// write the logical address
+		if(tmpaddr%2 != 0)
+			InBuf[2] = tmpOffset<<8;
+		else
+			InBuf[2] = tmpOffset;
+
+		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
+
+		//Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
+		bWriteSuccess = TRUE;
+		for(i =0; i<8; i++)
+		{
+			addr = BlkNum * 0x10 ;
+
+			InBuf[0] = addr+2*i;
+			InBuf[1] = 2;
+			InBuf[2] = 0x0;
+
+			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+			if(buffer[i] != InBuf[2])
+			{
+				bWriteSuccess = FALSE;
+				break;
+			}
+		}
+
+		//Step 6. invlidate mapping entry and find a free mapping entry if not succeed
+		if (!bWriteSuccess)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
+
+			// the offset of current mapping entry
+			addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+			//find a new mapping entry
+			BlkNum = 0xffff;
+			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+			{
+				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+				if( (LogicalAddress & 0xff) == 0)
+				{
+					BlkNum = i-EFUSE_USAGE_MAP_START;
+					break;
+				}
+				else if(( (LogicalAddress >> 8) & 0xff) == 0)
+				{
+					if (i != EFUSE_USAGE_MAP_END)
+					{
+						BlkNum = i+1-EFUSE_USAGE_MAP_START;
+					}
+					break;
+				}
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
+			if(BlkNum == 0xffff)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+				return FALSE;
+			}
+
+			//invalidate the original mapping entry if new entry is not found
+			tmpaddr = addr;
+
+			if(addr % 2 != 0)
+				addr = addr -1;
+			InBuf[0] = addr;
+			InBuf[1] = 2;
+
+			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+			// write the logical address
+			if(tmpaddr%2 != 0)
+			{
+				// Invalidate the high byte
+				for (i=8; i<15; i++)
+				{
+					if( ( (InBuf[2] >> i) & 0x01) == 0)
+					{
+						InBuf[2] |= (0x1 <<i);
+						break;
+					}
+				}
+			}
+			else
+			{
+				// invalidate the low byte
+				for (i=0; i<8; i++)
+				{
+					if( ( (InBuf[2] >> i) & 0x01) == 0)
+					{
+						InBuf[2] |= (0x1 <<i);
+						break;
+					}
+				}
+			}
+			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+		}
+	}
+	while (!bWriteSuccess&&Loop<2);
+	if(!bWriteSuccess)
+		DBGPRINT(RT_DEBUG_ERROR,("Efsue Write Failed!!\n"));
+	return TRUE;
+}
+
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+static VOID eFuseWritePhysical(
+	IN	PRTMP_ADAPTER	pAd,
+	PUSHORT lpInBuffer,
+	ULONG nInBufferSize,
+	PUCHAR lpOutBuffer,
+	ULONG nOutBufferSize
+)
+{
+	USHORT* pInBuf = (USHORT*)lpInBuffer;
+	int		i;
+	//USHORT* pOutBuf = (USHORT*)ioBuffer;
+	USHORT Offset = pInBuf[0];					// addr
+	USHORT Length = pInBuf[1];					// length
+	USHORT* pValueX = &pInBuf[2];				// value ...
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWritePhysical Offset=0x%x, length=%d\n", Offset, Length));
+
+	{
+		// Little-endian		S	|	S	Big-endian
+		// addr	3	2	1	0	|	0	1	2	3
+		// Ori-V	D	C	B	A	|	A	B	C	D
+		// After swapping
+		//		D	C	B	A	|	D	C	B	A
+		// Both the little and big-endian use the same sequence to write  data.
+		// Therefore, we only need swap data when read the data.
+		for (i=0; i<Length; i+=2)
+		{
+			eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+		}
+	}
+}
+
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+NTSTATUS eFuseWrite(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData,
+	IN	USHORT			length)
+{
+	int i;
+	USHORT* pValueX = (PUSHORT) pData;				//value ...
+
+	// The input value=3070 will be stored as following
+	// Little-endian		S	|	S	Big-endian
+	// addr			1	0	|	0	1
+	// Ori-V			30	70	|	30	70
+	// After swapping
+	//				30	70	|	70	30
+	// Casting
+	//				3070	|	7030 (x)
+	// The swapping should be removed for big-endian
+	for(i=0; i<length; i+=2)
+	{
+		eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+	}
+
+	return TRUE;
+}
+
+
+
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+INT set_eFuseGetFreeBlockCount_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	USHORT i;
+	USHORT	LogicalAddress;
+	USHORT efusefreenum=0;
+	if(!pAd->bUseEfuse)
+		return FALSE;
+	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
+	{
+		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+		if( (LogicalAddress & 0xff) == 0)
+		{
+			efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
+			break;
+		}
+		else if(( (LogicalAddress >> 8) & 0xff) == 0)
+		{
+			efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
+			break;
+		}
+
+		if(i == EFUSE_USAGE_MAP_END)
+			efusefreenum = 0;
+	}
+	printk("efuseFreeNumber is %d\n",efusefreenum);
+	return TRUE;
+}
+
+
+INT set_eFusedump_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+USHORT InBuf[3];
+	INT i=0;
+	if(!pAd->bUseEfuse)
+		return FALSE;
+	for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
+	{
+		InBuf[0] = 2*i;
+		InBuf[1] = 2;
+		InBuf[2] = 0x0;
+
+		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+		if(i%4==0)
+		printk("\nBlock %x:",i/8);
+		printk("%04x ",InBuf[2]);
+	}
+	return TRUE;
+}
+
+
+INT	set_eFuseLoadFromBin_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	PSTRING					src;
+	RTMP_OS_FD				srcf;
+	RTMP_OS_FS_INFO			osfsInfo;
+	INT						retval, memSize;
+	PSTRING					buffer, memPtr;
+	INT						i = 0,j=0,k=1;
+	USHORT					*PDATA;
+	USHORT					DATA;
+
+	memSize = 128 + MAX_EEPROM_BIN_FILE_SIZE + sizeof(USHORT) * 8;
+	memPtr = kmalloc(memSize, MEM_ALLOC_FLAG);
+	if (memPtr == NULL)
+		return FALSE;
+
+	NdisZeroMemory(memPtr, memSize);
+	src = memPtr; // kmalloc(128, MEM_ALLOC_FLAG);
+	buffer = src + 128;		// kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
+	PDATA = (USHORT*)(buffer + MAX_EEPROM_BIN_FILE_SIZE);	// kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
+
+	if(strlen(arg)>0)
+		NdisMoveMemory(src, arg, strlen(arg));
+	else
+		NdisMoveMemory(src, EFUSE_EEPROM_DEFULT_FILE, strlen(EFUSE_EEPROM_DEFULT_FILE));
+	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
+
+	RtmpOSFSInfoChange(&osfsInfo, TRUE);
+
+	srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
+	if (IS_FILE_OPEN_ERR(srcf))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening file %s\n", src));
+		retval = FALSE;
+		goto recoverFS;
+	}
+	else
+	{
+		// The object must have a read method
+		while(RtmpOSFileRead(srcf, &buffer[i], 1)==1)
+		{
+		i++;
+			if(i>MAX_EEPROM_BIN_FILE_SIZE)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("--> Error reading file %s, file size too large[>%d]\n", src, MAX_EEPROM_BIN_FILE_SIZE));
+				retval = FALSE;
+				goto closeFile;
+			}
+		}
+
+		retval = RtmpOSFileClose(srcf);
+		if (retval)
+			DBGPRINT(RT_DEBUG_TRACE, ("--> Error closing file %s\n", src));
+	}
+
+
+	RtmpOSFSInfoChange(&osfsInfo, FALSE);
+
+	for(j=0;j<i;j++)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]&0xff));
+		if((j+1)%2==0)
+			PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
+		if(j%16==0)
+		{
+			k=buffer[j];
+		}
+		else
+		{
+			k&=buffer[j];
+			if((j+1)%16==0)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
+				if(k!=0xff)
+					eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
+				else
+				{
+					if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
+						eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
+				}
+				/*
+				for(l=0;l<8;l++)
+					printk("%04x ",PDATA[l]);
+				printk("\n");
+				*/
+				NdisZeroMemory(PDATA,16);
+			}
+		}
+	}
+
+	return TRUE;
+
+closeFile:
+	if (srcf)
+		RtmpOSFileClose(srcf);
+
+recoverFS:
+	RtmpOSFSInfoChange(&osfsInfo, FALSE);
+
+
+	if (memPtr)
+		kfree(memPtr);
+
+	return retval;
+}
+
+
+static NTSTATUS eFuseWriteRegistersFromBin(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData)
+{
+	USHORT	i;
+	USHORT	eFuseData;
+	USHORT	LogicalAddress, BlkNum = 0xffff;
+	UCHAR	EFSROM_AOUT,Loop=0;
+	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
+	USHORT	efuseDataOffset;
+	UINT32	data,tempbuffer;
+	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
+	UINT32 buffer[4];
+	BOOLEAN		bWriteSuccess = TRUE;
+	BOOLEAN		bNotWrite=TRUE;
+	BOOLEAN		bAllocateNewBlk=TRUE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
+
+	do
+	{
+	//Step 0. find the entry in the mapping table
+	//The address of EEPROM is 2-bytes alignment.
+	//The last bit is used for alignment, so it must be 0.
+	Loop++;
+	tmpOffset = Offset & 0xfffe;
+	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
+
+	if( EFSROM_AOUT == 0x3f)
+	{	//find available logical address pointer
+		//the logical address does not exist, find an empty one
+		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
+		//==>48*16-3(reserved)=2FC
+		bAllocateNewBlk=TRUE;
+		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+		{
+			//Retrive the logical block nubmer form each logical address pointer
+			//It will access two logical address pointer each time.
+			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+			if( (LogicalAddress & 0xff) == 0)
+			{//Not used logical address pointer
+				BlkNum = i-EFUSE_USAGE_MAP_START;
+				break;
+			}
+			else if(( (LogicalAddress >> 8) & 0xff) == 0)
+			{//Not used logical address pointer
+				if (i != EFUSE_USAGE_MAP_END)
+				{
+					BlkNum = i-EFUSE_USAGE_MAP_START+1;
+				}
+				break;
+			}
+		}
+	}
+	else
+	{
+		bAllocateNewBlk=FALSE;
+		BlkNum = EFSROM_AOUT;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
+
+	if(BlkNum == 0xffff)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+		return FALSE;
+	}
+	//Step 1.1.0
+	//If the block is not existing in mapping table, create one
+	//and write down the 16-bytes data to the new block
+	if(bAllocateNewBlk)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
+		efuseDataOffset =  EFUSE_DATA3;
+		for(i=0; i< 4; i++)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
+			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
+
+
+			RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
+			efuseDataOffset -= 4;
+
+		}
+		/////////////////////////////////////////////////////////////////
+
+		//Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+		eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
+
+		//Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
+		eFuseCtrlStruc.field.EFSROM_MODE = 3;
+
+		//Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
+		eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+
+		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+		//Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
+		i = 0;
+		while(i < 100)
+		{
+			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+				break;
+
+			RTMPusecDelay(2);
+			i++;
+		}
+
+	}
+	else
+	{	//Step1.2.
+		//If the same logical number is existing, check if the writting data and the data
+		//saving in this block are the same.
+		/////////////////////////////////////////////////////////////////
+		//read current values of 16-byte block
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+		//Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+		eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+		//Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+		eFuseCtrlStruc.field.EFSROM_MODE = 0;
+
+		//Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+		eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+		//Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+		i = 0;
+		while(i < 500)
+		{
+			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+				break;
+			RTMPusecDelay(2);
+			i++;
+		}
+
+		//Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+		efuseDataOffset =  EFUSE_DATA3;
+		for(i=0; i< 4; i++)
+		{
+			RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
+			efuseDataOffset -=  4;
+		}
+		//Step1.2.5. Check if the data of efuse and the writing data are the same.
+		for(i =0; i<4; i++)
+		{
+			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
+			DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
+
+			if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
+				bNotWrite&=TRUE;
+			else
+			{
+				bNotWrite&=FALSE;
+				break;
+			}
+		}
+		if(!bNotWrite)
+		{
+		printk("The data is not the same\n");
+
+			for(i =0; i<8; i++)
+			{
+				addr = BlkNum * 0x10 ;
+
+				InBuf[0] = addr+2*i;
+				InBuf[1] = 2;
+				InBuf[2] = pData[i];
+
+				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+			}
+
+		}
+		else
+			return TRUE;
+	     }
+
+
+
+		//Step 2. Write mapping table
+		addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+		tmpaddr = addr;
+
+		if(addr % 2 != 0)
+			addr = addr -1;
+		InBuf[0] = addr;
+		InBuf[1] = 2;
+
+		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
+		tmpOffset = Offset;
+		tmpOffset >>= 4;
+		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
+		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
+
+		// write the logical address
+		if(tmpaddr%2 != 0)
+			InBuf[2] = tmpOffset<<8;
+		else
+			InBuf[2] = tmpOffset;
+
+		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
+
+		//Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
+		bWriteSuccess = TRUE;
+		for(i =0; i<8; i++)
+		{
+			addr = BlkNum * 0x10 ;
+
+			InBuf[0] = addr+2*i;
+			InBuf[1] = 2;
+			InBuf[2] = 0x0;
+
+			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+			DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
+			if(pData[i] != InBuf[2])
+			{
+				bWriteSuccess = FALSE;
+				break;
+			}
+		}
+
+		//Step 4. invlidate mapping entry and find a free mapping entry if not succeed
+
+		if (!bWriteSuccess&&Loop<2)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
+
+			// the offset of current mapping entry
+			addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+			//find a new mapping entry
+			BlkNum = 0xffff;
+			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+			{
+				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+				if( (LogicalAddress & 0xff) == 0)
+				{
+					BlkNum = i-EFUSE_USAGE_MAP_START;
+					break;
+				}
+				else if(( (LogicalAddress >> 8) & 0xff) == 0)
+				{
+					if (i != EFUSE_USAGE_MAP_END)
+					{
+						BlkNum = i+1-EFUSE_USAGE_MAP_START;
+					}
+					break;
+				}
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
+			if(BlkNum == 0xffff)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
+				return FALSE;
+			}
+
+			//invalidate the original mapping entry if new entry is not found
+			tmpaddr = addr;
+
+			if(addr % 2 != 0)
+				addr = addr -1;
+			InBuf[0] = addr;
+			InBuf[1] = 2;
+
+			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+			// write the logical address
+			if(tmpaddr%2 != 0)
+			{
+				// Invalidate the high byte
+				for (i=8; i<15; i++)
+				{
+					if( ( (InBuf[2] >> i) & 0x01) == 0)
+					{
+						InBuf[2] |= (0x1 <<i);
+						break;
+					}
+				}
+			}
+			else
+			{
+				// invalidate the low byte
+				for (i=0; i<8; i++)
+				{
+					if( ( (InBuf[2] >> i) & 0x01) == 0)
+					{
+						InBuf[2] |= (0x1 <<i);
+						break;
+					}
+				}
+			}
+			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+		}
+
+	}
+	while(!bWriteSuccess&&Loop<2);
+
+	return TRUE;
+}
+
+
+int rtmp_ee_efuse_read16(
+	IN RTMP_ADAPTER *pAd,
+	IN USHORT Offset,
+	OUT USHORT *pValue)
+{
+	if(pAd->bFroceEEPROMBuffer || pAd->bEEPROMFile)
+	{
+	    DBGPRINT(RT_DEBUG_TRACE,  ("Read from EEPROM Buffer\n"));
+	    NdisMoveMemory(pValue, &(pAd->EEPROMImage[Offset]), 2);
+	}
+	else
+	    eFuseReadRegisters(pAd, Offset, 2, pValue);
+	return (*pValue);
+}
+
+
+int rtmp_ee_efuse_write16(
+	IN RTMP_ADAPTER *pAd,
+	IN USHORT Offset,
+	IN USHORT data)
+{
+    if(pAd->bFroceEEPROMBuffer||pAd->bEEPROMFile)
+    {
+        DBGPRINT(RT_DEBUG_TRACE,  ("Write to EEPROM Buffer\n"));
+        NdisMoveMemory(&(pAd->EEPROMImage[Offset]), &data, 2);
+    }
+    else
+        eFuseWriteRegisters(pAd, Offset, 2, &data);
+	return 0;
+}
+
+
+int RtmpEfuseSupportCheck(
+	IN RTMP_ADAPTER *pAd)
+{
+	USHORT value;
+
+	if (IS_RT30xx(pAd))
+	{
+		eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
+		pAd->EFuseTag = (value & 0xff);
+	}
+	return 0;
+}
+
+INT set_eFuseBufferModeWriteBack_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	UINT Enable;
+
+
+	if(strlen(arg)>0)
+	{
+		Enable= simple_strtol(arg, 0, 16);
+	}
+	else
+		return FALSE;
+	if(Enable==1)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("set_eFuseBufferMode_Proc:: Call WRITEEEPROMBUF"));
+		eFuseWriteEeeppromBuf(pAd);
+	}
+	else
+		return FALSE;
+	return TRUE;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Load EEPROM from bin file for eFuse mode
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS         firmware image load ok
+		NDIS_STATUS_FAILURE         image not found
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+INT eFuseLoadEEPROM(
+	IN PRTMP_ADAPTER pAd)
+{
+	PSTRING					src = NULL;
+	INT						retval;
+	RTMP_OS_FD				srcf;
+	RTMP_OS_FS_INFO			osFSInfo;
+
+
+	src=EFUSE_BUFFER_PATH;
+	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
+
+
+	RtmpOSFSInfoChange(&osFSInfo, TRUE);
+
+	if (src && *src)
+	{
+		srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
+		if (IS_FILE_OPEN_ERR(srcf))
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
+			return FALSE;
+		}
+		else
+		{
+
+				memset(pAd->EEPROMImage, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
+
+
+			retval =RtmpOSFileRead(srcf, (PSTRING)pAd->EEPROMImage, MAX_EEPROM_BIN_FILE_SIZE);
+			if (retval > 0)
+							{
+				RTMPSetProfileParameters(pAd, (PSTRING)pAd->EEPROMImage);
+				retval = NDIS_STATUS_SUCCESS;
+			}
+			else
+				DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
+
+		}
+
+
+	}
+	else
+		{
+					DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
+					return FALSE;
+
+		}
+
+	retval=RtmpOSFileClose(srcf);
+
+	if (retval)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+	}
+
+
+	RtmpOSFSInfoChange(&osFSInfo, FALSE);
+
+	return TRUE;
+}
+
+INT eFuseWriteEeeppromBuf(
+	IN PRTMP_ADAPTER pAd)
+{
+
+	PSTRING					src = NULL;
+	INT						retval;
+	RTMP_OS_FD				srcf;
+	RTMP_OS_FS_INFO			osFSInfo;
+
+
+	src=EFUSE_BUFFER_PATH;
+	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
+
+	RtmpOSFSInfoChange(&osFSInfo, TRUE);
+
+
+
+	if (src && *src)
+	{
+		srcf = RtmpOSFileOpen(src, O_WRONLY|O_CREAT, 0);
+
+		if (IS_FILE_OPEN_ERR(srcf))
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
+			return FALSE;
+		}
+		else
+		{
+/*
+			// The object must have a read method
+			if (srcf->f_op && srcf->f_op->write)
+			{
+				// The object must have a read method
+                        srcf->f_op->write(srcf, pAd->EEPROMImage, 1024, &srcf->f_pos);
+
+			}
+			else
+			{
+						DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
+						return FALSE;
+			}
+*/
+
+			RtmpOSFileWrite(srcf, (PSTRING)pAd->EEPROMImage,MAX_EEPROM_BIN_FILE_SIZE);
+
+		}
+
+
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
+		return FALSE;
+
+	}
+
+	retval=RtmpOSFileClose(srcf);
+
+	if (retval)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+	}
+
+	RtmpOSFSInfoChange(&osFSInfo, FALSE);
+	return TRUE;
+}
+
+
+VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd,
+	PUINT EfuseFreeBlock)
+{
+	USHORT i;
+	USHORT	LogicalAddress;
+	if(!pAd->bUseEfuse)
+		{
+		DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
+		return ;
+		}
+	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
+	{
+		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+		if( (LogicalAddress & 0xff) == 0)
+		{
+			*EfuseFreeBlock= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
+			break;
+		}
+		else if(( (LogicalAddress >> 8) & 0xff) == 0)
+		{
+			*EfuseFreeBlock = (UCHAR) (EFUSE_USAGE_MAP_END-i);
+			break;
+		}
+
+		if(i == EFUSE_USAGE_MAP_END)
+			*EfuseFreeBlock = 0;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount is 0x%x\n",*EfuseFreeBlock));
+}
+
+INT eFuse_init(
+	IN PRTMP_ADAPTER pAd)
+{
+	UINT	EfuseFreeBlock=0;
+	DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and its size =%x[%x-%x] \n",EFUSE_USAGE_MAP_SIZE,EFUSE_USAGE_MAP_START,EFUSE_USAGE_MAP_END));
+	eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);
+	//If the used block of efuse is less than 5. We assume the default value
+	// of this efuse is empty and change to the buffer mode in odrder to
+	//bring up interfaces successfully.
+	if(EfuseFreeBlock > (EFUSE_USAGE_MAP_END-5))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and the information is too less to bring up interface. Force to use EEPROM Buffer Mode\n"));
+		pAd->bFroceEEPROMBuffer = TRUE;
+		eFuseLoadEEPROM(pAd);
+	}
+	else
+		pAd->bFroceEEPROMBuffer = FALSE;
+	DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse and force to use EEPROM Buffer Mode=%x\n",pAd->bFroceEEPROMBuffer));
+
+	return 0;
+}

+ 270 - 0
drivers/staging/rt2860/common/ee_prom.c

@@ -0,0 +1,270 @@
+/*
+ *************************************************************************
+ * 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:
+	ee_prom.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+
+#include	"../rt_config.h"
+
+
+
+// IRQL = PASSIVE_LEVEL
+static inline VOID RaiseClock(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  UINT32 *x)
+{
+	*x = *x | EESK;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+	RTMPusecDelay(1);				// Max frequency = 1MHz in Spec. definition
+}
+
+// IRQL = PASSIVE_LEVEL
+static inline VOID LowerClock(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  UINT32 *x)
+{
+	*x = *x & ~EESK;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+	RTMPusecDelay(1);
+}
+
+// IRQL = PASSIVE_LEVEL
+static inline USHORT ShiftInBits(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UINT32		x,i;
+	USHORT      data=0;
+
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+	x &= ~( EEDO | EEDI);
+
+	for(i=0; i<16; i++)
+	{
+		data = data << 1;
+		RaiseClock(pAd, &x);
+
+		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+		LowerClock(pAd, &x); //prevent read failed
+
+		x &= ~(EEDI);
+		if(x & EEDO)
+		    data |= 1;
+	}
+
+	return data;
+}
+
+
+// IRQL = PASSIVE_LEVEL
+static inline VOID ShiftOutBits(
+	IN PRTMP_ADAPTER	pAd,
+	IN USHORT			data,
+	IN USHORT			count)
+{
+	UINT32       x,mask;
+
+	mask = 0x01 << (count - 1);
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+	x &= ~(EEDO | EEDI);
+
+	do
+	{
+	    x &= ~EEDI;
+	    if(data & mask)		x |= EEDI;
+
+	    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	    RaiseClock(pAd, &x);
+	    LowerClock(pAd, &x);
+
+	    mask = mask >> 1;
+	} while(mask);
+
+	x &= ~EEDI;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+}
+
+
+// IRQL = PASSIVE_LEVEL
+static inline VOID EEpromCleanup(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UINT32 x;
+
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+	x &= ~(EECS | EEDI);
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+}
+
+
+static inline VOID EWEN(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UINT32	x;
+
+	// reset bits and set EECS
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+	x &= ~(EEDI | EEDO | EESK);
+	x |= EECS;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	// kick a pulse
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+
+	// output the read_opcode and six pulse in that order
+	ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
+	ShiftOutBits(pAd, 0, 6);
+
+	EEpromCleanup(pAd);
+}
+
+
+static inline VOID EWDS(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UINT32	x;
+
+	// reset bits and set EECS
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+	x &= ~(EEDI | EEDO | EESK);
+	x |= EECS;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	// kick a pulse
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+
+	// output the read_opcode and six pulse in that order
+	ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
+	ShiftOutBits(pAd, 0, 6);
+
+	EEpromCleanup(pAd);
+}
+
+
+// IRQL = PASSIVE_LEVEL
+int rtmp_ee_prom_read16(
+	IN PRTMP_ADAPTER	pAd,
+	IN USHORT			Offset,
+	OUT USHORT			*pValue)
+{
+	UINT32		x;
+	USHORT		data;
+
+
+	Offset /= 2;
+	// reset bits and set EECS
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+	x &= ~(EEDI | EEDO | EESK);
+	x |= EECS;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	// patch can not access e-Fuse issue
+	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
+	{
+		// kick a pulse
+		RaiseClock(pAd, &x);
+		LowerClock(pAd, &x);
+	}
+
+	// output the read_opcode and register number in that order
+	ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
+	ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
+
+	// Now read the data (16 bits) in from the selected EEPROM word
+	data = ShiftInBits(pAd);
+
+	EEpromCleanup(pAd);
+
+
+	*pValue = data;
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+int rtmp_ee_prom_write16(
+    IN  PRTMP_ADAPTER	pAd,
+    IN  USHORT Offset,
+    IN  USHORT Data)
+{
+	UINT32 x;
+
+
+	Offset /= 2;
+
+	EWEN(pAd);
+
+	// reset bits and set EECS
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+	x &= ~(EEDI | EEDO | EESK);
+	x |= EECS;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	// patch can not access e-Fuse issue
+	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
+	{
+		// kick a pulse
+		RaiseClock(pAd, &x);
+		LowerClock(pAd, &x);
+	}
+
+	// output the read_opcode ,register number and data in that order
+	ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
+	ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
+	ShiftOutBits(pAd, Data, 16);		// 16-bit access
+
+	// read DO status
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+	EEpromCleanup(pAd);
+
+	RTMPusecDelay(10000);	//delay for twp(MAX)=10ms
+
+	EWDS(pAd);
+
+	EEpromCleanup(pAd);
+
+
+	return NDIS_STATUS_SUCCESS;
+
+}

+ 42 - 1418
drivers/staging/rt2860/common/eeprom.c

@@ -36,1444 +36,68 @@
 */
 #include "../rt_config.h"
 
-// IRQL = PASSIVE_LEVEL
-VOID RaiseClock(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  UINT32 *x)
-{
-    *x = *x | EESK;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
-    RTMPusecDelay(1);				// Max frequency = 1MHz in Spec. definition
-}
-
-// IRQL = PASSIVE_LEVEL
-VOID LowerClock(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  UINT32 *x)
-{
-    *x = *x & ~EESK;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
-    RTMPusecDelay(1);
-}
-
-// IRQL = PASSIVE_LEVEL
-USHORT ShiftInBits(
-    IN	PRTMP_ADAPTER	pAd)
-{
-    UINT32		x,i;
-	USHORT      data=0;
-
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-    x &= ~( EEDO | EEDI);
-
-    for(i=0; i<16; i++)
-    {
-        data = data << 1;
-        RaiseClock(pAd, &x);
-
-        RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	LowerClock(pAd, &x); /* prevent read failed */
-
-        x &= ~(EEDI);
-        if(x & EEDO)
-            data |= 1;
-    }
-
-    return data;
-}
-
-// IRQL = PASSIVE_LEVEL
-VOID ShiftOutBits(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  USHORT data,
-    IN  USHORT count)
-{
-    UINT32       x,mask;
-
-    mask = 0x01 << (count - 1);
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-    x &= ~(EEDO | EEDI);
-
-    do
-    {
-        x &= ~EEDI;
-        if(data & mask)		x |= EEDI;
-
-        RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-        RaiseClock(pAd, &x);
-        LowerClock(pAd, &x);
-
-        mask = mask >> 1;
-    } while(mask);
-
-    x &= ~EEDI;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-}
-
-// IRQL = PASSIVE_LEVEL
-VOID EEpromCleanup(
-    IN	PRTMP_ADAPTER	pAd)
-{
-    UINT32 x;
-
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-    x &= ~(EECS | EEDI);
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-    RaiseClock(pAd, &x);
-    LowerClock(pAd, &x);
-}
-
-VOID EWEN(
-	IN	PRTMP_ADAPTER	pAd)
-{
-    UINT32	x;
-
-    // reset bits and set EECS
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-    x &= ~(EEDI | EEDO | EESK);
-    x |= EECS;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-
-    // output the read_opcode and six pulse in that order
-    ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
-    ShiftOutBits(pAd, 0, 6);
-
-    EEpromCleanup(pAd);
-}
-
-VOID EWDS(
-	IN	PRTMP_ADAPTER	pAd)
-{
-    UINT32	x;
-
-    // reset bits and set EECS
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-    x &= ~(EEDI | EEDO | EESK);
-    x |= EECS;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-
-    // output the read_opcode and six pulse in that order
-    ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
-    ShiftOutBits(pAd, 0, 6);
-
-    EEpromCleanup(pAd);
-}
-
-// IRQL = PASSIVE_LEVEL
-USHORT RTMP_EEPROM_READ16(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  USHORT Offset)
-{
-    UINT32		x;
-    USHORT		data;
-
-#ifdef RT2870
-	if (pAd->NicConfig2.field.AntDiversity)
-    {
-    	pAd->EepromAccess = TRUE;
-    }
-#endif
-    Offset /= 2;
-    // reset bits and set EECS
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-    x &= ~(EEDI | EEDO | EESK);
-    x |= EECS;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// patch can not access e-Fuse issue
-    if (!IS_RT3090(pAd))
-    {
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-    }
-
-    // output the read_opcode and register number in that order
-    ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
-    ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
-
-    // Now read the data (16 bits) in from the selected EEPROM word
-    data = ShiftInBits(pAd);
-
-    EEpromCleanup(pAd);
-
-#ifdef RT2870
-	// 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
-	if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
-    {
-	    pAd->EepromAccess = FALSE;
-	    AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-    }
-#endif
-    return data;
-}	//ReadEEprom
-
-VOID RTMP_EEPROM_WRITE16(
-    IN	PRTMP_ADAPTER	pAd,
-    IN  USHORT Offset,
-    IN  USHORT Data)
-{
-    UINT32 x;
-
-#ifdef RT2870
-	if (pAd->NicConfig2.field.AntDiversity)
-    {
-    	pAd->EepromAccess = TRUE;
-    }
-#endif
-	Offset /= 2;
-
-	EWEN(pAd);
-
-    // reset bits and set EECS
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-    x &= ~(EEDI | EEDO | EESK);
-    x |= EECS;
-    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	// patch can not access e-Fuse issue
-    if (!IS_RT3090(pAd))
-    {
-	// kick a pulse
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-    }
-
-    // output the read_opcode ,register number and data in that order
-    ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
-    ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
-	ShiftOutBits(pAd, Data, 16);		// 16-bit access
-
-    // read DO status
-    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	EEpromCleanup(pAd);
-
-	RTMPusecDelay(10000);	//delay for twp(MAX)=10ms
-
-	EWDS(pAd);
-
-    EEpromCleanup(pAd);
-
-#ifdef RT2870
-	// 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
-	if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
-    {
-	    pAd->EepromAccess = FALSE;
-	    AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-    }
-#endif
-}
-
-#ifdef RT2870
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-UCHAR eFuseReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData)
-{
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	int	i;
-	USHORT	efuseDataOffset;
-	UINT32	data;
-
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	//Use the eeprom logical address and covert to address to block number
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
-	eFuseCtrlStruc.field.EFSROM_MODE = 0;
-
-	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
 
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-	i = 0;
-	while(i < 100)
-	{
-		//rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-		{
-			break;
-		}
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	//if EFSROM_AOUT is not found in physical address, write 0xffff
-	if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
-	{
-		for(i=0; i<Length/2; i++)
-			*(pData+2*i) = 0xffff;
-	}
-	else
-	{
-		//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
-		efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
-		//data hold 4 bytes data.
-		//In RTMP_IO_READ32 will automatically execute 32-bytes swapping
-		RTMP_IO_READ32(pAd, efuseDataOffset, &data);
-		//Decide the upper 2 bytes or the bottom 2 bytes.
-		// Little-endian		S	|	S	Big-endian
-		// addr	3	2	1	0	|	0	1	2	3
-		// Ori-V	D	C	B	A	|	A	B	C	D
-		//After swapping
-		//		D	C	B	A	|	D	C	B	A
-		//Return 2-bytes
-		//The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
-		//For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
-		data = data >> (8*(Offset & 0x3));
-
-		NdisMoveMemory(pData, &data, Length);
-	}
-
-	return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-VOID eFusePhysicalReadRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData)
+INT RtmpChipOpsEepromHook(
+	IN RTMP_ADAPTER *pAd,
+	IN INT			infType)
 {
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	int	i;
-	USHORT	efuseDataOffset;
-	UINT32	data;
-
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
-	//Read in physical view
-	eFuseCtrlStruc.field.EFSROM_MODE = 1;
-
-	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-	i = 0;
-	while(i < 100)
-	{
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-			break;
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
-	//Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
-	//The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
-	//Decide which EFUSE_DATA to read
-	//590:F E D C
-	//594:B A 9 8
-	//598:7 6 5 4
-	//59C:3 2 1 0
-	efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
-
-	RTMP_IO_READ32(pAd, efuseDataOffset, &data);
-
-	data = data >> (8*(Offset & 0x3));
-
-	NdisMoveMemory(pData, &data, Length);
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-VOID eFuseReadPhysical(
-	IN	PRTMP_ADAPTER	pAd,
-  	IN	PUSHORT lpInBuffer,
-  	IN	ULONG nInBufferSize,
-  	OUT	PUSHORT lpOutBuffer,
-  	IN	ULONG nOutBufferSize
-)
-{
-	USHORT* pInBuf = (USHORT*)lpInBuffer;
-	USHORT* pOutBuf = (USHORT*)lpOutBuffer;
-
-	USHORT Offset = pInBuf[0];					//addr
-	USHORT Length = pInBuf[1];					//length
-	int 		i;
-
-	for(i=0; i<Length; i+=2)
-	{
-		eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS eFuseRead(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	OUT	PUCHAR			pData,
-	IN	USHORT			Length)
-{
-	USHORT* pOutBuf = (USHORT*)pData;
-	NTSTATUS	Status = STATUS_SUCCESS;
-	UCHAR	EFSROM_AOUT;
-	int	i;
-
-	for(i=0; i<Length; i+=2)
-	{
-		EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
-	}
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-VOID eFusePhysicalWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	OUT	USHORT* pData)
-{
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	int	i;
-	USHORT	efuseDataOffset;
-	UINT32	data, eFuseDataBuffer[4];
-
-	//Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
-
-	/////////////////////////////////////////////////////////////////
-	//read current values of 16-byte block
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
-	eFuseCtrlStruc.field.EFSROM_MODE = 1;
-
-	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-	i = 0;
-	while(i < 100)
-	{
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-			break;
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
-	efuseDataOffset =  EFUSE_DATA3;
-	for(i=0; i< 4; i++)
-	{
-		RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
-		efuseDataOffset -=  4;
-	}
-
-	//Update the value, the offset is multiple of 2, length is 2
-	efuseDataOffset = (Offset & 0xc) >> 2;
-	data = pData[0] & 0xffff;
-	//The offset should be 0x***10 or 0x***00
-	if((Offset % 4) != 0)
-	{
-		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
-	}
-	else
-	{
-		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
-	}
-
-	efuseDataOffset =  EFUSE_DATA3;
-	for(i=0; i< 4; i++)
-	{
-		RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
-		efuseDataOffset -= 4;
-	}
-	/////////////////////////////////////////////////////////////////
-
-	//Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	//Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
-	eFuseCtrlStruc.field.EFSROM_MODE = 3;
-
-	//Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	//Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
-	i = 0;
-	while(i < 100)
-	{
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-			break;
-
-		RTMPusecDelay(2);
-		i++;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS eFuseWriteRegisters(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData)
-{
-	USHORT	i;
-	USHORT	eFuseData;
-	USHORT	LogicalAddress, BlkNum = 0xffff;
-	UCHAR	EFSROM_AOUT;
-
-	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
-	USHORT buffer[8];
-	BOOLEAN		bWriteSuccess = TRUE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
-
-	//Step 0. find the entry in the mapping table
-	//The address of EEPROM is 2-bytes alignment.
-	//The last bit is used for alignment, so it must be 0.
-	tmpOffset = Offset & 0xfffe;
-	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
-
-	if( EFSROM_AOUT == 0x3f)
-	{	//find available logical address pointer
-		//the logical address does not exist, find an empty one
-		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
-		//==>48*16-3(reserved)=2FC
-		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-		{
-			//Retrive the logical block nubmer form each logical address pointer
-			//It will access two logical address pointer each time.
-			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-			if( (LogicalAddress & 0xff) == 0)
-			{//Not used logical address pointer
-				BlkNum = i-EFUSE_USAGE_MAP_START;
-				break;
-			}
-			else if(( (LogicalAddress >> 8) & 0xff) == 0)
-			{//Not used logical address pointer
-				if (i != EFUSE_USAGE_MAP_END)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START+1;
-				}
-				break;
-			}
-		}
-	}
-	else
-	{
-		BlkNum = EFSROM_AOUT;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
-
-	if(BlkNum == 0xffff)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
-		return FALSE;
-	}
-
-	//Step 1. Save data of this block	which is pointed by the avaible logical address pointer
-	// read and save the original block data
-	for(i =0; i<8; i++)
-	{
-		addr = BlkNum * 0x10 ;
-
-		InBuf[0] = addr+2*i;
-		InBuf[1] = 2;
-		InBuf[2] = 0x0;
-
-		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-		buffer[i] = InBuf[2];
-	}
-
-	//Step 2. Update the data in buffer, and write the data to Efuse
-	buffer[ (Offset >> 1) % 8] = pData[0];
+	RTMP_CHIP_OP	*pChipOps = &pAd->chipOps;
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+	UINT32			eFuseCtrl, MacCsr0;
+	int index;
 
+	index = 0;
 	do
 	{
-		//Step 3. Write the data to Efuse
-		if(!bWriteSuccess)
-		{
-			for(i =0; i<8; i++)
-			{
-				addr = BlkNum * 0x10 ;
-
-				InBuf[0] = addr+2*i;
-				InBuf[1] = 2;
-				InBuf[2] = buffer[i];
-
-				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
-			}
-		}
-		else
-		{
-				addr = BlkNum * 0x10 ;
-
-				InBuf[0] = addr+(Offset % 16);
-				InBuf[1] = 2;
-				InBuf[2] = pData[0];
-
-				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
-		}
-
-		//Step 4. Write mapping table
-		addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-		tmpaddr = addr;
+		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+		pAd->MACVersion = MacCsr0;
 
-		if(addr % 2 != 0)
-			addr = addr -1;
-		InBuf[0] = addr;
-		InBuf[1] = 2;
-
-		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
-		tmpOffset = Offset;
-		tmpOffset >>= 4;
-		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
-		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
-
-		// write the logical address
-		if(tmpaddr%2 != 0)
-			InBuf[2] = tmpOffset<<8;
-		else
-			InBuf[2] = tmpOffset;
-
-		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
-
-		//Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
-		bWriteSuccess = TRUE;
-		for(i =0; i<8; i++)
-		{
-			addr = BlkNum * 0x10 ;
-
-			InBuf[0] = addr+2*i;
-			InBuf[1] = 2;
-			InBuf[2] = 0x0;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-			if(buffer[i] != InBuf[2])
-			{
-				bWriteSuccess = FALSE;
-				break;
-			}
-		}
-
-		//Step 6. invlidate mapping entry and find a free mapping entry if not succeed
-		if (!bWriteSuccess)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
-
-			// the offset of current mapping entry
-			addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-			//find a new mapping entry
-			BlkNum = 0xffff;
-			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-			{
-				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-				if( (LogicalAddress & 0xff) == 0)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START;
-					break;
-				}
-				else if(( (LogicalAddress >> 8) & 0xff) == 0)
-				{
-					if (i != EFUSE_USAGE_MAP_END)
-					{
-						BlkNum = i+1-EFUSE_USAGE_MAP_START;
-					}
-					break;
-				}
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
-			if(BlkNum == 0xffff)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
-				return FALSE;
-			}
-
-			//invalidate the original mapping entry if new entry is not found
-			tmpaddr = addr;
-
-			if(addr % 2 != 0)
-				addr = addr -1;
-			InBuf[0] = addr;
-			InBuf[1] = 2;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-			// write the logical address
-			if(tmpaddr%2 != 0)
-			{
-				// Invalidate the high byte
-				for (i=8; i<15; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			else
-			{
-				// invalidate the low byte
-				for (i=0; i<8; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
-		}
-	}
-	while(!bWriteSuccess);
-
-	return TRUE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-VOID eFuseWritePhysical(
-	IN	PRTMP_ADAPTER	pAd,
-  	PUSHORT lpInBuffer,
-	ULONG nInBufferSize,
-  	PUCHAR lpOutBuffer,
-  	ULONG nOutBufferSize
-)
-{
-	USHORT* pInBuf = (USHORT*)lpInBuffer;
-	int 		i;
-	//USHORT* pOutBuf = (USHORT*)ioBuffer;
-
-	USHORT Offset = pInBuf[0];					//addr
-	USHORT Length = pInBuf[1];					//length
-	USHORT* pValueX = &pInBuf[2];				//value ...
-		// Little-endian		S	|	S	Big-endian
-		// addr	3	2	1	0	|	0	1	2	3
-		// Ori-V	D	C	B	A	|	A	B	C	D
-		//After swapping
-		//		D	C	B	A	|	D	C	B	A
-		//Both the little and big-endian use the same sequence to write  data.
-		//Therefore, we only need swap data when read the data.
-	for(i=0; i<Length; i+=2)
-	{
-		eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
-	}
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-NTSTATUS eFuseWrite(
-   	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT			Offset,
-	IN	PUCHAR			pData,
-	IN	USHORT			length)
-{
-	int i;
-
-	USHORT* pValueX = (PUSHORT) pData;				//value ...
-		//The input value=3070 will be stored as following
- 		// Little-endian		S	|	S	Big-endian
-		// addr			1	0	|	0	1
-		// Ori-V			30	70	|	30	70
-		//After swapping
-		//				30	70	|	70	30
-		//Casting
-		//				3070	|	7030 (x)
-		//The swapping should be removed for big-endian
-	for(i=0; i<length; i+=2)
-	{
-		eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
-	}
-
-	return TRUE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-INT set_eFuseGetFreeBlockCount_Proc(
-   	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	USHORT i;
-	USHORT	LogicalAddress;
-	USHORT efusefreenum=0;
-	if(!pAd->bUseEfuse)
-		return FALSE;
-	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
-	{
-		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-		if( (LogicalAddress & 0xff) == 0)
-		{
-			efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
-			break;
-		}
-		else if(( (LogicalAddress >> 8) & 0xff) == 0)
-		{
-			efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
-			break;
-		}
-
-		if(i == EFUSE_USAGE_MAP_END)
-			efusefreenum = 0;
-	}
-	printk("efuseFreeNumber is %d\n",efusefreenum);
-	return TRUE;
-}
-INT set_eFusedump_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-USHORT InBuf[3];
-	INT i=0;
-	if(!pAd->bUseEfuse)
-		return FALSE;
-	for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
-	{
-		InBuf[0] = 2*i;
-		InBuf[1] = 2;
-		InBuf[2] = 0x0;
-
-		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-		if(i%4==0)
-		printk("\nBlock %x:",i/8);
-		printk("%04x ",InBuf[2]);
-	}
-	return TRUE;
-}
-INT	set_eFuseLoadFromBin_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
-{
-	CHAR					*src;
-	struct file				*srcf;
-	INT 					retval;
-   	mm_segment_t			orgfs;
-	UCHAR					*buffer;
-	UCHAR					BinFileSize=0;
-	INT						i = 0,j=0,k=1;
-	USHORT					*PDATA;
-	USHORT					DATA;
-	BinFileSize=strlen("RT30xxEEPROM.bin");
-	src = kmalloc(128, MEM_ALLOC_FLAG);
-	NdisZeroMemory(src, 128);
-
- 	if(strlen(arg)>0)
-	{
-
-		NdisMoveMemory(src, arg, strlen(arg));
- 	}
-
-	else
-	{
-
-		NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
-	buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
-
-	if(buffer == NULL)
-	{
-		kfree(src);
-		 return FALSE;
-}
-	PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
-
-	if(PDATA==NULL)
-	{
-		kfree(src);
-
-		kfree(buffer);
-		return FALSE;
-	}
-
-    	orgfs = get_fs();
-   	 set_fs(KERNEL_DS);
-
-	if (src && *src)
-	{
-		srcf = filp_open(src, O_RDONLY, 0);
-		if (IS_ERR(srcf))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
-			return FALSE;
-		}
-		else
-		{
-			// The object must have a read method
-			if (srcf->f_op && srcf->f_op->read)
-			{
-				memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
-				while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i]));
-					if((i+1)%8==0)
-						DBGPRINT(RT_DEBUG_TRACE, ("\n"));
-              			i++;
-						if(i>=MAX_EEPROM_BIN_FILE_SIZE)
-							{
-								DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src));
-								kfree(PDATA);
-								kfree(buffer);
-								kfree(src);
-								return FALSE;
-							}
-			       }
-			}
-			else
-			{
-						DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
-						kfree(PDATA);
-						kfree(buffer);
-						kfree(src);
-						return FALSE;
-			}
-      		}
-
-
-	}
-	else
-		{
-					DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
-					kfree(PDATA);
-					kfree(buffer);
-					return FALSE;
-
-		}
-
-
-	retval=filp_close(srcf,NULL);
-
-	if (retval)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
-	}
-	set_fs(orgfs);
-
-	for(j=0;j<i;j++)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]));
-		if((j+1)%2==0)
-			PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
-		if(j%16==0)
-		{
-			k=buffer[j];
-		}
-		else
-		{
-			k&=buffer[j];
-			if((j+1)%16==0)
-			{
-
-				DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
-
-				if(k!=0xff)
-					eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
-				else
-					{
-						if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
-							eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
-					}
-				/*
-				for(l=0;l<8;l++)
-					printk("%04x ",PDATA[l]);
-				printk("\n");
-				*/
-				NdisZeroMemory(PDATA,16);
-
-
-			}
-		}
-
-
-	}
-
-
-	kfree(PDATA);
-	kfree(buffer);
-	kfree(src);
-	return TRUE;
-}
-NTSTATUS eFuseWriteRegistersFromBin(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	USHORT Offset,
-	IN	USHORT Length,
-	IN	USHORT* pData)
-{
-	USHORT	i;
-	USHORT	eFuseData;
-	USHORT	LogicalAddress, BlkNum = 0xffff;
-	UCHAR	EFSROM_AOUT,Loop=0;
-	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
-	USHORT	efuseDataOffset;
-	UINT32	data,tempbuffer;
-	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
-	UINT32 buffer[4];
-	BOOLEAN		bWriteSuccess = TRUE;
-	BOOLEAN		bNotWrite=TRUE;
-	BOOLEAN		bAllocateNewBlk=TRUE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
-
-	do
-	{
-	//Step 0. find the entry in the mapping table
-	//The address of EEPROM is 2-bytes alignment.
-	//The last bit is used for alignment, so it must be 0.
-	Loop++;
-	tmpOffset = Offset & 0xfffe;
-	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
-
-	if( EFSROM_AOUT == 0x3f)
-	{	//find available logical address pointer
-		//the logical address does not exist, find an empty one
-		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
-		//==>48*16-3(reserved)=2FC
-		bAllocateNewBlk=TRUE;
-		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-		{
-			//Retrive the logical block nubmer form each logical address pointer
-			//It will access two logical address pointer each time.
-			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-			if( (LogicalAddress & 0xff) == 0)
-			{//Not used logical address pointer
-				BlkNum = i-EFUSE_USAGE_MAP_START;
-				break;
-			}
-			else if(( (LogicalAddress >> 8) & 0xff) == 0)
-			{//Not used logical address pointer
-				if (i != EFUSE_USAGE_MAP_END)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START+1;
-				}
-				break;
-			}
-		}
-	}
-	else
-	{
-		bAllocateNewBlk=FALSE;
-		BlkNum = EFSROM_AOUT;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
-
-	if(BlkNum == 0xffff)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
-		return FALSE;
-	}
-	//Step 1.1.0
-	//If the block is not existing in mapping table, create one
-	//and write down the 16-bytes data to the new block
-	if(bAllocateNewBlk)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
-		efuseDataOffset =  EFUSE_DATA3;
-		for(i=0; i< 4; i++)
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
-			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
-
-
-			RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
-			efuseDataOffset -= 4;
-
-		}
-		/////////////////////////////////////////////////////////////////
-
-		//Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-		eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
-
-		//Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
-		eFuseCtrlStruc.field.EFSROM_MODE = 3;
-
-		//Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
-		eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-
-		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-		//Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done.
-		i = 0;
-		while(i < 100)
-		{
-			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+		if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
 				break;
 
-			RTMPusecDelay(2);
-			i++;
-		}
+		RTMPusecDelay(10);
+	} while (index++ < 100);
 
-	}
-	else
-	{	//Step1.2.
-		//If the same logical number is existing, check if the writting data and the data
-		//saving in this block are the same.
-		/////////////////////////////////////////////////////////////////
-		//read current values of 16-byte block
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-		//Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
-		eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-		//Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
-		eFuseCtrlStruc.field.EFSROM_MODE = 0;
-
-		//Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
-		eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-		//Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
-		i = 0;
-		while(i < 100)
-		{
-			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
-
-			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
-				break;
-			RTMPusecDelay(2);
-			i++;
-		}
-
-		//Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
-		efuseDataOffset =  EFUSE_DATA3;
-		for(i=0; i< 4; i++)
-		{
-			RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
-			efuseDataOffset -=  4;
-		}
-		//Step1.2.5. Check if the data of efuse and the writing data are the same.
-		for(i =0; i<4; i++)
-		{
-			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
-			DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
-
-			if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
-				bNotWrite&=TRUE;
-			else
+	pAd->bUseEfuse=FALSE;
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
+	pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
+	if(pAd->bUseEfuse)
 			{
-				bNotWrite&=FALSE;
-				break;
-			}
-		}
-		if(!bNotWrite)
-		{
-		printk("The data is not the same\n");
-
-			for(i =0; i<8; i++)
-			{
-				addr = BlkNum * 0x10 ;
-
-				InBuf[0] = addr+2*i;
-				InBuf[1] = 2;
-				InBuf[2] = pData[i];
-
-				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
-			}
-
-		}
-		else
-			return TRUE;
+		pChipOps->eeinit = eFuse_init;
+		pChipOps->eeread = rtmp_ee_efuse_read16;
+		pChipOps->eewrite = rtmp_ee_efuse_write16;
+		return 0 ;
 	     }
-
-
-
-		//Step 2. Write mapping table
-		addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-		tmpaddr = addr;
-
-		if(addr % 2 != 0)
-			addr = addr -1;
-		InBuf[0] = addr;
-		InBuf[1] = 2;
-
-		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
-		tmpOffset = Offset;
-		tmpOffset >>= 4;
-		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
-		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
-
-		// write the logical address
-		if(tmpaddr%2 != 0)
-			InBuf[2] = tmpOffset<<8;
 		else
-			InBuf[2] = tmpOffset;
-
-		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
-
-		//Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
-		bWriteSuccess = TRUE;
-		for(i =0; i<8; i++)
-		{
-			addr = BlkNum * 0x10 ;
-
-			InBuf[0] = addr+2*i;
-			InBuf[1] = 2;
-			InBuf[2] = 0x0;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-			DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
-			if(pData[i] != InBuf[2])
 			{
-				bWriteSuccess = FALSE;
-				break;
+		pAd->bFroceEEPROMBuffer = FALSE;
+		DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
 			}
-		}
-
-		//Step 4. invlidate mapping entry and find a free mapping entry if not succeed
+#endif // RTMP_EFUSE_SUPPORT //
+#endif // RT30xx //
 
-		if (!bWriteSuccess&&Loop<2)
+	switch(infType)
 		{
-			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
-
-			// the offset of current mapping entry
-			addr = EFUSE_USAGE_MAP_START+BlkNum;
-
-			//find a new mapping entry
-			BlkNum = 0xffff;
-			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
-			{
-				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-				if( (LogicalAddress & 0xff) == 0)
-				{
-					BlkNum = i-EFUSE_USAGE_MAP_START;
+#ifdef RTMP_PCI_SUPPORT
+		case RTMP_DEV_INF_PCI:
+			pChipOps->eeinit = NULL;
+			pChipOps->eeread = rtmp_ee_prom_read16;
+			pChipOps->eewrite = rtmp_ee_prom_write16;
 					break;
-				}
-				else if(( (LogicalAddress >> 8) & 0xff) == 0)
-				{
-					if (i != EFUSE_USAGE_MAP_END)
-					{
-						BlkNum = i+1-EFUSE_USAGE_MAP_START;
-					}
+#endif // RTMP_PCI_SUPPORT //
+#ifdef RTMP_USB_SUPPORT
+		case RTMP_DEV_INF_USB:
+			pChipOps->eeinit = NULL;
+			pChipOps->eeread = RTUSBReadEEPROM16;
+			pChipOps->eewrite = RTUSBWriteEEPROM16;
 					break;
-				}
-			}
-			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
-			if(BlkNum == 0xffff)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
-				return FALSE;
-			}
-
-			//invalidate the original mapping entry if new entry is not found
-			tmpaddr = addr;
+#endif // RTMP_USB_SUPPORT //
 
-			if(addr % 2 != 0)
-				addr = addr -1;
-			InBuf[0] = addr;
-			InBuf[1] = 2;
-
-			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-
-			// write the logical address
-			if(tmpaddr%2 != 0)
-			{
-				// Invalidate the high byte
-				for (i=8; i<15; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
+		default:
+			DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n"));
 						break;
 					}
-				}
-			}
-			else
-			{
-				// invalidate the low byte
-				for (i=0; i<8; i++)
-				{
-					if( ( (InBuf[2] >> i) & 0x01) == 0)
-					{
-						InBuf[2] |= (0x1 <<i);
-						break;
-					}
-				}
-			}
-			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
-		}
-
-	}
-	while(!bWriteSuccess&&Loop<2);
 
-	return TRUE;
+	return 0;
 }
-#endif

+ 1 - 1
drivers/staging/rt2860/common/firmware.h

@@ -43,7 +43,7 @@
 /* AUTO GEN PLEASE DO NOT MODIFY IT */
 
 
-UCHAR FirmwareImage [] = {
+UCHAR FirmwareImage_2860 [] = {
 0x02, 0x03, 0x5e, 0x02, 0x02, 0xb1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x82, 0xff, 0xff,
 0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x33, 0xc0, 0xe0,
 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,

+ 517 - 0
drivers/staging/rt2860/common/firmware_3070.h

@@ -0,0 +1,517 @@
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+
+
+UCHAR FirmwareImage_3070 [] = {
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
+0x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
+0x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
+0x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
+0xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
+0x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
+0x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
+0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
+0x02, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
+0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
+0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
+0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
+0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
+0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
+0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
+0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
+0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14,
+0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
+0x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
+0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
+0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
+0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
+0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2,
+0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
+0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
+0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
+0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
+0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
+0x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
+0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
+0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
+0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
+0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
+0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
+0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
+0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
+0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
+0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
+0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
+0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
+0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
+0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
+0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
+0xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
+0x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
+0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
+0x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
+0x9d, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
+0x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
+0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
+0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
+0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
+0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
+0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
+0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
+0xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
+0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
+0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
+0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
+0x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
+0x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
+0x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
+0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
+0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
+0x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
+0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
+0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
+0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
+0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
+0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
+0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
+0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
+0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
+0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
+0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
+0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
+0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
+0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
+0x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
+0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
+0x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
+0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
+0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
+0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
+0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
+0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
+0x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
+0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
+0x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
+0x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
+0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
+0x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
+0x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
+0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
+0xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
+0x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
+0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
+0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
+0xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
+0x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
+0x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
+0x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
+0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
+0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
+0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
+0x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
+0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
+0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
+0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
+0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
+0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
+0x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
+0x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
+0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
+0x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
+0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
+0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
+0xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
+0x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
+0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
+0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
+0x0d, 0x2a, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
+0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
+0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
+0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
+0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
+0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
+0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
+0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
+0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
+0x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
+0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
+0x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
+0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
+0x7f, 0x01, 0x12, 0x0d, 0x2a, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
+0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
+0x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
+0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
+0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
+0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
+0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
+0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
+0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
+0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
+0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
+0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x7b, 0xc4,
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x13, 0x1f, 0x02,
+0x13, 0x20, 0x02, 0x13, 0x3f, 0x02, 0x13, 0x44, 0x12, 0x13, 0x40, 0x22, 0x02, 0x17, 0xae, 0x02,
+0x18, 0xd2, 0x02, 0x14, 0x3d, 0x02, 0x13, 0x78, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x19,
+0x95, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x13, 0x1e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
+0xd9, 0x31, 0x10, 0xbd, 0x36, 0x11, 0x02, 0x50, 0x11, 0x39, 0x51, 0x11, 0x42, 0x52, 0x11, 0x42,
+0x53, 0x11, 0x42, 0x54, 0x11, 0x83, 0x55, 0x11, 0xd2, 0x56, 0x12, 0x25, 0x70, 0x12, 0x50, 0x71,
+0x12, 0x7e, 0x72, 0x12, 0xd5, 0x73, 0x12, 0xf6, 0x80, 0x00, 0x00, 0x13, 0x1e, 0x90, 0x70, 0x11,
+0xe0, 0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d,
+0x02, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
+0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x85, 0x56, 0x41, 0xd2,
+0x02, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0,
+0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff,
+0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04, 0xe0, 0xb4, 0x20, 0x06, 0x75,
+0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92,
+0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0,
+0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48,
+0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14,
+0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e,
+0x02, 0x13, 0x17, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5,
+0x47, 0x64, 0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60,
+0x05, 0xe5, 0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47,
+0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08,
+0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2,
+0x04, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70,
+0x11, 0xe0, 0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19,
+0xf0, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70,
+0x18, 0xe0, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
+0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
+0x02, 0x28, 0xef, 0xf0, 0x22, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed,
+0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
+0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17,
+0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
+0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x1e, 0x02, 0x13, 0x17, 0x90, 0x10,
+0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5, 0x59, 0xe5, 0x58,
+0xb4, 0x70, 0x1e, 0xe5, 0x59, 0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd,
+0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08,
+0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56,
+0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
+0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
+0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
+0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22,
+0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04,
+0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22,
+0xc2, 0x42, 0xd3, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70,
+0x18, 0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef,
+0x5e, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff,
+0x90, 0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a,
+0xb6, 0x13, 0x9a, 0x00, 0x14, 0x28, 0x04, 0x14, 0x24, 0x08, 0x14, 0x04, 0x10, 0x13, 0xae, 0x20,
+0x13, 0xce, 0x60, 0x13, 0xdf, 0xa0, 0x00, 0x00, 0x14, 0x2a, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42,
+0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x14, 0x2a, 0x80, 0x1b, 0xe5, 0x48,
+0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54,
+0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49,
+0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5,
+0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4,
+0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10,
+0xf5, 0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43,
+0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30,
+0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4,
+0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5,
+0x47, 0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22,
+0x12, 0x17, 0x79, 0x12, 0x14, 0x5f, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45,
+0x4f, 0x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74,
+0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5,
+0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
+0x25, 0x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
+0xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
+0x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25,
+0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02,
+0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b,
+0xe5, 0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5,
+0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5,
+0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2,
+0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e,
+0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26, 0x30,
+0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80,
+0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
+0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x26,
+0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80,
+0x26, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17,
+0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x34, 0xe5, 0x46, 0x20, 0xe4, 0x03,
+0x30, 0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
+0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54,
+0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92,
+0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3,
+0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13,
+0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47,
+0x64, 0x06, 0x70, 0x39, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f,
+0x14, 0x60, 0x0c, 0x24, 0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2,
+0x38, 0x80, 0x0b, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47,
+0x05, 0xaf, 0x27, 0x02, 0x17, 0x73, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x17, 0x73, 0xe5, 0x47, 0x64,
+0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02,
+0x16, 0xf2, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60,
+0x25, 0x14, 0x60, 0x2d, 0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50,
+0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a,
+0xd2, 0x39, 0xc2, 0x38, 0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80,
+0x1a, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f,
+0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80,
+0x13, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04,
+0xc2, 0x38, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02,
+0x17, 0x73, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02,
+0x29, 0xe0, 0x54, 0xfd, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b,
+0x24, 0xfc, 0x60, 0x45, 0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13,
+0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d,
+0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f,
+0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80,
+0x01, 0xc3, 0x92, 0x39, 0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5,
+0x27, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02,
+0x29, 0xe0, 0x54, 0xeb, 0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90,
+0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02,
+0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5,
+0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x48, 0x14, 0x60, 0x66, 0x24, 0x02, 0x60, 0x03, 0x02,
+0x18, 0xb6, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0,
+0x20, 0xe7, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3,
+0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0,
+0x75, 0x51, 0x01, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x62, 0x03, 0x02, 0x18, 0xb6,
+0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x12, 0x7f, 0x20, 0x12, 0x17, 0xa4, 0x90, 0x02, 0xa2,
+0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x18, 0xb6, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x18,
+0xb1, 0x90, 0x02, 0xa3, 0xe0, 0x30, 0xe6, 0x03, 0x02, 0x18, 0xad, 0x90, 0x04, 0x37, 0xe0, 0x64,
+0x22, 0x70, 0x7a, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04,
+0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35, 0x10, 0xe4, 0x90, 0x05,
+0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12,
+0x0d, 0x48, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xe5, 0x59,
+0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3, 0x80, 0x14, 0x90, 0x13,
+0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0,
+0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54,
+0xfd, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70,
+0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2,
+0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2,
+0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59,
+0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x19, 0x61, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70,
+0x6d, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13,
+0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
+0x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90,
+0x05, 0x00, 0x74, 0xe2, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0,
+0x7f, 0x01, 0x12, 0x0d, 0x48, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0,
+0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf,
+0x41, 0x12, 0x19, 0x61, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf,
+0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
+0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef,
+0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe,
+0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70,
+0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70,
+0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0,
+0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90,
+0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70,
+0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x65, 0xd3, } ;

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 475 - 344
drivers/staging/rt2860/common/mlme.c


+ 1280 - 0
drivers/staging/rt2860/common/rt_channel.c

@@ -0,0 +1,1280 @@
+/*
+ *************************************************************************
+ * 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.             *
+ *                                                                       *
+ *************************************************************************
+*/
+#include "../rt_config.h"
+
+
+CH_FREQ_MAP CH_HZ_ID_MAP[]=
+		{
+			{1, 2412},
+			{2, 2417},
+			{3, 2422},
+			{4, 2427},
+			{5, 2432},
+			{6, 2437},
+			{7, 2442},
+			{8, 2447},
+			{9, 2452},
+			{10, 2457},
+			{11, 2462},
+			{12, 2467},
+			{13, 2472},
+			{14, 2484},
+
+			/*  UNII */
+			{36, 5180},
+			{40, 5200},
+			{44, 5220},
+			{48, 5240},
+			{52, 5260},
+			{56, 5280},
+			{60, 5300},
+			{64, 5320},
+			{149, 5745},
+			{153, 5765},
+			{157, 5785},
+			{161, 5805},
+			{165, 5825},
+			{167, 5835},
+			{169, 5845},
+			{171, 5855},
+			{173, 5865},
+
+			/* HiperLAN2 */
+			{100, 5500},
+			{104, 5520},
+			{108, 5540},
+			{112, 5560},
+			{116, 5580},
+			{120, 5600},
+			{124, 5620},
+			{128, 5640},
+			{132, 5660},
+			{136, 5680},
+			{140, 5700},
+
+			/* Japan MMAC */
+			{34, 5170},
+			{38, 5190},
+			{42, 5210},
+			{46, 5230},
+
+			/*  Japan */
+			{184, 4920},
+			{188, 4940},
+			{192, 4960},
+			{196, 4980},
+
+			{208, 5040},	/* Japan, means J08 */
+			{212, 5060},	/* Japan, means J12 */
+			{216, 5080},	/* Japan, means J16 */
+};
+
+INT	CH_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP)/sizeof(CH_FREQ_MAP));
+
+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 PCH_REGION GetChRegion(
+	IN PUCHAR CntryCode)
+{
+	INT loop = 0;
+	PCH_REGION pChRegion = NULL;
+
+	while (strcmp((PSTRING) ChRegion[loop].CountReg, "") != 0)
+	{
+		if (strncmp((PSTRING) ChRegion[loop].CountReg, (PSTRING) CntryCode, 2) == 0)
+		{
+			pChRegion = &ChRegion[loop];
+			break;
+		}
+		loop++;
+	}
+
+	if (pChRegion == NULL)
+		pChRegion = &ChRegion[loop];
+	return pChRegion;
+}
+
+static 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 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);
+        }
+	}
+}
+
+
+VOID BuildChannelListEx(
+	IN PRTMP_ADAPTER pAd)
+{
+	PCH_REGION pChReg;
+
+	pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
+	CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
+}
+
+
+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 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 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;
+}
+
+
+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()
+			}
+		}
+	}
+
+
+}
+
+
+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;
+	}
+}
+
+
+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;
+	}
+
+	if (i == pAd->ChannelListNum)
+		return 0xff;
+	else
+		return pAd->ChannelList[i].MaxTxPwr;
+}

+ 194 - 0
drivers/staging/rt2860/common/rt_rf.c

@@ -0,0 +1,194 @@
+/*
+ *************************************************************************
+ * 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:
+	rt_rf.c
+
+	Abstract:
+	Ralink Wireless driver RF related functions
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+
+#include "../rt_config.h"
+
+
+#ifdef RTMP_RF_RW_SUPPORT
+/*
+	========================================================================
+
+	Routine Description: Write RT30xx RF register through MAC
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS RT30xxWriteRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			regID,
+	IN	UCHAR			value)
+{
+	RF_CSR_CFG_STRUC	rfcsr;
+	UINT				i = 0;
+
+	do
+	{
+		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+		if (!rfcsr.field.RF_CSR_KICK)
+			break;
+		i++;
+	}
+	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	rfcsr.field.RF_CSR_WR = 1;
+	rfcsr.field.RF_CSR_KICK = 1;
+	rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
+	rfcsr.field.RF_CSR_DATA = value;
+
+	RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description: Read RT30xx RF register through MAC
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS RT30xxReadRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			regID,
+	IN	PUCHAR			pValue)
+{
+	RF_CSR_CFG_STRUC	rfcsr;
+	UINT				i=0, k=0;
+
+	for (i=0; i<MAX_BUSY_COUNT; i++)
+	{
+		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+		if (rfcsr.field.RF_CSR_KICK == BUSY)
+		{
+			continue;
+		}
+		rfcsr.word = 0;
+		rfcsr.field.RF_CSR_WR = 0;
+		rfcsr.field.RF_CSR_KICK = 1;
+		rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
+		RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+		for (k=0; k<MAX_BUSY_COUNT; k++)
+		{
+			RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+			if (rfcsr.field.RF_CSR_KICK == IDLE)
+				break;
+		}
+		if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
+			(rfcsr.field.TESTCSR_RFACC_REGNUM == regID))
+		{
+			*pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
+			break;
+		}
+	}
+	if (rfcsr.field.RF_CSR_KICK == BUSY)
+	{
+		DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID, rfcsr.word,i,k));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	return STATUS_SUCCESS;
+}
+
+
+VOID NICInitRFRegisters(
+	IN RTMP_ADAPTER *pAd)
+{
+	if (pAd->chipOps.AsicRfInit)
+		pAd->chipOps.AsicRfInit(pAd);
+}
+
+
+VOID RtmpChipOpsRFHook(
+	IN RTMP_ADAPTER *pAd)
+{
+	RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+
+	pChipOps->pRFRegTable = NULL;
+	pChipOps->AsicRfInit = NULL;
+	pChipOps->AsicRfTurnOn = NULL;
+	pChipOps->AsicRfTurnOff = NULL;
+	pChipOps->AsicReverseRfFromSleepMode = NULL;
+	pChipOps->AsicHaltAction = NULL;
+	/* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */
+
+#ifdef RT30xx
+	if (IS_RT30xx(pAd))
+	{
+		pChipOps->pRFRegTable = RT30xx_RFRegTable;
+		pChipOps->AsicHaltAction = RT30xxHaltAction;
+#ifdef RT3070
+		if((IS_RT3070(pAd) || IS_RT3071(pAd)) && (pAd->infType == RTMP_DEV_INF_USB))
+		{
+			pChipOps->AsicRfInit = NICInitRT3070RFRegisters;
+			if (IS_RT3071(pAd))
+			{
+				pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup;
+				pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup;
+			}
+		}
+#endif // RT3070 //
+	}
+#endif // RT30xx //
+}
+
+#endif // RTMP_RF_RW_SUPPORT //

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 101 - 687
drivers/staging/rt2860/common/rtmp_init.c


+ 233 - 0
drivers/staging/rt2860/common/rtmp_mcu.c

@@ -0,0 +1,233 @@
+/*
+ *************************************************************************
+ * 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_mcu.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+
+#include	"../rt_config.h"
+
+#ifdef RT2860
+#include "firmware.h"
+#endif
+#ifdef RT2870
+#include "../../rt3070/firmware.h"
+#include "firmware_3070.h"
+#endif
+
+#include <linux/bitrev.h>
+
+//#define BIN_IN_FILE /* use *.bin firmware */
+
+#ifdef RTMP_MAC_USB
+//
+// RT2870 Firmware Spec only used 1 oct for version expression
+//
+#define FIRMWARE_MINOR_VERSION	7
+#endif // RTMP_MAC_USB //
+
+// New 8k byte firmware size for RT3071/RT3072
+#define FIRMWAREIMAGE_MAX_LENGTH	0x2000
+#define FIRMWAREIMAGE_LENGTH			(sizeof (FirmwareImage) / sizeof(UCHAR))
+#define FIRMWARE_MAJOR_VERSION		0
+
+#define FIRMWAREIMAGEV1_LENGTH		0x1000
+#define FIRMWAREIMAGEV2_LENGTH		0x1000
+
+#ifdef RTMP_MAC_PCI
+#define FIRMWARE_MINOR_VERSION		2
+#endif // RTMP_MAC_PCI //
+
+/*
+	========================================================================
+
+	Routine Description:
+		erase 8051 firmware image in MAC ASIC
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+INT RtmpAsicEraseFirmware(
+	IN PRTMP_ADAPTER pAd)
+{
+	ULONG i;
+
+	for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
+		RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
+
+	return 0;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Load 8051 firmware file into MAC ASIC
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS         firmware image load ok
+		NDIS_STATUS_FAILURE         image not found
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+NDIS_STATUS RtmpAsicLoadFirmware(
+	IN PRTMP_ADAPTER pAd)
+{
+
+	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
+	PUCHAR			pFirmwareImage;
+	ULONG			FileLength, Index;
+	//ULONG			firm;
+	UINT32			MacReg = 0;
+	UINT32			Version = (pAd->MACVersion >> 16);
+
+//	pFirmwareImage = FirmwareImage;
+//	FileLength = sizeof(FirmwareImage);
+
+	// New 8k byte firmware size for RT3071/RT3072
+	{
+#ifdef RTMP_MAC_PCI
+		if ((Version == 0x2860) || (Version == 0x3572) || IS_RT3090(pAd))
+		{
+			pFirmwareImage = FirmwareImage_2860;
+			FileLength = FIRMWAREIMAGE_MAX_LENGTH;
+		}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+		/* the firmware image consists of two parts */
+		if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
+		{	/* use the second part */
+			//printk("KH:Use New Version,part2\n");
+			pFirmwareImage = (PUCHAR)&FirmwareImage_3070[FIRMWAREIMAGEV1_LENGTH];
+			FileLength = FIRMWAREIMAGEV2_LENGTH;
+		}
+		else
+		{
+			//printk("KH:Use New Version,part1\n");
+			if (Version == 0x3070)
+				pFirmwareImage = FirmwareImage_3070;
+			else
+				pFirmwareImage = FirmwareImage_2870;
+			FileLength = FIRMWAREIMAGEV1_LENGTH;
+		}
+#endif // RTMP_MAC_USB //
+	}
+
+	RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
+
+
+	/* check if MCU is ready */
+	Index = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
+
+		if (MacReg & 0x80)
+			break;
+
+		RTMPusecDelay(1000);
+	} while (Index++ < 1000);
+
+	if (Index > 1000)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
+		Status = NDIS_STATUS_FAILURE;
+	}
+
+    DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __func__, Status));
+
+    return Status;
+}
+
+
+INT RtmpAsicSendCommandToMcu(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 Command,
+	IN UCHAR		 Token,
+	IN UCHAR		 Arg0,
+	IN UCHAR		 Arg1)
+{
+	HOST_CMD_CSR_STRUC	H2MCmd;
+	H2M_MAILBOX_STRUC	H2MMailbox;
+	ULONG				i = 0;
+#ifdef RTMP_MAC_PCI
+#endif // RTMP_MAC_PCI //
+
+	do
+	{
+		RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
+		if (H2MMailbox.field.Owner == 0)
+			break;
+
+		RTMPusecDelay(2);
+	} while(i++ < 100);
+
+	if (i > 100)
+	{
+#ifdef RTMP_MAC_PCI
+#endif // RTMP_MAC_PCI //
+		{
+		DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
+		}
+		return FALSE;
+	}
+
+#ifdef RTMP_MAC_PCI
+#endif // RTMP_MAC_PCI //
+
+	H2MMailbox.field.Owner	  = 1;	   // pass ownership to MCU
+	H2MMailbox.field.CmdToken = Token;
+	H2MMailbox.field.HighByte = Arg1;
+	H2MMailbox.field.LowByte  = Arg0;
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
+
+	H2MCmd.word			  = 0;
+	H2MCmd.field.HostCommand  = Command;
+	RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+
+	if (Command != 0x80)
+	{
+	}
+
+	return TRUE;
+}

+ 323 - 0
drivers/staging/rt2860/common/rtmp_timer.c

@@ -0,0 +1,323 @@
+/*
+ *************************************************************************
+ * 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_timer.c
+
+    Abstract:
+    task for timer handling
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+    Name          Date            Modification logs
+    Shiang Tu	08-28-2008   init version
+
+*/
+
+#include "../rt_config.h"
+
+
+BUILD_TIMER_FUNCTION(MlmePeriodicExec);
+//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
+BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+BUILD_TIMER_FUNCTION(APSDPeriodicExec);
+BUILD_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RTMP_MAC_USB
+BUILD_TIMER_FUNCTION(BeaconUpdateExec);
+#endif // RTMP_MAC_USB //
+
+BUILD_TIMER_FUNCTION(BeaconTimeout);
+BUILD_TIMER_FUNCTION(ScanTimeout);
+BUILD_TIMER_FUNCTION(AuthTimeout);
+BUILD_TIMER_FUNCTION(AssocTimeout);
+BUILD_TIMER_FUNCTION(ReassocTimeout);
+BUILD_TIMER_FUNCTION(DisassocTimeout);
+BUILD_TIMER_FUNCTION(LinkDownExec);
+BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+#ifdef RTMP_PCI_SUPPORT
+BUILD_TIMER_FUNCTION(PsPollWakeExec);
+BUILD_TIMER_FUNCTION(RadioOnExec);
+#endif // RTMP_PCI_SUPPORT //
+#ifdef RTMP_MAC_USB
+BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout);
+#endif // RTMP_MAC_USB //
+
+#if defined(AP_LED) || defined(STA_LED)
+extern void LedCtrlMain(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+BUILD_TIMER_FUNCTION(LedCtrlMain);
+#endif
+
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+static void RtmpTimerQHandle(RTMP_ADAPTER *pAd)
+{
+#ifndef KTHREAD_SUPPORT
+	int status;
+#endif
+	RALINK_TIMER_STRUCT	*pTimer;
+	RTMP_TIMER_TASK_ENTRY	*pEntry;
+	unsigned long	irqFlag;
+	RTMP_OS_TASK *pTask;
+
+
+	pTask = &pAd->timerTask;
+	while(!pTask->task_killed)
+	{
+		pTimer = NULL;
+
+#ifdef KTHREAD_SUPPORT
+		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
+#else
+		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
+#endif
+
+		if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
+			break;
+
+		// event happened.
+		while(pAd->TimerQ.pQHead)
+		{
+			RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
+			pEntry = pAd->TimerQ.pQHead;
+			if (pEntry)
+			{
+				pTimer = pEntry->pRaTimer;
+
+				// update pQHead
+				pAd->TimerQ.pQHead = pEntry->pNext;
+				if (pEntry == pAd->TimerQ.pQTail)
+					pAd->TimerQ.pQTail = NULL;
+
+				// return this queue entry to timerQFreeList.
+				pEntry->pNext = pAd->TimerQ.pQPollFreeList;
+				pAd->TimerQ.pQPollFreeList = pEntry;
+			}
+			RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
+
+			if (pTimer)
+			{
+				if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend))
+					pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
+				if ((pTimer->Repeat) && (pTimer->State == FALSE))
+					RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
+			}
+		}
+
+#ifndef KTHREAD_SUPPORT
+		if (status != 0)
+		{
+			pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+#endif
+	}
+}
+
+
+INT RtmpTimerQThread(
+	IN OUT PVOID Context)
+{
+	RTMP_OS_TASK	*pTask;
+	PRTMP_ADAPTER	pAd;
+
+
+	pTask = (RTMP_OS_TASK *)Context;
+	pAd = (PRTMP_ADAPTER)pTask->priv;
+
+	RtmpOSTaskCustomize(pTask);
+
+	RtmpTimerQHandle(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
+#ifndef KTHREAD_SUPPORT
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+#endif
+	/* notify the exit routine that we're actually exiting now
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	RtmpOSTaskNotifyToExit(pTask);
+
+	return 0;
+
+}
+
+
+RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer)
+{
+	RTMP_TIMER_TASK_ENTRY *pQNode = NULL, *pQTail;
+	unsigned long irqFlags;
+	RTMP_OS_TASK	*pTask = &pAd->timerTask;
+
+	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+	if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)
+	{
+		if(pAd->TimerQ.pQPollFreeList)
+		{
+			pQNode = pAd->TimerQ.pQPollFreeList;
+			pAd->TimerQ.pQPollFreeList = pQNode->pNext;
+
+			pQNode->pRaTimer = pTimer;
+			pQNode->pNext = NULL;
+
+			pQTail = pAd->TimerQ.pQTail;
+			if (pAd->TimerQ.pQTail != NULL)
+				pQTail->pNext = pQNode;
+			pAd->TimerQ.pQTail = pQNode;
+			if (pAd->TimerQ.pQHead == NULL)
+				pAd->TimerQ.pQHead = pQNode;
+		}
+	}
+	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+	if (pQNode)
+	{
+#ifdef KTHREAD_SUPPORT
+		WAKE_UP(pTask);
+#else
+		RTMP_SEM_EVENT_UP(&pTask->taskSema);
+#endif
+	}
+
+	return pQNode;
+}
+
+
+BOOLEAN RtmpTimerQRemove(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer)
+{
+	RTMP_TIMER_TASK_ENTRY *pNode, *pPrev = NULL;
+	unsigned long irqFlags;
+
+	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+	if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED)
+	{
+		pNode = pAd->TimerQ.pQHead;
+		while (pNode)
+		{
+			if (pNode->pRaTimer == pTimer)
+				break;
+			pPrev = pNode;
+			pNode = pNode->pNext;
+		}
+
+		// Now move it to freeList queue.
+		if (pNode)
+		{
+			if (pNode == pAd->TimerQ.pQHead)
+				pAd->TimerQ.pQHead = pNode->pNext;
+			if (pNode == pAd->TimerQ.pQTail)
+				pAd->TimerQ.pQTail = pPrev;
+			if (pPrev != NULL)
+				pPrev->pNext = pNode->pNext;
+
+			// return this queue entry to timerQFreeList.
+			pNode->pNext = pAd->TimerQ.pQPollFreeList;
+			pAd->TimerQ.pQPollFreeList = pNode;
+		}
+	}
+	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+	return TRUE;
+}
+
+
+void RtmpTimerQExit(RTMP_ADAPTER *pAd)
+{
+	RTMP_TIMER_TASK_ENTRY *pTimerQ;
+	unsigned long irqFlags;
+
+	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+	while (pAd->TimerQ.pQHead)
+	{
+		pTimerQ = pAd->TimerQ.pQHead;
+		pAd->TimerQ.pQHead = pTimerQ->pNext;
+		// remove the timeQ
+	}
+	pAd->TimerQ.pQPollFreeList = NULL;
+	os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
+	pAd->TimerQ.pQTail = NULL;
+	pAd->TimerQ.pQHead = NULL;
+#ifndef KTHREAD_SUPPORT
+	pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
+#endif
+	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+}
+
+
+void RtmpTimerQInit(RTMP_ADAPTER *pAd)
+{
+	int	i;
+	RTMP_TIMER_TASK_ENTRY *pQNode, *pEntry;
+	unsigned long irqFlags;
+
+	NdisAllocateSpinLock(&pAd->TimerQLock);
+
+	NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
+
+	os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
+	if (pAd->TimerQ.pTimerQPoll)
+	{
+		pEntry = NULL;
+		pQNode = (RTMP_TIMER_TASK_ENTRY *)pAd->TimerQ.pTimerQPoll;
+		NdisZeroMemory(pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
+
+		RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+		for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
+		{
+			pQNode->pNext = pEntry;
+			pEntry = pQNode;
+			pQNode++;
+		}
+		pAd->TimerQ.pQPollFreeList = pEntry;
+		pAd->TimerQ.pQHead = NULL;
+		pAd->TimerQ.pQTail = NULL;
+		pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
+		RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+	}
+}
+#endif // RTMP_TIMER_TASK_SUPPORT //

+ 397 - 63
drivers/staging/rt2860/common/spectrum.c

@@ -40,6 +40,239 @@
 #include "../rt_config.h"
 #include "action.h"
 
+
+/* The regulatory information in the USA (US) */
+DOT11_REGULATORY_INFORMATION USARegulatoryInfo[] =
+{
+/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
+    {0,	                {0,                   0,           {0}}}, // Invlid entry
+    {1,                 {4,                   16,           {36, 40, 44, 48}}},
+    {2,                 {4,                   23,           {52, 56, 60, 64}}},
+    {3,                 {4,                   29,           {149, 153, 157, 161}}},
+    {4,                 {11,                  23,           {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
+    {5,                 {5,                   30,           {149, 153, 157, 161, 165}}},
+    {6,                 {10,                  14,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
+    {7,                 {10,                  27,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
+    {8,                 {5,                   17,           {11, 13, 15, 17, 19}}},
+    {9,                 {5,                   30,           {11, 13, 15, 17, 19}}},
+    {10,                {2,                   20,           {21, 25}}},
+    {11,                {2,                   33,            {21, 25}}},
+    {12,                {11,                  30,            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}}
+};
+#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
+
+
+/* The regulatory information in Europe */
+DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo[] =
+{
+/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
+    {0,                 {0,                   0,           {0}}}, // Invalid entry
+    {1,                 {4,                   20,           {36, 40, 44, 48}}},
+    {2,                 {4,                   20,           {52, 56, 60, 64}}},
+    {3,                 {11,                  30,           {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
+    {4,                 {13,                  20,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}
+};
+#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
+
+
+/* The regulatory information in Japan */
+DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo[] =
+{
+/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
+    {0,                 {0,                   0,           {0}}}, // Invalid entry
+    {1,                 {4,                   22,           {34, 38, 42, 46}}},
+    {2,                 {3,                   24,           {8, 12, 16}}},
+    {3,                 {3,                   24,           {8, 12, 16}}},
+    {4,                 {3,                   24,           {8, 12, 16}}},
+    {5,                 {3,                   24,           {8, 12, 16}}},
+    {6,                 {3,                   22,           {8, 12, 16}}},
+    {7,                 {4,                   24,           {184, 188, 192, 196}}},
+    {8,                 {4,                   24,           {184, 188, 192, 196}}},
+    {9,                 {4,                   24,           {184, 188, 192, 196}}},
+    {10,                {4,                   24,           {184, 188, 192, 196}}},
+    {11,                {4,                   22,           {184, 188, 192, 196}}},
+    {12,                {4,                   24,           {7, 8, 9, 11}}},
+    {13,                {4,                   24,           {7, 8, 9, 11}}},
+    {14,                {4,                   24,           {7, 8, 9, 11}}},
+    {15,                {4,                   24,           {7, 8, 9, 11}}},
+    {16,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
+    {17,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
+    {18,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
+    {19,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
+    {20,                {6,                   17,           {183, 184, 185, 187, 188, 189}}},
+    {21,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
+    {22,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
+    {23,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
+    {24,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
+    {25,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {26,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {27,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {28,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {29,                {8,                   17,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {30,                {13,                  23,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}},
+    {31,                {1,                   23,           {14}}},
+    {32,                {4,                   22,           {52, 56, 60, 64}}}
+};
+#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
+
+
+CHAR RTMP_GetTxPwr(
+	IN PRTMP_ADAPTER pAd,
+	IN HTTRANSMIT_SETTING HTTxMode)
+{
+typedef struct __TX_PWR_CFG
+{
+	UINT8 Mode;
+	UINT8 MCS;
+	UINT16 req;
+	UINT8 shift;
+	UINT32 BitMask;
+} TX_PWR_CFG;
+
+	UINT32 Value;
+	INT Idx;
+	UINT8 PhyMode;
+	CHAR CurTxPwr;
+	UINT8 TxPwrRef = 0;
+	CHAR DaltaPwr;
+	ULONG TxPwr[5];
+
+
+	TX_PWR_CFG TxPwrCfg[] = {
+		{MODE_CCK, 0, 0, 4, 0x000000f0},
+		{MODE_CCK, 1, 0, 0, 0x0000000f},
+		{MODE_CCK, 2, 0, 12, 0x0000f000},
+		{MODE_CCK, 3, 0, 8, 0x00000f00},
+
+		{MODE_OFDM, 0, 0, 20, 0x00f00000},
+		{MODE_OFDM, 1, 0, 16, 0x000f0000},
+		{MODE_OFDM, 2, 0, 28, 0xf0000000},
+		{MODE_OFDM, 3, 0, 24, 0x0f000000},
+		{MODE_OFDM, 4, 1, 4, 0x000000f0},
+		{MODE_OFDM, 5, 1, 0, 0x0000000f},
+		{MODE_OFDM, 6, 1, 12, 0x0000f000},
+		{MODE_OFDM, 7, 1, 8, 0x00000f00}
+		,{MODE_HTMIX, 0, 1, 20, 0x00f00000},
+		{MODE_HTMIX, 1, 1, 16, 0x000f0000},
+		{MODE_HTMIX, 2, 1, 28, 0xf0000000},
+		{MODE_HTMIX, 3, 1, 24, 0x0f000000},
+		{MODE_HTMIX, 4, 2, 4, 0x000000f0},
+		{MODE_HTMIX, 5, 2, 0, 0x0000000f},
+		{MODE_HTMIX, 6, 2, 12, 0x0000f000},
+		{MODE_HTMIX, 7, 2, 8, 0x00000f00},
+		{MODE_HTMIX, 8, 2, 20, 0x00f00000},
+		{MODE_HTMIX, 9, 2, 16, 0x000f0000},
+		{MODE_HTMIX, 10, 2, 28, 0xf0000000},
+		{MODE_HTMIX, 11, 2, 24, 0x0f000000},
+		{MODE_HTMIX, 12, 3, 4, 0x000000f0},
+		{MODE_HTMIX, 13, 3, 0, 0x0000000f},
+		{MODE_HTMIX, 14, 3, 12, 0x0000f000},
+		{MODE_HTMIX, 15, 3, 8, 0x00000f00}
+	};
+#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG))
+
+	CurTxPwr = 19;
+
+	/* check Tx Power setting from UI. */
+	if (pAd->CommonCfg.TxPowerPercentage > 90)
+		;
+	else if (pAd->CommonCfg.TxPowerPercentage > 60)  /* reduce Pwr for 1 dB. */
+		CurTxPwr -= 1;
+	else if (pAd->CommonCfg.TxPowerPercentage > 30)  /* reduce Pwr for 3 dB. */
+		CurTxPwr -= 3;
+	else if (pAd->CommonCfg.TxPowerPercentage > 15)  /* reduce Pwr for 6 dB. */
+		CurTxPwr -= 6;
+	else if (pAd->CommonCfg.TxPowerPercentage > 9)   /* reduce Pwr for 9 dB. */
+		CurTxPwr -= 9;
+	else                                           /* reduce Pwr for 12 dB. */
+		CurTxPwr -= 12;
+
+	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];
+		}
+	}
+
+
+	switch(HTTxMode.field.MODE)
+	{
+		case MODE_CCK:
+		case MODE_OFDM:
+			Value = TxPwr[1];
+			TxPwrRef = (Value & 0x00000f00) >> 8;
+
+			break;
+
+		case MODE_HTMIX:
+		case MODE_HTGREENFIELD:
+			if (pAd->CommonCfg.TxStream == 1)
+			{
+				Value = TxPwr[2];
+				TxPwrRef = (Value & 0x00000f00) >> 8;
+			}
+			else if (pAd->CommonCfg.TxStream == 2)
+			{
+				Value = TxPwr[3];
+				TxPwrRef = (Value & 0x00000f00) >> 8;
+			}
+			break;
+	}
+
+	PhyMode =
+				(HTTxMode.field.MODE == MODE_HTGREENFIELD)
+				? MODE_HTMIX :
+				HTTxMode.field.MODE;
+
+	for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++)
+	{
+		if ((TxPwrCfg[Idx].Mode == PhyMode)
+			&& (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS))
+		{
+			Value = TxPwr[TxPwrCfg[Idx].req];
+			DaltaPwr = TxPwrRef - (CHAR)((Value & TxPwrCfg[Idx].BitMask)
+											>> TxPwrCfg[Idx].shift);
+			CurTxPwr -= DaltaPwr;
+			break;
+		}
+	}
+
+	return CurTxPwr;
+}
+
+
 VOID MeasureReqTabInit(
 	IN PRTMP_ADAPTER pAd)
 {
@@ -57,7 +290,7 @@ VOID MeasureReqTabInit(
 VOID MeasureReqTabExit(
 	IN PRTMP_ADAPTER pAd)
 {
-	NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock);
+	NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
 
 	if (pAd->CommonCfg.pMeasureReqTab)
 		kfree(pAd->CommonCfg.pMeasureReqTab);
@@ -66,7 +299,7 @@ VOID MeasureReqTabExit(
 	return;
 }
 
-static PMEASURE_REQ_ENTRY MeasureReqLookUp(
+PMEASURE_REQ_ENTRY MeasureReqLookUp(
 	IN PRTMP_ADAPTER	pAd,
 	IN UINT8			DialogToken)
 {
@@ -102,7 +335,7 @@ static PMEASURE_REQ_ENTRY MeasureReqLookUp(
 	return pEntry;
 }
 
-static PMEASURE_REQ_ENTRY MeasureReqInsert(
+PMEASURE_REQ_ENTRY MeasureReqInsert(
 	IN PRTMP_ADAPTER	pAd,
 	IN UINT8			DialogToken)
 {
@@ -201,7 +434,7 @@ static PMEASURE_REQ_ENTRY MeasureReqInsert(
 	return pEntry;
 }
 
-static VOID MeasureReqDelete(
+VOID MeasureReqDelete(
 	IN PRTMP_ADAPTER	pAd,
 	IN UINT8			DialogToken)
 {
@@ -275,7 +508,7 @@ VOID TpcReqTabInit(
 VOID TpcReqTabExit(
 	IN PRTMP_ADAPTER pAd)
 {
-	NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock);
+	NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock);
 
 	if (pAd->CommonCfg.pTpcReqTab)
 		kfree(pAd->CommonCfg.pTpcReqTab);
@@ -511,6 +744,72 @@ static UINT8 GetCurTxPwr(
 	return 16; /* 16 dBm */
 }
 
+/*
+	==========================================================================
+	Description:
+		Get Current Transmit Power.
+
+	Parametrs:
+
+	Return	: Current Time Stamp.
+	==========================================================================
+ */
+VOID InsertChannelRepIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN PSTRING pCountry,
+	IN UINT8 RegulatoryClass)
+{
+	ULONG TempLen;
+	UINT8 Len;
+	UINT8 IEId = IE_AP_CHANNEL_REPORT;
+	PUCHAR pChListPtr = NULL;
+
+	Len = 1;
+	if (strncmp(pCountry, "US", 2) == 0)
+	{
+		if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE)
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: USA Unknow Requlatory class (%d)\n",
+						__func__, RegulatoryClass));
+			return;
+		}
+
+		Len += USARegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels;
+		pChListPtr = USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
+	}
+	else if (strncmp(pCountry, "JP", 2) == 0)
+	{
+		if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE)
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: JP Unknow Requlatory class (%d)\n",
+						__func__, RegulatoryClass));
+			return;
+		}
+
+		Len += JapanRegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels;
+		pChListPtr = JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
+					__func__, pCountry));
+		return;
+	}
+
+	MakeOutgoingFrame(pFrameBuf,	&TempLen,
+					1,				&IEId,
+					1,				&Len,
+					1,				&RegulatoryClass,
+					Len -1,			pChListPtr,
+					END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+	return;
+}
+
 /*
 	==========================================================================
 	Description:
@@ -524,7 +823,7 @@ static UINT8 GetCurTxPwr(
 	Return	: None.
 	==========================================================================
  */
-static VOID InsertDialogToken(
+VOID InsertDialogToken(
 	IN PRTMP_ADAPTER pAd,
 	OUT PUCHAR pFrameBuf,
 	OUT PULONG pFrameLen,
@@ -585,7 +884,7 @@ static VOID InsertDialogToken(
 	Return	: None.
 	==========================================================================
  */
- static VOID InsertTpcReportIE(
+VOID InsertTpcReportIE(
 	IN PRTMP_ADAPTER pAd,
 	OUT PUCHAR pFrameBuf,
 	OUT PULONG pFrameLen,
@@ -679,16 +978,16 @@ static VOID InsertMeasureReqIE(
 	IN PRTMP_ADAPTER pAd,
 	OUT PUCHAR pFrameBuf,
 	OUT PULONG pFrameLen,
+	IN UINT8 Len,
 	IN PMEASURE_REQ_INFO pMeasureReqIE)
 {
 	ULONG TempLen;
-	UINT8 Len = sizeof(MEASURE_REQ_INFO);
 	UINT8 ElementID = IE_MEASUREMENT_REQUEST;
 
 	MakeOutgoingFrame(pFrameBuf,					&TempLen,
 						1,							&ElementID,
 						1,							&Len,
-						Len,						pMeasureReqIE,
+						sizeof(MEASURE_REQ_INFO),	pMeasureReqIE,
 						END_OF_ARGS);
 
 	*pFrameLen = *pFrameLen + TempLen;
@@ -758,53 +1057,43 @@ static VOID InsertMeasureReportIE(
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueMeasurementReq(
+VOID MakeMeasurementReqFrame(
 	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
+	OUT PUCHAR pOutBuffer,
+	OUT PULONG pFrameLen,
+	IN UINT8 TotalLen,
+	IN UINT8 Category,
+	IN UINT8 Action,
 	IN UINT8 MeasureToken,
 	IN UINT8 MeasureReqMode,
 	IN UINT8 MeasureReqType,
-	IN UINT8 MeasureCh,
-	IN UINT16 MeasureDuration)
+	IN UINT8 NumOfRepetitions)
 {
-	PUCHAR pOutBuffer = NULL;
-	NDIS_STATUS NStatus;
-	ULONG FrameLen;
-	HEADER_802_11 ActHdr;
+	ULONG TempLen;
 	MEASURE_REQ_INFO MeasureReqIE;
-	UINT8 RmReqDailogToken = RandomByte(pAd);
-	UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
 
-	// build action frame header.
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-						pAd->CurrentAddress);
+	InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category, Action);
 
-	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-	if(NStatus != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
-		return;
-	}
-	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
-	FrameLen = sizeof(HEADER_802_11);
+	// fill Dialog Token
+	InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen, MeasureToken);
 
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ);
+	/* fill Number of repetitions. */
+	if (Category == CATEGORY_RM)
+	{
+		MakeOutgoingFrame((pOutBuffer+*pFrameLen),	&TempLen,
+						2,							&NumOfRepetitions,
+						END_OF_ARGS);
 
-	// fill Dialog Token
-	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken);
+		*pFrameLen += TempLen;
+	}
 
 	// prepare Measurement IE.
 	NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
-	MeasureReqIE.Token = RmReqDailogToken;
+	MeasureReqIE.Token = MeasureToken;
 	MeasureReqIE.ReqMode.word = MeasureReqMode;
 	MeasureReqIE.ReqType = MeasureReqType;
-	MeasureReqIE.MeasureReq.ChNum = MeasureCh;
-	MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
-	MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
-	InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
+	InsertMeasureReqIE(pAd, (pOutBuffer+*pFrameLen), pFrameLen,
+		TotalLen, &MeasureReqIE);
 
 	return;
 }
@@ -858,7 +1147,7 @@ VOID EnqueueMeasurementRep(
 	// prepare Measurement IE.
 	NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
 	MeasureRepIE.Token = MeasureToken;
-	MeasureRepIE.ReportMode.word = MeasureReqMode;
+	MeasureRepIE.ReportMode = MeasureReqMode;
 	MeasureRepIE.ReportType = MeasureReqType;
 	InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
 
@@ -1159,7 +1448,8 @@ static BOOLEAN PeerMeasureReqSanity(
 	IN VOID *pMsg,
 	IN ULONG MsgLen,
 	OUT PUINT8 pDialogToken,
-	OUT PMEASURE_REQ_INFO pMeasureReqInfo)
+	OUT PMEASURE_REQ_INFO pMeasureReqInfo,
+	OUT PMEASURE_REQ pMeasureReq)
 {
 	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
 	PUCHAR pFramePtr = Fr->Octet;
@@ -1192,12 +1482,12 @@ static BOOLEAN PeerMeasureReqSanity(
 				NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
 				NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
 				NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
-				ptr = eid_ptr->Octet + 3;
-				NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1);
+				ptr = (PUCHAR)(eid_ptr->Octet + 3);
+				NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1);
 				NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
-				pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime);
+				pMeasureReq->MeasureStartTime = SWAP64(MeasureStartTime);
 				NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
-				pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration);
+				pMeasureReq->MeasureDuration = SWAP16(MeasureDuration);
 
 				result = TRUE;
 				break;
@@ -1285,7 +1575,7 @@ static BOOLEAN PeerMeasureReportSanity(
 				if (pMeasureReportInfo->ReportType == RM_BASIC)
 				{
 					PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
-					ptr = eid_ptr->Octet + 3;
+					ptr = (PUCHAR)(eid_ptr->Octet + 3);
 					NdisMoveMemory(&pReport->ChNum, ptr, 1);
 					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
 					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
@@ -1295,7 +1585,7 @@ static BOOLEAN PeerMeasureReportSanity(
 				else if (pMeasureReportInfo->ReportType == RM_CCA)
 				{
 					PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
-					ptr = eid_ptr->Octet + 3;
+					ptr = (PUCHAR)(eid_ptr->Octet + 3);
 					NdisMoveMemory(&pReport->ChNum, ptr, 1);
 					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
 					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
@@ -1305,7 +1595,7 @@ static BOOLEAN PeerMeasureReportSanity(
 				else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
 				{
 					PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
-					ptr = eid_ptr->Octet + 3;
+					ptr = (PUCHAR)(eid_ptr->Octet + 3);
 					NdisMoveMemory(&pReport->ChNum, ptr, 1);
 					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
 					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
@@ -1533,9 +1823,10 @@ static VOID PeerMeasureReqAction(
 	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
 	UINT8 DialogToken;
 	MEASURE_REQ_INFO MeasureReqInfo;
+	MEASURE_REQ	MeasureReq;
 	MEASURE_REPORT_MODE ReportMode;
 
-	if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo))
+	if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo, &MeasureReq))
 	{
 		ReportMode.word = 0;
 		ReportMode.field.Incapable = 1;
@@ -1729,8 +2020,8 @@ VOID PeerSpectrumAction(
 			break;
 
 		case SPEC_CHANNEL_SWITCH:
-{
-}
+
+
 			PeerChSwAnnAction(pAd, Elem);
 			break;
 	}
@@ -1749,16 +2040,31 @@ VOID PeerSpectrumAction(
  */
 INT Set_MeasureReq_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	UINT Aid = 1;
 	UINT ArgIdx;
-	PUCHAR thisChar;
+	PSTRING thisChar;
 
 	MEASURE_REQ_MODE MeasureReqMode;
 	UINT8 MeasureReqToken = RandomByte(pAd);
 	UINT8 MeasureReqType = RM_BASIC;
 	UINT8 MeasureCh = 1;
+	UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
+	MEASURE_REQ MeasureReq;
+	UINT8 TotalLen;
+
+	HEADER_802_11 ActHdr;
+	PUCHAR pOutBuffer = NULL;
+	NDIS_STATUS NStatus;
+	ULONG FrameLen;
+
+	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+	if(NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
+		goto END_OF_MEASURE_REQ;
+	}
 
 	ArgIdx = 1;
 	while ((thisChar = strsep((char **)&arg, "-")) != NULL)
@@ -1766,7 +2072,7 @@ INT Set_MeasureReq_Proc(
 		switch(ArgIdx)
 		{
 			case 1:	// Aid.
-				Aid = simple_strtol(thisChar, 0, 16);
+				Aid = (UINT8) simple_strtol(thisChar, 0, 16);
 				break;
 
 			case 2: // Measurement Request Type.
@@ -1774,12 +2080,12 @@ INT Set_MeasureReq_Proc(
 				if (MeasureReqType > 3)
 				{
 					DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __func__, MeasureReqType));
-					return TRUE;
+					goto END_OF_MEASURE_REQ;
 				}
 				break;
 
 			case 3: // Measurement channel.
-				MeasureCh = simple_strtol(thisChar, 0, 16);
+				MeasureCh = (UINT8) simple_strtol(thisChar, 0, 16);
 				break;
 		}
 		ArgIdx++;
@@ -1789,7 +2095,7 @@ INT Set_MeasureReq_Proc(
 	if (!VALID_WCID(Aid))
 	{
 		DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
-		return TRUE;
+		goto END_OF_MEASURE_REQ;
 	}
 
 	MeasureReqMode.word = 0;
@@ -1797,21 +2103,49 @@ INT Set_MeasureReq_Proc(
 
 	MeasureReqInsert(pAd, MeasureReqToken);
 
-	EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr,
-		MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000);
+	// build action frame header.
+	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pAd->MacTab.Content[Aid].Addr,
+						pAd->CurrentAddress);
+
+	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+	FrameLen = sizeof(HEADER_802_11);
+
+	TotalLen = sizeof(MEASURE_REQ_INFO) + sizeof(MEASURE_REQ);
+
+	MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen,
+		sizeof(MEASURE_REQ_INFO), CATEGORY_RM, RM_BASIC,
+		MeasureReqToken, MeasureReqMode.word,
+		MeasureReqType, 0);
+
+	MeasureReq.ChNum = MeasureCh;
+	MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
+	MeasureReq.MeasureDuration = cpu2le16(2000);
+
+	{
+		ULONG TempLen;
+		MakeOutgoingFrame(	pOutBuffer+FrameLen,	&TempLen,
+							sizeof(MEASURE_REQ),	&MeasureReq,
+							END_OF_ARGS);
+		FrameLen += TempLen;
+	}
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (UINT)FrameLen);
+
+END_OF_MEASURE_REQ:
+	MlmeFreeMemory(pAd, pOutBuffer);
 
 	return TRUE;
 }
 
 INT Set_TpcReq_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg)
+	IN	PSTRING			arg)
 {
 	UINT Aid;
 
 	UINT8 TpcReqToken = RandomByte(pAd);
 
-	Aid = simple_strtol(arg, 0, 16);
+	Aid = (UINT) simple_strtol(arg, 0, 16);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid));
 	if (!VALID_WCID(Aid))

+ 0 - 241
drivers/staging/rt2860/config.mk

@@ -1,241 +0,0 @@
-# Support ATE function
-HAS_ATE=n
-
-# Support 28xx QA ATE function
-HAS_28xx_QA=n
-
-# Support Wpa_Supplicant
-HAS_WPA_SUPPLICANT=n
-
-# Support Native WpaSupplicant for Network Maganger
-HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n
-
-#Support Net interface block while Tx-Sw queue full
-HAS_BLOCK_NET_IF=n
-
-#Support DFS function
-HAS_DFS_SUPPORT=n
-
-#Support Carrier-Sense function
-HAS_CS_SUPPORT=n
-
-#ifdef MULTI_CARD
-# Support for Multiple Cards
-HAS_MC_SUPPORT=n
-#endif // MULTI_CARD //
-
-#Support for IEEE802.11e DLS
-HAS_QOS_DLS_SUPPORT=n
-
-#Support for EXT_CHANNEL
-HAS_EXT_BUILD_CHANNEL_LIST=n
-
-#Support for Net-SNMP
-HAS_SNMP_SUPPORT=n
-
-#Support features of Single SKU.
-HAS_SINGLE_SKU_SUPPORT=n
-
-#Support features of 802.11n
-HAS_DOT11_N_SUPPORT=y
-
-
-#################################################
-
-CC := $(CROSS_COMPILE)gcc
-LD := $(CROSS_COMPILE)ld
-
-WFLAGS := -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT  -DLINUX -Wall -Wstrict-prototypes -Wno-trigraphs
-
-
-#################################################
-
-#ifdef CONFIG_STA_SUPPORT
-# config for STA mode
-
-ifeq ($(RT28xx_MODE),STA)
-WFLAGS += -DCONFIG_STA_SUPPORT -DDBG
-
-ifeq ($(HAS_WPA_SUPPLICANT),y)
-WFLAGS += -DWPA_SUPPLICANT_SUPPORT
-endif
-
-ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y)
-WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
-endif
-
-ifeq ($(HAS_ATE),y)
-WFLAGS += -DRALINK_ATE
-ifeq ($(HAS_28xx_QA),y)
-WFLAGS += -DRALINK_28xx_QA
-endif
-endif
-
-ifeq ($(HAS_SNMP_SUPPORT),y)
-WFLAGS += -DSNMP_SUPPORT
-endif
-
-ifeq ($(HAS_QOS_DLS_SUPPORT),y)
-WFLAGS += -DQOS_DLS_SUPPORT
-endif
-
-ifeq ($(HAS_DOT11_N_SUPPORT),y)
-WFLAGS += -DDOT11_N_SUPPORT
-endif
-
-ifeq ($(HAS_CS_SUPPORT),y)
-WFLAGS += -DCARRIER_DETECTION_SUPPORT
-endif
-
-ifeq ($(HAS_SINGLE_SKU_SUPPORT),y)
-WFLAGS += -DSINGLE_SKU
-endif
-
-endif
-# endif of ifeq ($(RT28xx_MODE),STA)
-#endif // CONFIG_STA_SUPPORT //
-
-#################################################
-
-#################################################
-
-#
-# Common compiler flag
-#
-
-
-ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y)
-WFLAGS += -DEXT_BUILD_CHANNEL_LIST
-endif
-
-ifeq ($(CHIPSET),2870)
-WFLAGS +=-DRT2870
-endif
-
-ifeq ($(PLATFORM),5VT)
-#WFLAGS += -DCONFIG_5VT_ENHANCE
-endif
-
-ifeq ($(HAS_BLOCK_NET_IF),y)
-WFLAGS += -DBLOCK_NET_IF
-endif
-
-ifeq ($(HAS_DFS_SUPPORT),y)
-WFLAGS += -DDFS_SUPPORT
-endif
-
-#ifdef MULTI_CARD
-ifeq ($(HAS_MC_SUPPORT),y)
-WFLAGS += -DMULTIPLE_CARD_SUPPORT
-endif
-#endif // MULTI_CARD //
-
-ifeq ($(HAS_LLTD),y)
-WFLAGS += -DLLTD_SUPPORT
-endif
-
-ifeq ($(PLATFORM),IXP)
-WFLAGS += -DRT_BIG_ENDIAN
-endif
-
-ifeq ($(PLATFORM),IKANOS_V160)
-WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0
-endif
-
-ifeq ($(PLATFORM),IKANOS_V180)
-WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0
-endif
-
-ifeq ($(PLATFORM),INF_TWINPASS)
-WFLAGS += -DRT_BIG_ENDIAN -DINF_TWINPASS
-endif
-
-ifeq ($(PLATFORM),INF_DANUBE)
-WFLAGS += -DINF_DANUBE -DRT_BIG_ENDIAN
-endif
-
-ifeq ($(PLATFORM),CAVM_OCTEON)
-WFLAGS += -DRT_BIG_ENDIAN
-endif
-
-ifeq ($(PLATFORM),BRCM_6358)
-WFLAGS += -DRT_BIG_ENDIAN
-endif
-
-ifeq ($(PLATFORM),INF_AMAZON_SE)
-#WFLAGS += -DRT_BIG_ENDIAN -DINF_AMAZON_SE -DBG_FT_SUPPORT
-WFLAGS += -DRT_BIG_ENDIAN -DINF_AMAZON_SE
-endif
-
-#kernel build options for 2.4
-# move to Makefile outside LINUX_SRC := /opt/star/kernel/linux-2.4.27-star
-
-ifeq ($(PLATFORM),STAR)
-CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -Uarm -fno-common -pipe -mapcs-32 -D__LINUX_ARM_ARCH__=4 -march=armv4  -mshort-load-bytes -msoft-float -Uarm -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS)
-
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),SIGMA)
-CFLAGS := -D__KERNEL__ -I$(RT28xx_DIR)/include -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -DEM86XX_CHIP=EM86XX_CHIPID_TANGO2 -DEM86XX_REVISION=6 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT2860_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2     -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe  -mabi=32 -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -DMODULE $(WFLAGS)
-
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),SIGMA_8622)
-CFLAGS := -D__KERNEL__ -I$(CROSS_COMPILE_INCLUDE)/include -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-common -pipe -fno-builtin -D__linux__ -DNO_MM -mapcs-32 -march=armv4 -mtune=arm7tdmi -msoft-float -DMODULE -mshort-load-bytes -nostdinc -iwithprefix -DMODULE $(WFLAGS)
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),5VT)
-CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=apcs-gnu -mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=arm926ej-s --param max-inline-insns-single=40000  -Uarm -Wdeclaration-after-statement -Wno-pointer-sign -DMODULE $(WFLAGS)
-
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),IKANOS_V160)
-CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -march=lx4189 -Wa, -DMODULE $(WFLAGS)
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),IKANOS_V180)
-CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -mips32r2 -Wa, -DMODULE $(WFLAGS)
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),INF_TWINPASS)
-CFLAGS := -D__KERNEL__ -DMODULE -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -G 0 -mno-abicalls -fno-pic -march=4kc -mips32 -Wa,--trap -pipe -mlong-calls $(WFLAGS)
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),INF_DANUBE)
-CFLAGS := -I$(RT28xx_DIR)/include $(WFLAGS) -Wundef -fno-strict-aliasing -fno-common -ffreestanding -Os -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -msoft-float  -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-generic
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),BRCM_6358)
-CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include -nostdinc -iwithprefix include -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -I $(LINUX_SRC)/include/asm/gcc -G 0 -mno-abicalls -fno-pic -pipe  -finline-limit=100000 -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-bcm963xx -I$(LINUX_SRC)/include/asm-mips/mach-generic  -Os -fomit-frame-pointer -Wdeclaration-after-statement  -DMODULE -mlong-calls
-export CFLAGS
-endif
-
-ifeq ($(PLATFORM),PC)
-    ifneq (,$(findstring 2.4,$(LINUX_SRC)))
-	# Linux 2.4
-	CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS)
-	export CFLAGS
-    else
-	# Linux 2.6
-	EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include
-    endif
-endif
-
-ifeq ($(PLATFORM),IXP)
-        EXTRA_CFLAGS := -v $(WFLAGS) -I$(RT28xx_DIR)/include -mbig-endian
-endif
-
-ifeq ($(PLATFORM),CAVM_OCTEON)
-	EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include \
-				    -mabi=64 $(WFLAGS)
-export CFLAGS
-endif
-

+ 82 - 0
drivers/staging/rt2860/crypt_hmac.h

@@ -0,0 +1,82 @@
+/*
+ *************************************************************************
+ * 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:
+    HMAC
+
+    Abstract:
+    FIPS 198: The Keyed-Hash Message Authentication Code (HMAC)
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ------------------------------------------
+    Eddy        2008/11/24      Create HMAC-SHA1, HMAC-SHA256
+***************************************************************************/
+#ifndef __CRYPT_HMAC_H__
+#define __CRYPT_HMAC_H__
+
+#ifdef CRYPT_TESTPLAN
+#include "crypt_testplan.h"
+#else
+#include "rt_config.h"
+#endif /* CRYPT_TESTPLAN */
+
+#ifdef SHA1_SUPPORT
+#define HMAC_SHA1_SUPPORT
+VOID HMAC_SHA1 (
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen);
+#endif /* SHA1_SUPPORT */
+
+#ifdef SHA256_SUPPORT
+#define HMAC_SHA256_SUPPORT
+VOID HMAC_SHA256 (
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen);
+#endif /* SHA256_SUPPORT */
+
+#ifdef MD5_SUPPORT
+#define HMAC_MD5_SUPPORT
+VOID HMAC_MD5 (
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen);
+#endif /* MD5_SUPPORT */
+
+#endif /* __CRYPT_HMAC_H__ */

+ 80 - 0
drivers/staging/rt2860/crypt_md5.h

@@ -0,0 +1,80 @@
+/*
+ *************************************************************************
+ * 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:
+    MD5
+
+    Abstract:
+    RFC1321: The MD5 Message-Digest Algorithm
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ------------------------------------------
+    Eddy        2008/11/24      Create md5
+***************************************************************************/
+
+#ifndef __CRYPT_MD5_H__
+#define __CRYPT_MD5_H__
+
+#ifdef CRYPT_TESTPLAN
+#include "crypt_testplan.h"
+#else
+#include "rt_config.h"
+#endif /* CRYPT_TESTPLAN */
+
+/* Algorithm options */
+#define MD5_SUPPORT
+
+#ifdef MD5_SUPPORT
+#define MD5_BLOCK_SIZE    64 /* 512 bits = 64 bytes */
+#define MD5_DIGEST_SIZE   16 /* 128 bits = 16 bytes */
+typedef struct {
+    UINT32 HashValue[4];
+    UINT64 MessageLen;
+    UINT8  Block[MD5_BLOCK_SIZE];
+    UINT   BlockLen;
+} MD5_CTX_STRUC, *PMD5_CTX_STRUC;
+
+VOID MD5_Init (
+    IN  MD5_CTX_STRUC *pMD5_CTX);
+VOID MD5_Hash (
+    IN  MD5_CTX_STRUC *pMD5_CTX);
+VOID MD5_Append (
+    IN  MD5_CTX_STRUC *pMD5_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen);
+VOID MD5_End (
+    IN  MD5_CTX_STRUC *pMD5_CTX,
+    OUT UINT8 DigestMessage[]);
+VOID RT_MD5 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[]);
+#endif /* MD5_SUPPORT */
+
+#endif /* __CRYPT_MD5_H__ */

+ 109 - 0
drivers/staging/rt2860/crypt_sha2.h

@@ -0,0 +1,109 @@
+/*
+ *************************************************************************
+ * 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:
+    SHA2
+
+    Abstract:
+    FIPS 180-2: Secure Hash Standard (SHS)
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ------------------------------------------
+    Eddy        2008/11/24      Create SHA1
+    Eddy        2008/07/23      Create SHA256
+***************************************************************************/
+
+#ifndef __CRYPT_SHA2_H__
+#define __CRYPT_SHA2_H__
+
+#ifdef CRYPT_TESTPLAN
+#include "crypt_testplan.h"
+#else
+#include "rt_config.h"
+#endif /* CRYPT_TESTPLAN */
+
+/* Algorithm options */
+#define SHA1_SUPPORT
+#define SHA256_SUPPORT
+
+#ifdef SHA1_SUPPORT
+#define SHA1_BLOCK_SIZE    64 /* 512 bits = 64 bytes */
+#define SHA1_DIGEST_SIZE   20 /* 160 bits = 20 bytes */
+typedef struct _SHA1_CTX_STRUC {
+    UINT32 HashValue[5];  /* 5 = (SHA1_DIGEST_SIZE / 32) */
+    UINT64 MessageLen;    /* total size */
+    UINT8  Block[SHA1_BLOCK_SIZE];
+    UINT   BlockLen;
+} SHA1_CTX_STRUC, *PSHA1_CTX_STRUC;
+
+VOID RT_SHA1_Init (
+    IN  SHA1_CTX_STRUC *pSHA_CTX);
+VOID SHA1_Hash (
+    IN  SHA1_CTX_STRUC *pSHA_CTX);
+VOID SHA1_Append (
+    IN  SHA1_CTX_STRUC *pSHA_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen);
+VOID SHA1_End (
+    IN  SHA1_CTX_STRUC *pSHA_CTX,
+    OUT UINT8 DigestMessage[]);
+VOID RT_SHA1 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[]);
+#endif /* SHA1_SUPPORT */
+
+#ifdef SHA256_SUPPORT
+#define SHA256_BLOCK_SIZE   64 /* 512 bits = 64 bytes */
+#define SHA256_DIGEST_SIZE  32 /* 256 bits = 32 bytes */
+typedef struct _SHA256_CTX_STRUC {
+    UINT32 HashValue[8];  /* 8 = (SHA256_DIGEST_SIZE / 32) */
+    UINT64 MessageLen;    /* total size */
+    UINT8  Block[SHA256_BLOCK_SIZE];
+    UINT   BlockLen;
+} SHA256_CTX_STRUC, *PSHA256_CTX_STRUC;
+
+VOID SHA256_Init (
+    IN  SHA256_CTX_STRUC *pSHA_CTX);
+VOID SHA256_Hash (
+    IN  SHA256_CTX_STRUC *pSHA_CTX);
+VOID SHA256_Append (
+    IN  SHA256_CTX_STRUC *pSHA_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen);
+VOID SHA256_End (
+    IN  SHA256_CTX_STRUC *pSHA_CTX,
+    OUT UINT8 DigestMessage[]);
+VOID RT_SHA256 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[]);
+#endif /* SHA256_SUPPORT */
+
+#endif /* __CRYPT_SHA2_H__ */

+ 30 - 2
drivers/staging/rt2860/dfs.h

@@ -43,6 +43,33 @@
 #define WIDTH_RD_CHECK 1
 
 
+
+/*************************************************************************
+  *
+  *	DFS Radar related definitions.
+  *
+  ************************************************************************/
+//#define CARRIER_DETECT_TASK_NUM	6
+//#define RADAR_DETECT_TASK_NUM	7
+
+// McuRadarState && McuCarrierState for 2880-SW-MCU
+#define FREE_FOR_TX				0
+#define WAIT_CTS_BEING_SENT		1
+#define DO_DETECTION			2
+
+// McuRadarEvent
+#define RADAR_EVENT_CTS_SENT			0x01 // Host signal MCU that CTS has been sent
+#define RADAR_EVENT_CTS_CARRIER_SENT	0x02 // Host signal MCU that CTS has been sent (Carrier)
+#define RADAR_EVENT_RADAR_DETECTING		0x04 // Radar detection is on going, carrier detection hold back
+#define RADAR_EVENT_CARRIER_DETECTING	0x08 // Carrier detection is on going, radar detection hold back
+#define RADAR_EVENT_WIDTH_RADAR			0x10 // BBP == 2 radar detected
+#define RADAR_EVENT_CTS_KICKED			0x20 // Radar detection need to sent double CTS, first CTS sent
+
+// McuRadarCmd
+#define DETECTION_STOP			0
+#define RADAR_DETECTION			1
+#define CARRIER_DETECTION		2
+
 VOID BbpRadarDetectionStart(
 	IN PRTMP_ADAPTER pAd);
 
@@ -77,12 +104,13 @@ ULONG RTMPReadRadarDuration(
 VOID RTMPCleanRadarDuration(
 	IN PRTMP_ADAPTER	pAd);
 
+
 INT Set_ChMovingTime_Proc(
 	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg);
+	IN PSTRING arg);
 
 INT Set_LongPulseRadarTh_Proc(
 	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR arg);
+	IN PSTRING arg);
 
 

+ 93 - 0
drivers/staging/rt2860/eeprom.h

@@ -0,0 +1,93 @@
+/*
+ *************************************************************************
+ * 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:
+	eeprom.h
+
+	Abstract:
+	Miniport header file for eeprom related information
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+
+
+#ifdef RTMP_PCI_SUPPORT
+/*************************************************************************
+  *	Public function declarations for prom-based chipset
+  ************************************************************************/
+int rtmp_ee_prom_read16(
+	IN PRTMP_ADAPTER	pAd,
+	IN USHORT			Offset,
+	OUT USHORT			*pValue);
+
+int rtmp_ee_prom_write16(
+	IN PRTMP_ADAPTER	pAd,
+	IN USHORT			Offset,
+	IN USHORT			value);
+#endif // RTMP_PCI_SUPPORT //
+#ifdef RTMP_USB_SUPPORT
+/*************************************************************************
+  *	Public function declarations for usb-based prom chipset
+  ************************************************************************/
+NTSTATUS RTUSBReadEEPROM16(
+	IN PRTMP_ADAPTER	pAd,
+	IN	USHORT			offset,
+	OUT	PUSHORT			pData);
+
+NTSTATUS RTUSBWriteEEPROM16(
+	IN RTMP_ADAPTER *pAd,
+	IN USHORT offset,
+	IN USHORT value);
+#endif // RTMP_USB_SUPPORT //
+
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+int rtmp_ee_efuse_read16(
+	IN RTMP_ADAPTER *pAd,
+	IN USHORT Offset,
+	OUT USHORT *pValue);
+
+int rtmp_ee_efuse_write16(
+	IN RTMP_ADAPTER *pAd,
+	IN USHORT Offset,
+	IN USHORT data);
+#endif // RTMP_EFUSE_SUPPORT //
+#endif // RT30xx //
+
+/*************************************************************************
+  *	Public function declarations for prom operation callback functions setting
+  ************************************************************************/
+INT RtmpChipOpsEepromHook(
+	IN RTMP_ADAPTER *pAd,
+	IN INT			infType);
+
+#endif // __EEPROM_H__ //

+ 83 - 0
drivers/staging/rt2860/iface/rtmp_pci.h

@@ -0,0 +1,83 @@
+/*
+ *************************************************************************
+ * 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 __RTMP_PCI_H__
+#define __RTMP_PCI_H__
+
+#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p)				\
+	((POS_COOKIE)handle)->pci_dev = dev_p;
+
+
+#ifdef LINUX
+// set driver data
+#define RT28XX_DRVDATA_SET(_a)			pci_set_drvdata(_a, net_dev);
+
+#define RT28XX_PUT_DEVICE(dev_p)
+
+#ifndef SA_SHIRQ
+#define SA_SHIRQ IRQF_SHARED
+#endif
+
+#ifdef PCI_MSI_SUPPORT
+#define RTMP_MSI_ENABLE(_pAd) \
+	{     POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
+		(_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; \
+	}
+
+#define RTMP_MSI_DISABLE(_pAd) \
+	{     POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
+		if (_pAd->HaveMsi == TRUE) \
+			pci_disable_msi(_pObj->pci_dev); \
+		_pAd->HaveMsi = FALSE;  \
+	}
+#else
+#define RTMP_MSI_ENABLE(_pAd)		do{}while(0)
+#define RTMP_MSI_DISABLE(_pAd)		do{}while(0)
+#endif // PCI_MSI_SUPPORT //
+
+#define RTMP_PCI_DEV_UNMAP()										\
+{	if (net_dev->base_addr)	{								\
+		iounmap((void *)(net_dev->base_addr));				\
+		release_mem_region(pci_resource_start(dev_p, 0),	\
+							pci_resource_len(dev_p, 0)); }	\
+	if (net_dev->irq) pci_release_regions(dev_p); }
+
+
+#define PCI_REG_READ_WORD(pci_dev, offset, Configuration)   \
+    if (pci_read_config_word(pci_dev, offset, &reg16) == 0)     \
+        Configuration = le2cpu16(reg16);                        \
+    else                                                        \
+        Configuration = 0;
+
+#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration)  \
+    reg16 = cpu2le16(Configuration);                        \
+    pci_write_config_word(pci_dev, offset, reg16);
+
+#endif // LINUX //
+
+
+#endif // __RTMP_PCI_H__ //

+ 200 - 0
drivers/staging/rt2860/iface/rtmp_usb.h

@@ -0,0 +1,200 @@
+/*
+ *************************************************************************
+ * 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 __RTMP_USB_H__
+#define __RTMP_USB_H__
+
+
+#include "../rtusb_io.h"
+
+
+#ifdef LINUX
+#include <linux/usb.h>
+
+typedef struct usb_device	* PUSB_DEV;
+typedef struct urb *purbb_t;
+typedef struct usb_ctrlrequest devctrlrequest;
+#endif // LINUX //
+
+extern UCHAR EpToQueue[6];
+
+
+#define RXBULKAGGRE_ZISE			12
+#define MAX_TXBULK_LIMIT			(LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
+#define MAX_TXBULK_SIZE			(LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
+#define MAX_RXBULK_SIZE			(LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
+#define MAX_MLME_HANDLER_MEMORY 20
+
+
+// Flags for Bulkflags control for bulk out data
+//
+#define	fRTUSB_BULK_OUT_DATA_NULL				0x00000001
+#define	fRTUSB_BULK_OUT_RTS						0x00000002
+#define	fRTUSB_BULK_OUT_MLME						0x00000004
+
+#define	fRTUSB_BULK_OUT_PSPOLL					0x00000010
+#define	fRTUSB_BULK_OUT_DATA_FRAG				0x00000020
+#define	fRTUSB_BULK_OUT_DATA_FRAG_2				0x00000040
+#define	fRTUSB_BULK_OUT_DATA_FRAG_3				0x00000080
+#define	fRTUSB_BULK_OUT_DATA_FRAG_4				0x00000100
+
+#define	fRTUSB_BULK_OUT_DATA_NORMAL				0x00010000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_2			0x00020000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_3			0x00040000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_4			0x00080000
+
+// TODO:move to ./ate/include/iface/ate_usb.h
+
+
+#define FREE_HTTX_RING(_pCookie, _pipeId, _txContext)			\
+{										\
+	if ((_txContext)->ENextBulkOutPosition == (_txContext)->CurWritePosition)	\
+	{																	\
+		(_txContext)->bRingEmpty = TRUE;			\
+	}																	\
+	/*NdisInterlockedDecrement(&(_p)->TxCount); */\
+}
+
+
+
+/******************************************************************************
+
+	USB Bulk operation related definitions
+
+******************************************************************************/
+
+#ifdef LINUX
+#define BULKAGGRE_ZISE          100
+#define RT28XX_PUT_DEVICE							usb_put_dev
+#define RTUSB_ALLOC_URB(iso)							usb_alloc_urb(iso, GFP_ATOMIC)
+#define RTUSB_SUBMIT_URB(pUrb)							usb_submit_urb(pUrb, GFP_ATOMIC)
+#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr)			usb_buffer_alloc(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr)
+#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)	usb_buffer_free(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)
+
+#define RTUSB_FREE_URB(pUrb)	usb_free_urb(pUrb)
+
+// unlink urb
+#define RTUSB_UNLINK_URB(pUrb)		usb_kill_urb(pUrb)
+
+extern void dump_urb(struct urb* purb);
+
+#define InterlockedIncrement		atomic_inc
+#define NdisInterlockedIncrement	atomic_inc
+#define InterlockedDecrement		atomic_dec
+#define NdisInterlockedDecrement	atomic_dec
+#define InterlockedExchange		atomic_set
+
+#endif // LINUX //
+
+
+
+#define NT_SUCCESS(status)			(((status) >=0) ? (TRUE):(FALSE))
+
+
+
+#define USBD_TRANSFER_DIRECTION_OUT		0
+#define USBD_TRANSFER_DIRECTION_IN		0
+#define USBD_SHORT_TRANSFER_OK			0
+#define PURB			purbb_t
+
+#define PIRP		PVOID
+#define NDIS_OID	UINT
+#ifndef USB_ST_NOERROR
+#define USB_ST_NOERROR     0
+#endif
+
+// vendor-specific control operations
+#define CONTROL_TIMEOUT_JIFFIES ( (100 * OS_HZ) / 1000)
+#define UNLINK_TIMEOUT_MS		3
+
+
+VOID RTUSBBulkOutDataPacketComplete(purbb_t purb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+
+
+#ifdef KTHREAD_SUPPORT
+#define RTUSBMlmeUp(pAd) \
+	do{								    \
+		RTMP_OS_TASK	*_pTask = &((pAd)->mlmeTask);\
+		if (_pTask->kthread_task) \
+        { \
+			_pTask->kthread_running = TRUE; \
+	        wake_up(&_pTask->kthread_q); \
+		} \
+	}while(0)
+#else
+#define RTUSBMlmeUp(pAd)	        \
+	do{								    \
+		RTMP_OS_TASK	*_pTask = &((pAd)->mlmeTask);\
+		CHECK_PID_LEGALITY(_pTask->taskPID)		    \
+		{ \
+			RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \
+		}\
+	}while(0)
+#endif
+
+#ifdef KTHREAD_SUPPORT
+#define RTUSBCMDUp(pAd) \
+	do{	\
+		RTMP_OS_TASK	*_pTask = &((pAd)->cmdQTask);	\
+		{ \
+			_pTask->kthread_running = TRUE; \
+	        wake_up(&_pTask->kthread_q); \
+		} \
+	}while(0)
+
+#else
+#define RTUSBCMDUp(pAd)	                \
+	do{									    \
+		RTMP_OS_TASK	*_pTask = &((pAd)->cmdQTask);	\
+		CHECK_PID_LEGALITY(_pTask->taskPID)	    \
+		{\
+			RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \
+		}\
+	}while(0)
+#endif
+
+#define DEVICE_VENDOR_REQUEST_OUT       0x40
+#define DEVICE_VENDOR_REQUEST_IN        0xc0
+//#define INTERFACE_VENDOR_REQUEST_OUT    0x41
+//#define INTERFACE_VENDOR_REQUEST_IN     0xc1
+
+#define BULKOUT_MGMT_RESET_FLAG		0x80
+
+#define RTUSB_SET_BULK_FLAG(_M, _F)	((_M)->BulkFlags |= (_F))
+#define RTUSB_CLEAR_BULK_FLAG(_M, _F)	((_M)->BulkFlags &= ~(_F))
+#define RTUSB_TEST_BULK_FLAG(_M, _F)	(((_M)->BulkFlags & (_F)) != 0)
+
+#define RTMP_IRQ_REQUEST(net_dev)		do{}while(0)
+#define RTMP_IRQ_RELEASE(net_dev)		do{}while(0)
+
+
+#endif // __RTMP_USB_H__ //

+ 0 - 107
drivers/staging/rt2860/md5.h

@@ -1,107 +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:
-	md5.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-	jan			10-28-03		Initial
-	Rita    	11-23-04		Modify MD5 and SHA-1
-*/
-
-#ifndef	uint8
-#define	uint8  unsigned	char
-#endif
-
-#ifndef	uint32
-#define	uint32 unsigned	long int
-#endif
-
-
-#ifndef	__MD5_H__
-#define	__MD5_H__
-
-#define MD5_MAC_LEN 16
-
-typedef struct _MD5_CTX {
-    UINT32   Buf[4];             // buffers of four states
-	UCHAR   Input[64];          // input message
-	UINT32   LenInBitCount[2];   // length counter for input message, 0 up to 64 bits
-}   MD5_CTX;
-
-VOID MD5Init(MD5_CTX *pCtx);
-VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
-VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx);
-VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16]);
-
-void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
-void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
-
-//
-// SHA context
-//
-typedef	struct _SHA_CTX
-{
-	UINT32   Buf[5];             // buffers of five states
-	UCHAR   Input[80];          // input message
-	UINT32   LenInBitCount[2];   // length counter for input message, 0 up to 64 bits
-
-}	SHA_CTX;
-
-VOID SHAInit(SHA_CTX *pCtx);
-UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
-VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]);
-VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20]);
-
-#define SHA_DIGEST_LEN 20
-#endif // __MD5_H__
-
-/******************************************************************************/
-#ifndef	_AES_H
-#define	_AES_H
-
-typedef	struct
-{
-	uint32 erk[64];		/* encryption round	keys */
-	uint32 drk[64];		/* decryption round	keys */
-	int	nr;				/* number of rounds	*/
-}
-aes_context;
-
-int	 rtmp_aes_set_key( aes_context *ctx,	uint8 *key,	int	nbits );
-void rtmp_aes_encrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] );
-void rtmp_aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] );
-
-void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output);
-int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output);
-
-#endif /* aes.h	*/
-

+ 13 - 76
drivers/staging/rt2860/mlme.h

@@ -39,6 +39,10 @@
 #ifndef __MLME_H__
 #define __MLME_H__
 
+#include "rtmp_dot11.h"
+
+
+
 // maximum supported capability information -
 // ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot
 #define SUPPORTED_CAPABILITY_INFO   0x0533
@@ -58,23 +62,24 @@
 #define JAP_W56	4
 #define MAX_RD_REGION 5
 
-#ifdef	NDIS51_MINIPORT
-#define BEACON_LOST_TIME            4000       // 2048 msec = 2 sec
-#else
 #define BEACON_LOST_TIME            4 * OS_HZ    // 2048 msec = 2 sec
-#endif
 
 #define DLS_TIMEOUT                 1200      // unit: msec
 #define AUTH_TIMEOUT                300       // unit: msec
 #define ASSOC_TIMEOUT               300       // unit: msec
-#define JOIN_TIMEOUT                2 * OS_HZ      // unit: msec
+#define JOIN_TIMEOUT                2000        // unit: msec
 #define SHORT_CHANNEL_TIME          90        // unit: msec
 #define MIN_CHANNEL_TIME            110        // unit: msec, for dual band scan
 #define MAX_CHANNEL_TIME            140       // unit: msec, for single band scan
 #define	FAST_ACTIVE_SCAN_TIME	    30 		  // Active scan waiting for probe response time
 #define CW_MIN_IN_BITS              4         // actual CwMin = 2^CW_MIN_IN_BITS - 1
+#define LINK_DOWN_TIMEOUT           20000      // unit: msec
+#define AUTO_WAKEUP_TIMEOUT			70			//unit: msec
+
+
 #define CW_MAX_IN_BITS              10        // actual CwMax = 2^CW_MAX_IN_BITS - 1
 
+
 // Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720).
 // SHould not refer to this constant anymore
 //#define RSSI_TO_DBM_OFFSET          120 // for RT2530 RSSI-115 = dBm
@@ -290,7 +295,7 @@ typedef struct PACKED _HT_CAPABILITY_IE{
 #define dot11BSSWidthTriggerScanInterval					300  // in sec. max interval between scan operations to be performed to detect BSS channel width trigger events.
 #define dot11OBSSScanPassiveTotalPerChannel					200	// in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan.
 #define dot11OBSSScanActiveTotalPerChannel					20	//in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan
-#define dot11BSSWidthChannelTransactionDelayFactor			5	// min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maxima
+#define dot11BSSWidthChannelTransactionDelayFactor			5	// min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maximum
 																//	interval between overlapping BSS scan operations.
 #define dot11BSSScanActivityThreshold						25	// in %%, max total time that a STA may be active on the medium during a period of
 																//	(dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without
@@ -382,7 +387,7 @@ typedef struct {
 	BOOLEAN			bHtEnable;	 // If we should use ht rate.
 	BOOLEAN			bPreNHt;	 // If we should use ht rate.
 	//Substract from HT Capability IE
-	UCHAR			MCSSet[16];	//only supoort MCS=0-15,32 ,
+	UCHAR			MCSSet[16];
 } RT_HT_PHY_INFO, *PRT_HT_PHY_INFO;
 
 //This structure substracts ralink supports from all 802.11n-related features.
@@ -460,60 +465,6 @@ typedef struct  PACKED{
 	UCHAR				NewExtChanOffset;
 } NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE;
 
-
-// 4-byte HTC field.  maybe included in any frame except non-QOS data frame.  The Order bit must set 1.
-typedef struct PACKED {
-    UINT32		MA:1;	//management action payload exist in (QoS Null+HTC)
-    UINT32		TRQ:1;	//sounding request
-    UINT32		MRQ:1;	//MCS feedback. Request for a MCS feedback
-    UINT32		MRSorASI:3;	// MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
-    UINT32		MFS:3;	//SET to the received value of MRS. 0x111 for unsolicited MFB.
-    UINT32		MFBorASC:7;	//Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
-    UINT32		CalPos:2;	// calibration position
-    UINT32		CalSeq:2;  //calibration sequence
-    UINT32		FBKReq:2;	//feedback request
-    UINT32		CSISTEERING:2;	//CSI/ STEERING
-    UINT32		ZLFAnnouce:1;	// ZLF announcement
-    UINT32		rsv:5;  //calibration sequence
-    UINT32		ACConstraint:1;	//feedback request
-    UINT32		RDG:1;	//RDG / More PPDU
-} HT_CONTROL, *PHT_CONTROL;
-
-// 2-byte QOS CONTROL field
-typedef struct PACKED {
-    USHORT      TID:4;
-    USHORT      EOSP:1;
-    USHORT      AckPolicy:2;  //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP  3: BA
-    USHORT      AMsduPresent:1;
-    USHORT      Txop_QueueSize:8;
-} QOS_CONTROL, *PQOS_CONTROL;
-
-// 2-byte Frame control field
-typedef	struct	PACKED {
-	USHORT		Ver:2;				// Protocol version
-	USHORT		Type:2;				// MSDU type
-	USHORT		SubType:4;			// MSDU subtype
-	USHORT		ToDs:1;				// To DS indication
-	USHORT		FrDs:1;				// From DS indication
-	USHORT		MoreFrag:1;			// More fragment bit
-	USHORT		Retry:1;			// Retry status bit
-	USHORT		PwrMgmt:1;			// Power management bit
-	USHORT		MoreData:1;			// More data bit
-	USHORT		Wep:1;				// Wep data
-	USHORT		Order:1;			// Strict order expected
-} FRAME_CONTROL, *PFRAME_CONTROL;
-
-typedef	struct	PACKED _HEADER_802_11	{
-    FRAME_CONTROL   FC;
-    USHORT          Duration;
-    UCHAR           Addr1[MAC_ADDR_LEN];
-    UCHAR           Addr2[MAC_ADDR_LEN];
-	UCHAR			Addr3[MAC_ADDR_LEN];
-	USHORT			Frag:4;
-	USHORT			Sequence:12;
-	UCHAR			Octet[0];
-}	HEADER_802_11, *PHEADER_802_11;
-
 typedef struct PACKED _FRAME_802_11 {
     HEADER_802_11   Hdr;
     UCHAR            Octet[1];
@@ -595,20 +546,6 @@ typedef struct {
 } EACH_TID, *PEACH_TID;
 
 
-typedef struct PACKED _PSPOLL_FRAME {
-    FRAME_CONTROL   FC;
-    USHORT          Aid;
-    UCHAR           Bssid[MAC_ADDR_LEN];
-    UCHAR           Ta[MAC_ADDR_LEN];
-}   PSPOLL_FRAME, *PPSPOLL_FRAME;
-
-typedef	struct	PACKED _RTS_FRAME	{
-    FRAME_CONTROL   FC;
-    USHORT          Duration;
-    UCHAR           Addr1[MAC_ADDR_LEN];
-    UCHAR           Addr2[MAC_ADDR_LEN];
-}RTS_FRAME, *PRTS_FRAME;
-
 // BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap.
 typedef struct PACKED _FRAME_BA_REQ {
 	FRAME_CONTROL   FC;
@@ -1059,7 +996,7 @@ typedef struct _MLME_START_REQ_STRUCT {
 typedef struct PACKED {
     UCHAR   Eid;
     UCHAR   Len;
-    CHAR   Octet[1];
+    UCHAR   Octet[1];
 } EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
 
 typedef struct PACKED _RTMP_TX_RATE_SWITCH

+ 93 - 42
drivers/staging/rt2860/oid.h

@@ -37,9 +37,14 @@
 #ifndef _OID_H_
 #define _OID_H_
 
+//#include <linux/wireless.h>
 
+#ifndef TRUE
 #define TRUE				1
+#endif
+#ifndef FALSE
 #define FALSE				0
+#endif
 //
 // IEEE 802.11 Structures and definitions
 //
@@ -73,24 +78,25 @@
 #define NDIS_802_11_LENGTH_RATES        8
 #define NDIS_802_11_LENGTH_RATES_EX     16
 #define MAC_ADDR_LENGTH                 6
-#define MAX_NUM_OF_CHS					49 // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
+//#define MAX_NUM_OF_CHS					49 // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
+#define MAX_NUM_OF_CHS				54      // 14 channels @2.4G +  12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination
 #define MAX_NUMBER_OF_EVENT				10  // entry # in EVENT table
 #define MAX_NUMBER_OF_MAC				32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
 #define MAX_NUMBER_OF_ACL				64
 #define MAX_LENGTH_OF_SUPPORT_RATES		12    // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
 #define MAX_NUMBER_OF_DLS_ENTRY			4
 
-#define OID_GEN_MACHINE_NAME               0x0001021A
 
 #define RT_QUERY_SIGNAL_CONTEXT				0x0402
 #define RT_SET_IAPP_PID                 	0x0404
 #define RT_SET_APD_PID						0x0405
 #define RT_SET_DEL_MAC_ENTRY				0x0406
-
+#define RT_QUERY_EVENT_TABLE			0x0407
 //
 // IEEE 802.11 OIDs
 //
 #define	OID_GET_SET_TOGGLE			0x8000
+#define	OID_GET_SET_FROM_UI			0x4000
 
 #define OID_802_11_ADD_WEP			0x0112
 #define OID_802_11_DISASSOCIATE			0x0114
@@ -101,22 +107,28 @@
 
 #define	RT_OID_DEVICE_NAME							0x0607
 #define	RT_OID_VERSION_INFO							0x0608
+#define	OID_802_11_BSSID_LIST						0x0609
+#define	OID_802_3_CURRENT_ADDRESS					0x060A
 #define	OID_GEN_MEDIA_CONNECT_STATUS				0x060B
+#define	RT_OID_802_11_QUERY_LINK_STATUS				0x060C
+#define	OID_802_11_RSSI								0x060D
+#define	OID_802_11_STATISTICS						0x060E
 #define	OID_GEN_RCV_OK								0x060F
 #define	OID_GEN_RCV_NO_BUFFER						0x0610
-
+#define	RT_OID_802_11_QUERY_EEPROM_VERSION			0x0611
+#define	RT_OID_802_11_QUERY_FIRMWARE_VERSION		0x0612
+#define	RT_OID_802_11_QUERY_LAST_RX_RATE			0x0613
+#define	RT_OID_802_11_TX_POWER_LEVEL_1				0x0614
+#define	RT_OID_802_11_QUERY_PIDVID					0x0615
+//for WPA_SUPPLICANT_SUPPORT
 #define OID_SET_COUNTERMEASURES                     0x0616
 #define RT_OID_WPA_SUPPLICANT_SUPPORT               0x0621
 #define RT_OID_WE_VERSION_COMPILED                  0x0622
 #define RT_OID_NEW_DRIVER                           0x0623
 
-//rt2860 , kathy
 #define RT_OID_DRIVER_DEVICE_NAME                   0x0645
 #define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT          0x0647
 
-// Ralink defined OIDs
-// Dennis Lee move to platform specific
-
 typedef enum _NDIS_802_11_STATUS_TYPE
 {
     Ndis802_11StatusType_Authentication,
@@ -169,10 +181,10 @@ typedef enum _NDIS_802_11_NETWORK_TYPE
    Ndis802_11FH,
    Ndis802_11DS,
     Ndis802_11OFDM5,
-    Ndis802_11OFDM5_N,
     Ndis802_11OFDM24,
-    Ndis802_11OFDM24_N,
    Ndis802_11Automode,
+    Ndis802_11OFDM5_N,
+    Ndis802_11OFDM24_N,
     Ndis802_11NetworkTypeMax    // not a real type, defined as an upper bound
 } NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
 
@@ -271,13 +283,15 @@ typedef struct PACKED _RADIUS_CONF
 	UINT32			own_ip_addr;
 	UINT32			retry_interval;
 	UINT32			session_timeout_interval;
-	UCHAR			EAPifname[IFNAMSIZ];
-	UCHAR			EAPifname_len;
-	UCHAR 			PreAuthifname[IFNAMSIZ];
-	UCHAR			PreAuthifname_len;
-	RADIUS_KEY_INFO	RadiusInfo[8/*MAX_MBSSID_NUM*/];
+	UCHAR			EAPifname[8][IFNAMSIZ];
+	UCHAR			EAPifname_len[8];
+	UCHAR			PreAuthifname[8][IFNAMSIZ];
+	UCHAR			PreAuthifname_len[8];
+	RADIUS_KEY_INFO	RadiusInfo[8];
 } RADIUS_CONF, *PRADIUS_CONF;
 
+
+
 // Key mapping keys require a BSSID
 typedef struct _NDIS_802_11_KEY
 {
@@ -289,6 +303,13 @@ typedef struct _NDIS_802_11_KEY
     UCHAR           KeyMaterial[1];     // variable length depending on above field
 } NDIS_802_11_KEY, *PNDIS_802_11_KEY;
 
+typedef struct _NDIS_802_11_PASSPHRASE
+{
+    UINT           KeyLength;          // length of key in bytes
+    NDIS_802_11_MAC_ADDRESS BSSID;
+    UCHAR           KeyMaterial[1];     // variable length depending on above field
+} NDIS_802_11_PASSPHRASE, *PNDIS_802_11_PASSPHRASE;
+
 typedef struct _NDIS_802_11_REMOVE_KEY
 {
     UINT           Length;             // Length of this structure
@@ -481,6 +502,19 @@ typedef struct _NDIS_802_11_AUTHENTICATION_EVENT
     NDIS_802_11_AUTHENTICATION_REQUEST  Request[1];
 } NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT;
 
+/*
+typedef struct _NDIS_802_11_TEST
+{
+    ULONG Length;
+    ULONG Type;
+    union
+    {
+        NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent;
+        NDIS_802_11_RSSI RssiTrigger;
+    };
+} NDIS_802_11_TEST, *PNDIS_802_11_TEST;
+ */
+
 // 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE
 typedef enum _NDIS_802_11_MEDIA_STREAM_MODE
 {
@@ -519,14 +553,18 @@ typedef struct _NDIS_802_11_CAPABILITY
      NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
 } NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
 
-#define RT_PRIV_IOCTL_EXT							(SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon
+#ifdef LINUX
+#endif // LINUX //
+
+
+#define RT_PRIV_IOCTL							(SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon
 #define RTPRIV_IOCTL_SET							(SIOCIWFIRSTPRIV + 0x02)
 
 #define RTPRIV_IOCTL_STATISTICS                     (SIOCIWFIRSTPRIV + 0x09)
 #define RTPRIV_IOCTL_ADD_PMKID_CACHE                (SIOCIWFIRSTPRIV + 0x0A)
 #define RTPRIV_IOCTL_RADIUS_DATA                    (SIOCIWFIRSTPRIV + 0x0C)
 #define RTPRIV_IOCTL_GSITESURVEY					(SIOCIWFIRSTPRIV + 0x0D)
-#define RT_PRIV_IOCTL								(SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
+#define RT_PRIV_IOCTL_EXT							(SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
 #define RTPRIV_IOCTL_GET_MAC_TABLE					(SIOCIWFIRSTPRIV + 0x0F)
 
 #define RTPRIV_IOCTL_SHOW							(SIOCIWFIRSTPRIV + 0x11)
@@ -535,27 +573,54 @@ enum {
     SHOW_DRVIER_VERION = 5,
     SHOW_BA_INFO = 6,
 	SHOW_DESC_INFO = 7,
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 	SHOW_RXBULK_INFO = 8,
 	SHOW_TXBULK_INFO = 9,
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
     RAIO_OFF = 10,
     RAIO_ON = 11,
 	SHOW_CFG_VALUE = 20,
-#if !defined(RT2860)
 	SHOW_ADHOC_ENTRY_INFO = 21,
-#endif
 };
 
-#ifdef LLTD_SUPPORT
+
+
+
+
+
+#define OID_802_11_BUILD_CHANNEL_EX				0x0714
+#define OID_802_11_GET_CH_LIST					0x0715
+#define OID_802_11_GET_COUNTRY_CODE				0x0716
+#define OID_802_11_GET_CHANNEL_GEOGRAPHY		0x0717
+
+//#define RT_OID_802_11_STATISTICS              (OID_GET_SET_TOGGLE | OID_802_11_STATISTICS)
+
+#define RT_OID_WSC_SET_PASSPHRASE                   0x0740 // passphrase for wpa(2)-psk
+#define RT_OID_WSC_DRIVER_AUTO_CONNECT              0x0741
+#define RT_OID_WSC_QUERY_DEFAULT_PROFILE            0x0742
+#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX        0x0743
+#define RT_OID_WSC_SET_ACTION                       0x0744
+#define RT_OID_WSC_SET_SSID                         0x0745
+#define RT_OID_WSC_SET_PIN_CODE                     0x0746
+#define RT_OID_WSC_SET_MODE                         0x0747 // PIN or PBC
+#define RT_OID_WSC_SET_CONF_MODE                    0x0748 // Enrollee or Registrar
+#define RT_OID_WSC_SET_PROFILE                      0x0749
+#define	RT_OID_WSC_CONFIG_STATUS					0x074F
+#define RT_OID_802_11_WSC_QUERY_PROFILE				0x0750
 // for consistency with RT61
-#define RT_OID_GET_PHY_MODE                         0x761
-#endif // LLTD_SUPPORT //
+#define RT_OID_WSC_QUERY_STATUS						0x0751
+#define RT_OID_WSC_PIN_CODE							0x0752
+#define RT_OID_WSC_UUID								0x0753
+#define RT_OID_WSC_SET_SELECTED_REGISTRAR			0x0754
+#define RT_OID_WSC_EAPMSG							0x0755
+#define RT_OID_WSC_MANUFACTURER						0x0756
+#define RT_OID_WSC_MODEL_NAME						0x0757
+#define RT_OID_WSC_MODEL_NO							0x0758
+#define RT_OID_WSC_SERIAL_NO						0x0759
+#define RT_OID_WSC_MAC_ADDRESS						0x0760
 
-#if defined(RT2860) || defined(RT30xx)
 // New for MeetingHouse Api support
 #define OID_MH_802_1X_SUPPORTED               0xFFEDC100
-#endif
 
 // MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition!!!
 typedef union  _HTTRANSMIT_SETTING {
@@ -564,6 +629,7 @@ typedef union  _HTTRANSMIT_SETTING {
 	USHORT		BW:1;	//channel bandwidth 20MHz or 40 MHz
 	USHORT		ShortGI:1;
 	USHORT		STBC:2;	//SPACE
+//	USHORT		rsv:3;
 	USHORT		rsv:2;
 	USHORT		TxBF:1;
 	USHORT		MODE:2;	// Use definition MODE_xxx.
@@ -577,7 +643,6 @@ typedef enum _RT_802_11_PREAMBLE {
     Rt802_11PreambleAuto
 } RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
 
-// Only for STA, need to sync with AP
 typedef enum _RT_802_11_PHY_MODE {
 	PHY_11BG_MIXED = 0,
 	PHY_11B,
@@ -744,19 +809,6 @@ typedef struct {
 	UCHAR		rsv;
 } OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE;
 
-#ifdef LLTD_SUPPORT
-typedef struct _RT_LLTD_ASSOICATION_ENTRY {
-    UCHAR           Addr[ETH_LENGTH_OF_ADDRESS];
-    unsigned short  MOR;        // maximum operational rate
-    UCHAR           phyMode;
-} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY;
-
-typedef struct _RT_LLTD_ASSOICATION_TABLE {
-    unsigned int                Num;
-    RT_LLTD_ASSOICATION_ENTRY   Entry[MAX_NUMBER_OF_MAC];
-} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE;
-#endif // LLTD_SUPPORT //
-
 #define MAX_CUSTOM_LEN 128
 
 typedef enum _RT_802_11_D_CLIENT_MODE
@@ -772,7 +824,6 @@ typedef struct _RT_CHANNEL_LIST_INFO
 	UCHAR ChannelListNum; // number of channel in ChannelList[]
 } RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO;
 
-#ifdef RT2870
 // WSC configured credential
 typedef	struct	_WSC_CREDENTIAL
 {
@@ -790,9 +841,9 @@ typedef	struct	_WSC_CREDENTIAL
 typedef	struct	_WSC_PROFILE
 {
 	UINT			ProfileCnt;
+	UINT			ApplyProfileIdx;  // add by johnli, fix WPS test plan 5.1.1
 	WSC_CREDENTIAL	Profile[8];				// Support up to 8 profiles
 }	WSC_PROFILE, *PWSC_PROFILE;
-#endif
 
 #endif // _OID_H_
 

+ 873 - 0
drivers/staging/rt2860/pci_main_dev.c

@@ -0,0 +1,873 @@
+/*
+ *************************************************************************
+ * 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:
+    pci_main_dev.c
+
+    Abstract:
+    Create and register network interface for PCI based chipsets in Linux platform.
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+*/
+
+#include "rt_config.h"
+#include <linux/pci.h>
+
+//
+// Function declarations
+//
+extern int rt28xx_close(IN struct net_device *net_dev);
+extern int rt28xx_open(struct net_device *net_dev);
+
+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);
+static void __exit rt2860_cleanup_module(void);
+static int __init rt2860_init_module(void);
+
+ static VOID RTMPInitPCIeDevice(
+    IN  struct pci_dev   *pci_dev,
+    IN PRTMP_ADAPTER     pAd);
+
+#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_probe,
+    remove:     __devexit_p(rt2860_remove_one),
+#ifdef CONFIG_PM
+	suspend:	rt2860_suspend,
+	resume:		rt2860_resume,
+#endif
+};
+
+
+/***************************************************************************
+ *
+ *	PCI device initialization related procedures.
+ *
+ ***************************************************************************/
+#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 = 0;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
+
+	if (net_dev == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
+	}
+	else
+	{
+		GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+		/* 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
+		GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	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);
+
+
+//
+// PCI device probe & initialization function
+//
+static INT __devinit   rt2860_probe(
+    IN  struct pci_dev              *pci_dev,
+    IN  const struct pci_device_id  *pci_id)
+{
+	PRTMP_ADAPTER		pAd = (PRTMP_ADAPTER)NULL;
+	struct  net_device		*net_dev;
+	PVOID				handle;
+	PSTRING				print_name;
+	ULONG				csr_addr;
+	INT rv = 0;
+	RTMP_OS_NETDEV_OP_HOOK	netDevHook;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_probe\n"));
+
+//PCIDevInit==============================================
+	// wake up and enable device
+	if ((rv = pci_enable_device(pci_dev))!= 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Enable PCI device failed, errno=%d!\n", rv));
+		return rv;
+	}
+
+	print_name = pci_name(pci_dev);
+
+	if ((rv = pci_request_regions(pci_dev, print_name)) != 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Request PCI resource failed, errno=%d!\n", rv));
+		goto err_out;
+	}
+
+	// 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;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n",  print_name,
+					(ULONG)pci_resource_start(pci_dev, 0), (ULONG)csr_addr, pci_dev->irq));
+	}
+
+	// Set DMA master
+	pci_set_master(pci_dev);
+
+
+//RtmpDevInit==============================================
+	// Allocate RTMP_ADAPTER adapter structure
+	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
+	if (handle == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s(): Allocate memory for os handle failed!\n", __func__));
+		goto err_out_iounmap;
+	}
+
+	((POS_COOKIE)handle)->pci_dev = pci_dev;
+
+	rv = RTMPAllocAdapterBlock(handle, &pAd);	//shiang: we may need the pci_dev for allocate structure of "RTMP_ADAPTER"
+	if (rv != NDIS_STATUS_SUCCESS)
+		goto err_out_iounmap;
+	// Here are the RTMP_ADAPTER structure with pci-bus specific parameters.
+	pAd->CSRBaseAddress = (PUCHAR)csr_addr;
+	DBGPRINT(RT_DEBUG_ERROR, ("pAd->CSRBaseAddress =0x%lx, csr_addr=0x%lx!\n", (ULONG)pAd->CSRBaseAddress, csr_addr));
+	RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_PCI);
+
+
+//NetDevInit==============================================
+	net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
+	if (net_dev == NULL)
+		goto err_out_free_radev;
+
+	// Here are the net_device structure with pci-bus specific parameters.
+	net_dev->irq = pci_dev->irq;		// Interrupt IRQ number
+	net_dev->base_addr = csr_addr;		// Save CSR virtual address and irq to device structure
+	pci_set_drvdata(pci_dev, net_dev);	// Set driver data
+
+/* for supporting Network Manager */
+	/* Set the sysfs physical device reference for the network logical device
+	  * if set prior to registration will cause a symlink during initialization.
+	 */
+	SET_NETDEV_DEV(net_dev, &(pci_dev->dev));
+
+
+//All done, it's time to register the net device to linux kernel.
+	// Register this device
+	rv = RtmpOSNetDevAttach(net_dev, &netDevHook);
+	if (rv)
+		goto err_out_free_netdev;
+
+	pAd->StaCfg.OriDevType = net_dev->type;
+	RTMPInitPCIeDevice(pci_dev, pAd);
+
+#ifdef KTHREAD_SUPPORT
+#endif // KTHREAD_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n"));
+
+	return 0; // probe ok
+
+
+	/* --------------------------- ERROR HANDLE --------------------------- */
+err_out_free_netdev:
+	RtmpOSNetDevFree(net_dev);
+
+err_out_free_radev:
+	/* free RTMP_ADAPTER strcuture and os_cookie*/
+	RTMPFreeAdapter(pAd);
+
+err_out_iounmap:
+	iounmap((void *)(csr_addr));
+	release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
+
+err_out_free_res:
+	pci_release_regions(pci_dev);
+
+err_out:
+	pci_disable_device(pci_dev);
+
+	DBGPRINT(RT_DEBUG_ERROR, ("<=== rt2860_probe failed with rv = %d!\n", rv));
+
+	return -ENODEV; /* probe fail */
+}
+
+
+static VOID __devexit rt2860_remove_one(
+    IN  struct pci_dev  *pci_dev)
+{
+	PNET_DEV	net_dev = pci_get_drvdata(pci_dev);
+	RTMP_ADAPTER	*pAd = NULL;
+	ULONG			csr_addr = net_dev->base_addr; // pAd->CSRBaseAddress;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
+
+	if (pAd != NULL)
+	{
+		// Unregister/Free all allocated net_device.
+		RtmpPhyNetDevExit(pAd, net_dev);
+
+		// Unmap CSR base address
+		iounmap((char *)(csr_addr));
+
+		// release memory region
+		release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
+
+		// Free RTMP_ADAPTER related structures.
+		RtmpRaDevCtrlExit(pAd);
+
+	}
+	else
+	{
+		// Unregister network device
+		RtmpOSNetDevDetach(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 the root net_device
+	RtmpOSNetDevFree(net_dev);
+
+}
+
+
+/*
+========================================================================
+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;
+}
+
+
+/***************************************************************************
+ *
+ *	PCIe device initialization related procedures.
+ *
+ ***************************************************************************/
+ static VOID RTMPInitPCIeDevice(
+    IN  struct pci_dev   *pci_dev,
+    IN PRTMP_ADAPTER     pAd)
+{
+	USHORT  device_id;
+	POS_COOKIE pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id);
+	device_id = le2cpu16(device_id);
+	pObj->DeviceID = device_id;
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE);
+	if (
+		(device_id == NIC2860_PCIe_DEVICE_ID) ||
+		(device_id == NIC2790_PCIe_DEVICE_ID) ||
+		(device_id == VEN_AWT_PCIe_DEVICE_ID) ||
+		 0)
+	{
+		UINT32 MacCsr0 = 0, Index= 0;
+		do
+		{
+			RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+
+			if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
+				break;
+
+			RTMPusecDelay(10);
+		} while (Index++ < 100);
+
+		// Support advanced power save after 2892/2790.
+		// MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO).
+		if ((MacCsr0&0xffff0000) != 0x28600000)
+		{
+			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE);
+		}
+	}
+}
+
+
+VOID RTMPInitPCIeLinkCtrlValue(
+	IN	PRTMP_ADAPTER	pAd)
+{
+    INT     pos;
+    USHORT	reg16, data2, PCIePowerSaveLevel, Configuration;
+    BOOLEAN	bFindIntel = FALSE;
+	POS_COOKIE pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+		return;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
+	// Init EEPROM, and save settings
+	if (!IS_RT3090(pAd))
+	{
+		RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
+		pAd->PCIePowerSaveLevel = PCIePowerSaveLevel & 0xff;
+
+		if ((PCIePowerSaveLevel&0xff) == 0xff)
+		{
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE);
+			DBGPRINT(RT_DEBUG_TRACE, ("====> PCIePowerSaveLevel = 0x%x.\n", PCIePowerSaveLevel));
+			return;
+		}
+	else
+	{
+		PCIePowerSaveLevel &= 0x3;
+		RT28xx_EEPROM_READ16(pAd, 0x24, data2);
+
+		if( !(((data2&0xff00) == 0x9200) && ((data2&0x80) !=0)) )
+		{
+			if (PCIePowerSaveLevel > 1 )
+				PCIePowerSaveLevel = 1;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("====> Write 0x83 = 0x%x.\n", PCIePowerSaveLevel));
+		AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00);
+		RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
+		PCIePowerSaveLevel &= 0xff;
+		PCIePowerSaveLevel = PCIePowerSaveLevel >> 6;
+		switch(PCIePowerSaveLevel)
+		{
+				case 0:	// Only support L0
+					pAd->LnkCtrlBitMask = 0;
+				break;
+				case 1:	// Only enable L0s
+					pAd->LnkCtrlBitMask = 1;
+				break;
+				case 2:	// enable L1, L0s
+					pAd->LnkCtrlBitMask = 3;
+				break;
+				case 3:	// sync with host clk and enable L1, L0s
+				pAd->LnkCtrlBitMask = 0x103;
+				break;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("====> LnkCtrlBitMask = 0x%x.\n", pAd->LnkCtrlBitMask));
+	}
+	}
+	else if (IS_RT3090(pAd))
+	{
+		// 1. read setting from inf file.
+		// .....
+		USHORT	PCIePowerSetting = 0;
+		/* code from windows, default value of rt30xxPowerMode = 0
+		PCIePowerSetting = pAd->StaCfg.PSControl.field.rt30xxPowerMode;
+		*/
+		DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx Read PowerLevelMode =  0x%x.\n", PCIePowerSetting));
+		// 2. Check EnableNewPS
+		/*
+		if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+			PCIePowerSetting = 1;
+		*/
+
+		if ((pAd->MACVersion&0xffff) <= 0x0211)
+		{
+			// Chip Version E only allow 1
+			PCIePowerSetting = 1;
+			DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx Write 0x83 Command = 0x%x.\n", PCIePowerSetting));
+			AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSetting, 0x00);
+		}
+		else
+		{
+			// Chip Version F only allow 1 or 2
+			if ((PCIePowerSetting > 2) || (PCIePowerSetting == 0))
+				PCIePowerSetting = 1;
+			DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx Write 0x83 Command = 0x%x.\n", PCIePowerSetting));
+			AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSetting, 0x00);
+		}
+
+	}
+
+    // Find Ralink PCIe Device's Express Capability Offset
+	pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
+
+    if (pos != 0)
+    {
+        // Ralink PCIe Device's Link Control Register Offset
+        pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+	pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, &reg16);
+        Configuration = le2cpu16(reg16);
+        DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
+                                    pAd->RLnkCtrlOffset, Configuration));
+        pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
+        Configuration &= 0xfefc;
+        Configuration |= (0x0);
+		if ((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
+			||(pObj->DeviceID == NIC2790_PCIe_DEVICE_ID))
+		{
+			reg16 = cpu2le16(Configuration);
+			pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, reg16);
+			DBGPRINT(RT_DEBUG_TRACE, ("Write (Ralink PCIe Link Control Register)  offset 0x%x = 0x%x\n",
+                                    pos + PCI_EXP_LNKCTL, Configuration));
+		}
+
+        RTMPFindHostPCIDev(pAd);
+        if (pObj->parent_pci_dev)
+        {
+		USHORT  vendor_id;
+
+		pci_read_config_word(pObj->parent_pci_dev, PCI_VENDOR_ID, &vendor_id);
+		vendor_id = le2cpu16(vendor_id);
+		if (vendor_id == PCIBUS_INTEL_VENDOR)
+			bFindIntel = TRUE;
+
+		// Find PCI-to-PCI Bridge Express Capability Offset
+		pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP);
+
+		if (pos != 0)
+		{
+			BOOLEAN		bChange = FALSE;
+			// PCI-to-PCI Bridge Link Control Register Offset
+			pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+			pci_read_config_word(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, &reg16);
+			Configuration = le2cpu16(reg16);
+			DBGPRINT(RT_DEBUG_TRACE, ("Read (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
+			                            pAd->HostLnkCtrlOffset, Configuration));
+			pAd->HostLnkCtrlConfiguration = (Configuration & 0x103);
+			Configuration &= 0xfefc;
+			Configuration |= (0x0);
+
+			switch (pObj->DeviceID)
+			{
+				case NIC2860_PCIe_DEVICE_ID:
+				case NIC2790_PCIe_DEVICE_ID:
+					bChange = TRUE;
+					break;
+				default:
+					break;
+			}
+
+			if (bChange)
+			{
+				reg16 = cpu2le16(Configuration);
+				pci_write_config_word(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, reg16);
+				DBGPRINT(RT_DEBUG_TRACE, ("Write (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
+						pAd->HostLnkCtrlOffset, Configuration));
+			}
+		}
+		else
+		{
+			pAd->HostLnkCtrlOffset = 0;
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot find PCI-to-PCI Bridge PCI Express Capability!\n", __func__));
+		}
+        }
+    }
+    else
+    {
+        pAd->RLnkCtrlOffset = 0;
+        pAd->HostLnkCtrlOffset = 0;
+        DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot find Ralink PCIe Device's PCI Express Capability!\n", __func__));
+    }
+
+    if (bFindIntel == FALSE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Doesn't find Intel PCI host controller. \n"));
+		// Doesn't switch L0, L1, So set PCIePowerSaveLevel to 0xff
+		pAd->PCIePowerSaveLevel = 0xff;
+		if ((pAd->RLnkCtrlOffset != 0)
+		)
+		{
+			pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, &reg16);
+			Configuration = le2cpu16(reg16);
+			DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink 30xx PCIe Link Control Register) offset 0x%x = 0x%x\n",
+			                        pAd->RLnkCtrlOffset, Configuration));
+			pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
+			Configuration &= 0xfefc;
+			Configuration |= (0x0);
+			reg16 = cpu2le16(Configuration);
+			pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, reg16);
+			DBGPRINT(RT_DEBUG_TRACE, ("Write (Ralink PCIe Link Control Register)  offset 0x%x = 0x%x\n",
+			                        pos + PCI_EXP_LNKCTL, Configuration));
+		}
+	}
+}
+
+VOID RTMPFindHostPCIDev(
+    IN	PRTMP_ADAPTER	pAd)
+{
+    USHORT  reg16;
+    UCHAR   reg8;
+	UINT	DevFn;
+    PPCI_DEV    pPci_dev;
+	POS_COOKIE	pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+		return;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
+
+    pObj->parent_pci_dev = NULL;
+    if (pObj->pci_dev->bus->parent)
+    {
+        for (DevFn = 0; DevFn < 255; DevFn++)
+        {
+            pPci_dev = pci_get_slot(pObj->pci_dev->bus->parent, DevFn);
+            if (pPci_dev)
+            {
+                pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE, &reg16);
+                reg16 = le2cpu16(reg16);
+                pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS, &reg8);
+                if ((reg16 == PCI_CLASS_BRIDGE_PCI) &&
+                    (reg8 == pObj->pci_dev->bus->number))
+                {
+                    pObj->parent_pci_dev = pPci_dev;
+                }
+            }
+        }
+    }
+}
+
+/*
+	========================================================================
+
+	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)
+{
+	USHORT  PCIePowerSaveLevel, reg16;
+	USHORT	Configuration;
+	POS_COOKIE	pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+		return;
+
+	if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
+		||(pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)))
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
+	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
+	if ((PCIePowerSaveLevel&0xff) == 0xff)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("return  \n"));
+		return;
+	}
+
+	if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0))
+    {
+        PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
+        if ((Configuration != 0) &&
+            (Configuration != 0xFFFF))
+        {
+		Configuration &= 0xfefc;
+		// If call from interface down, restore to orginial setting.
+		if (Level == RESTORE_CLOSE)
+		{
+			Configuration |= pAd->HostLnkCtrlConfiguration;
+		}
+		else
+			Configuration |= 0x0;
+            PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
+		DBGPRINT(RT_DEBUG_TRACE, ("Restore PCI host : offset 0x%x = 0x%x\n", pAd->HostLnkCtrlOffset, Configuration));
+        }
+        else
+            DBGPRINT(RT_DEBUG_ERROR, ("Restore PCI host : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", Configuration));
+    }
+
+    if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0))
+    {
+        PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
+        if ((Configuration != 0) &&
+            (Configuration != 0xFFFF))
+        {
+		Configuration &= 0xfefc;
+			// If call from interface down, restore to orginial setting.
+			if (Level == RESTORE_CLOSE)
+		Configuration |= pAd->RLnkCtrlConfiguration;
+			else
+				Configuration |= 0x0;
+            PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
+		DBGPRINT(RT_DEBUG_TRACE, ("Restore Ralink : offset 0x%x = 0x%x\n", pAd->RLnkCtrlOffset, Configuration));
+        }
+        else
+            DBGPRINT(RT_DEBUG_ERROR, ("Restore Ralink : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", Configuration));
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("%s <===\n", __func__));
+}
+
+/*
+	========================================================================
+
+	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)
+{
+	USHORT  PCIePowerSaveLevel, reg16;
+	USHORT	Configuration;
+	POS_COOKIE	pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+		return;
+
+	if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
+		||(pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)))
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__));
+	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
+	if ((PCIePowerSaveLevel&0xff) == 0xff)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("return  \n"));
+		return;
+	}
+	PCIePowerSaveLevel = PCIePowerSaveLevel>>6;
+
+
+	if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0))
+	{
+		// first 2892 chip not allow to frequently set mode 3. will cause hang problem.
+		if (PCIePowerSaveLevel > Max)
+			PCIePowerSaveLevel = Max;
+
+        PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
+		Configuration |= 0x100;
+        PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
+		DBGPRINT(RT_DEBUG_TRACE, ("Write Ralink device : offset 0x%x = 0x%x\n", pAd->RLnkCtrlOffset, Configuration));
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("RTMPPCIePowerLinkCtrl <==============\n"));
+}

+ 0 - 333
drivers/staging/rt2860/rt2860.h

@@ -1,333 +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.             *
- *                                                                       *
- *************************************************************************
- */
-
-#ifndef __RT2860_H__
-#define __RT2860_H__
-
-#define RT28xx_CHIP_NAME	"RT2860"
-
-#define TXINFO_SIZE               0
-#define TXPADDING_SIZE      	  0
-
-/* ----------------- EEPROM Related MACRO ----------------- */
-#define RT28xx_EEPROM_READ16(pAd, offset, var)		\
-	var = RTMP_EEPROM_READ16(pAd, offset)
-
-#define RT28xx_EEPROM_WRITE16(pAd, offset, var)		\
-	RTMP_EEPROM_WRITE16(pAd, offset, var)
-
-/* ----------------- TASK/THREAD Related MACRO ----------------- */
-#define RT28XX_TASK_THREAD_INIT(pAd, Status)		\
-	init_thread_task(pAd); NICInitTxRxRingAndBacklogQueue(pAd);	\
-	Status = NDIS_STATUS_SUCCESS;
-
-/* function declarations */
-#define IRQ_HANDLE_TYPE  irqreturn_t
-
-IRQ_HANDLE_TYPE
-rt2860_interrupt(int irq, void *dev_instance);
-
-/* ----------------- Frimware Related MACRO ----------------- */
-#define RT28XX_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 RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
-#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
-
-
-#define RT28XX_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 RT28XX_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 RTMP_PKT_TAIL_PADDING 0
-
-#define fRTMP_ADAPTER_NEED_STOP_TX	0
-
-#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 ----------------- */
-
-// no use
-#define RT28XX_RCV_PKT_GET_INIT(pAd)
-#define RT28XX_RV_A_BUF_END
-//#define RT28XX_RV_ALL_BUF_END
-
-
-/* ----------------- ASIC Related MACRO ----------------- */
-// no use
-#define RT28XX_DMA_POST_WRITE(pAd)
-
-// reset MAC of a station entry to 0x000000000000
-#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid)						\
-	AsicDelWcidTab(pAd, Wcid);
-
-// add this entry into ASIC RX WCID search table
-#define RT28XX_STA_ENTRY_ADD(pAd, pEntry)							\
-	AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
-
-// remove Pair-wise key material from ASIC
-#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)					\
-	AsicRemovePairwiseKeyEntry(pAd, BssIdx, (UCHAR)Wcid);
-
-// add Client security information into ASIC WCID table and IVEIV table
-#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)		\
-	RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, 					\
-							pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry);
-
-#define RT28XX_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 RT28XX_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 RT28XX_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)
-
-
-/* ----------------- PCI/USB Related MACRO ----------------- */
-
-#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p)				\
-	((POS_COOKIE)handle)->pci_dev = dev_p;
-
-// set driver data
-#define RT28XX_DRVDATA_SET(_a)			pci_set_drvdata(_a, net_dev);
-
-#define RT28XX_UNMAP()										\
-{	if (net_dev->base_addr)	{								\
-		iounmap((void *)(net_dev->base_addr));				\
-		release_mem_region(pci_resource_start(dev_p, 0),	\
-							pci_resource_len(dev_p, 0)); }	\
-	if (net_dev->irq) pci_release_regions(dev_p); }
-
-#ifdef PCI_MSI_SUPPORT
-#define RTMP_MSI_ENABLE(_pAd) \
-{ 	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
-	(_pAd)->HaveMsi =	pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; }
-
-#define RTMP_MSI_DISABLE(_pAd) \
-{ 	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
-	if (_pAd->HaveMsi == TRUE) \
-		pci_disable_msi(_pObj->pci_dev); \
-	_pAd->HaveMsi = FALSE;	}
-#else
-#define RTMP_MSI_ENABLE(_pAd)
-#define RTMP_MSI_DISABLE(_pAd)
-#endif // PCI_MSI_SUPPORT //
-
-#define SA_SHIRQ IRQF_SHARED
-
-#define RT28XX_IRQ_REQUEST(net_dev)							\
-{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv);	\
-	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);		\
-	RTMP_MSI_ENABLE(_pAd);									\
-	if ((retval = request_irq(_pObj->pci_dev->irq, 		\
-							rt2860_interrupt, SA_SHIRQ,		\
-							(net_dev)->name, (net_dev)))) {	\
-		printk("RT2860: request_irq  ERROR(%d)\n", retval);	\
-	return retval; } }
-
-#define RT28XX_IRQ_RELEASE(net_dev)								\
-{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv);		\
-	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);			\
-	synchronize_irq(_pObj->pci_dev->irq);						\
-	free_irq(_pObj->pci_dev->irq, (net_dev));					\
-	RTMP_MSI_DISABLE(_pAd); }
-
-#define RT28XX_IRQ_INIT(pAd)										\
-	{	pAd->int_enable_reg = ((DELAYINTMASK) |						\
-							(RxINT|TxDataInt|TxMgmtInt)) & ~(0x03);	\
-		pAd->int_disable_mask = 0;									\
-		pAd->int_pending = 0; }
-
-#define RT28XX_IRQ_ENABLE(pAd)									\
-	{	/* clear garbage ints */								\
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);		\
-		NICEnableInterrupt(pAd); }
-
-#define RT28XX_PUT_DEVICE(dev_p)
-
-
-/* ----------------- MLME Related MACRO ----------------- */
-#define RT28XX_MLME_HANDLER(pAd)			MlmeHandler(pAd)
-
-#define RT28XX_MLME_PRE_SANITY_CHECK(pAd)
-
-#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
-	RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
-#define RT28XX_MLME_RESET_STATE_MACHINE(pAd)	\
-		MlmeRestartStateMachine(pAd)
-
-#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)		\
-		HandleCounterMeasure(_pAd, _pEntry)
-
-/* ----------------- Power Save Related MACRO ----------------- */
-#define RT28XX_PS_POLL_ENQUEUE(pAd)				EnqueuePsPoll(pAd)
-
-//
-// 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 NIC_PCI_VENDOR_ID       0x1814
-
-#define VEN_AWT_PCIe_DEVICE_ID	0x1059
-#define VEN_AWT_PCI_VENDOR_ID	0x1A3B
-
-#define EDIMAX_PCI_VENDOR_ID	0x1432
-
-// 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 PCI_REG_READ_WORD(pci_dev, offset, Configuration)   \
-    if (pci_read_config_word(pci_dev, offset, &reg16) == 0)     \
-        Configuration = le2cpu16(reg16);                        \
-    else                                                        \
-        Configuration = 0;
-
-#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration)  \
-    reg16 = cpu2le16(Configuration);                        \
-    pci_write_config_word(pci_dev, offset, reg16);          \
-
-#define RT28XX_STA_FORCE_WAKEUP(pAd, Level) \
-    RT28xxPciStaAsicForceWakeup(pAd, Level);
-
-#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
-    RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
-
-#define RT28XX_MLME_RADIO_ON(pAd) \
-    RT28xxPciMlmeRadioOn(pAd);
-
-#define RT28XX_MLME_RADIO_OFF(pAd) \
-    RT28xxPciMlmeRadioOFF(pAd);
-
-#endif //__RT2860_H__
-

+ 20 - 12
drivers/staging/rt2860/rt_config.h

@@ -41,29 +41,37 @@
 #define	__RT_CONFIG_H__
 
 #include    "rtmp_type.h"
-#ifdef LINUX
-#include	"rt_linux.h"
-#endif
-#include    "rtmp_def.h"
-#include    "rt28xx.h"
+#include "rtmp_os.h"
 
-#ifdef RT2860
-#include	"rt2860.h"
-#endif
-#ifdef RT2870
-#include	"../rt2870/rt2870.h"
-#endif // RT2870 //
+#include "rtmp_def.h"
+#include "rtmp_chip.h"
+#include "rtmp_timer.h"
 
 #include    "oid.h"
 #include    "mlme.h"
 #include    "wpa.h"
-#include    "md5.h"
+#include "crypt_md5.h"
+#include "crypt_sha2.h"
+#include "crypt_hmac.h"
 #include    "rtmp.h"
 #include	"ap.h"
 #include	"dfs.h"
 #include	"chlist.h"
 #include	"spectrum.h"
 
+#include "eeprom.h"
+#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
+#include "rtmp_mcu.h"
+#endif
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+
+
+
 #ifdef IGMP_SNOOP_SUPPORT
 #include "igmp_snoop.h"
 #endif // IGMP_SNOOP_SUPPORT //

+ 555 - 60
drivers/staging/rt2860/rt_linux.c

@@ -30,27 +30,6 @@
 
 ULONG	RTDebugLevel = RT_DEBUG_ERROR;
 
-BUILD_TIMER_FUNCTION(MlmePeriodicExec);
-BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
-BUILD_TIMER_FUNCTION(APSDPeriodicExec);
-BUILD_TIMER_FUNCTION(AsicRfTuningExec);
-#ifdef RT2870
-BUILD_TIMER_FUNCTION(BeaconUpdateExec);
-#endif // RT2870 //
-
-BUILD_TIMER_FUNCTION(BeaconTimeout);
-BUILD_TIMER_FUNCTION(ScanTimeout);
-BUILD_TIMER_FUNCTION(AuthTimeout);
-BUILD_TIMER_FUNCTION(AssocTimeout);
-BUILD_TIMER_FUNCTION(ReassocTimeout);
-BUILD_TIMER_FUNCTION(DisassocTimeout);
-BUILD_TIMER_FUNCTION(LinkDownExec);
-BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
-BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-#ifdef RT2860
-BUILD_TIMER_FUNCTION(PsPollWakeExec);
-BUILD_TIMER_FUNCTION(RadioOnExec);
-#endif
 
 // for wireless system event message
 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
@@ -106,7 +85,7 @@ VOID RTMP_SetPeriodicTimer(
 	IN	NDIS_MINIPORT_TIMER *pTimer,
 	IN	unsigned long timeout)
 {
-	timeout = ((timeout*HZ) / 1000);
+	timeout = ((timeout*OS_HZ) / 1000);
 	pTimer->expires = jiffies + timeout;
 	add_timer(pTimer);
 }
@@ -131,7 +110,7 @@ VOID RTMP_OS_Add_Timer(
 	if (timer_pending(pTimer))
 		return;
 
-	timeout = ((timeout*HZ) / 1000);
+	timeout = ((timeout*OS_HZ) / 1000);
 	pTimer->expires = jiffies + timeout;
 	add_timer(pTimer);
 }
@@ -140,7 +119,7 @@ VOID RTMP_OS_Mod_Timer(
 	IN	NDIS_MINIPORT_TIMER		*pTimer,
 	IN	unsigned long timeout)
 {
-	timeout = ((timeout*HZ) / 1000);
+	timeout = ((timeout*OS_HZ) / 1000);
 	mod_timer(pTimer, jiffies + timeout);
 }
 
@@ -186,8 +165,8 @@ void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
 
 // pAd MUST allow to be NULL
 NDIS_STATUS os_alloc_mem(
-	IN	PRTMP_ADAPTER pAd,
-	OUT	PUCHAR *mem,
+	IN	RTMP_ADAPTER *pAd,
+	OUT	UCHAR **mem,
 	IN	ULONG  size)
 {
 	*mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
@@ -200,7 +179,7 @@ NDIS_STATUS os_alloc_mem(
 // pAd MUST allow to be NULL
 NDIS_STATUS os_free_mem(
 	IN	PRTMP_ADAPTER pAd,
-	IN	PUCHAR mem)
+	IN	PVOID mem)
 {
 
 	ASSERT(mem);
@@ -209,6 +188,20 @@ NDIS_STATUS os_free_mem(
 }
 
 
+
+
+PNDIS_PACKET RtmpOSNetPktAlloc(
+	IN RTMP_ADAPTER *pAd,
+	IN int size)
+{
+	struct sk_buff *skb;
+	/* Add 2 more bytes for ip header alignment*/
+	skb = dev_alloc_skb(size+2);
+
+	return ((PNDIS_PACKET)skb);
+}
+
+
 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
 	IN	PRTMP_ADAPTER pAd,
 	IN	ULONG	Length)
@@ -283,13 +276,16 @@ VOID	RTMPFreeAdapter(
 
 	os_cookie=(POS_COOKIE)pAd->OS_Cookie;
 
+	if (pAd->BeaconBuf)
 	kfree(pAd->BeaconBuf);
 
 
 	NdisFreeSpinLock(&pAd->MgmtRingLock);
-#ifdef RT2860
+
+#ifdef RTMP_MAC_PCI
 	NdisFreeSpinLock(&pAd->RxRingLock);
-#endif
+#endif // RTMP_MAC_PCI //
+
 	for (index =0 ; index < NUM_OF_TX_RING; index++)
 	{
     	NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
@@ -299,7 +295,9 @@ VOID	RTMPFreeAdapter(
 
 	NdisFreeSpinLock(&pAd->irq_lock);
 
+
 	vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
+	if (os_cookie)
 	kfree(os_cookie);
 }
 
@@ -379,7 +377,7 @@ NDIS_STATUS RTMPAllocateNdisPacket(
 	ASSERT(DataLen);
 
 	// 1. Allocate a packet
-	pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
+	pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + RTMP_PKT_TAIL_PADDING);
 	if (pPacket == NULL)
  	{
 		*ppPacket = NULL;
@@ -442,7 +440,7 @@ void RTMP_QueryPacketInfo(
 	OUT	UINT		 *pSrcBufLen)
 {
 	pPacketInfo->BufferCount = 1;
-	pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+	pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket);
 	pPacketInfo->PhysicalBufferCount = 1;
 	pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
 
@@ -464,7 +462,7 @@ void RTMP_QueryNextPacketInfo(
 	if (pPacket)
 	{
 		pPacketInfo->BufferCount = 1;
-		pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+		pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket);
 		pPacketInfo->PhysicalBufferCount = 1;
 		pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
 
@@ -485,18 +483,6 @@ void RTMP_QueryNextPacketInfo(
 	}
 }
 
-// not yet support MBSS
-PNET_DEV get_netdev_from_bssid(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			FromWhichBSSID)
-{
-    PNET_DEV dev_p = NULL;
-
-	dev_p = pAd->net_dev;
-
-	ASSERT(dev_p);
-	return dev_p; /* return one of MBSS */
-}
 
 PNDIS_PACKET DuplicatePacket(
 	IN	PRTMP_ADAPTER	pAd,
@@ -538,9 +524,9 @@ PNDIS_PACKET duplicate_pkt(
 	if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
 	{
 		skb_reserve(skb, 2);
-		NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
+		NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
 		skb_put(skb, HdrLen);
-		NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
+		NdisMoveMemory(skb->tail, pData, DataSize);
 		skb_put(skb, DataSize);
 		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
 		pPacket = OSPKT_TO_RTPKT(skb);
@@ -649,7 +635,9 @@ void wlan_802_11_to_802_3_packet(
 	//
 
 	NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
-}
+	}
+
+
 
 void announce_802_3_packet(
 	IN	PRTMP_ADAPTER	pAd,
@@ -726,8 +714,8 @@ VOID RTMPSendWirelessEvent(
 	IN	CHAR			Rssi)
 {
 
-	union 	iwreq_data      wrqu;
-	PUCHAR 	pBuf = NULL, pBufPtr = NULL;
+	//union		iwreq_data      wrqu;
+	PSTRING	pBuf = NULL, pBufPtr = NULL;
 	USHORT	event, type, BufLen;
 	UCHAR	event_table_len = 0;
 
@@ -788,13 +776,7 @@ VOID RTMPSendWirelessEvent(
 		pBufPtr[pBufPtr - pBuf] = '\0';
 		BufLen = pBufPtr - pBuf;
 
-		memset(&wrqu, 0, sizeof(wrqu));
-	    wrqu.data.flags = Event_flag;
-		wrqu.data.length = BufLen;
-
-		//send wireless event
-	    wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
-
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL, (PUCHAR)pBuf, BufLen);
 		//DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
 
 		kfree(pBuf);
@@ -896,7 +878,7 @@ void send_monitor_packets(
 
     ph->msgcode		    = DIDmsg_lnxind_wlansniffrm;
 	ph->msglen		    = sizeof(wlan_ng_prism2_header);
-	strcpy(ph->devname, pAd->net_dev->name);
+	strcpy((PSTRING) ph->devname, (PSTRING) pAd->net_dev->name);
 
     ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
 	ph->hosttime.status = 0;
@@ -972,18 +954,275 @@ err_free_sk_buff:
 
 }
 
-void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
+
+/*******************************************************************************
+
+	Device IRQ related functions.
+
+ *******************************************************************************/
+int RtmpOSIRQRequest(IN PNET_DEV pNetDev)
+{
+	struct net_device *net_dev = pNetDev;
+	PRTMP_ADAPTER pAd = NULL;
+	int retval = 0;
+
+	GET_PAD_FROM_NET_DEV(pAd, pNetDev);
+
+	ASSERT(pAd);
+
+#ifdef RTMP_PCI_SUPPORT
+	if (pAd->infType == RTMP_DEV_INF_PCI)
+	{
+		POS_COOKIE _pObj = (POS_COOKIE)(pAd->OS_Cookie);
+		RTMP_MSI_ENABLE(pAd);
+		retval = request_irq(_pObj->pci_dev->irq,  rt2860_interrupt, SA_SHIRQ, (net_dev)->name, (net_dev));
+		if (retval != 0)
+			printk("RT2860: request_irq  ERROR(%d)\n", retval);
+	}
+#endif // RTMP_PCI_SUPPORT //
+
+
+	return retval;
+
+}
+
+
+int RtmpOSIRQRelease(IN PNET_DEV pNetDev)
 {
-	daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
+	struct net_device *net_dev = pNetDev;
+	PRTMP_ADAPTER pAd = NULL;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	ASSERT(pAd);
+
+#ifdef RTMP_PCI_SUPPORT
+	if (pAd->infType == RTMP_DEV_INF_PCI)
+	{
+		POS_COOKIE pObj = (POS_COOKIE)(pAd->OS_Cookie);
+		synchronize_irq(pObj->pci_dev->irq);
+		free_irq(pObj->pci_dev->irq, (net_dev));
+		RTMP_MSI_DISABLE(pAd);
+	}
+#endif // RTMP_PCI_SUPPORT //
+
+
+	return 0;
+}
+
+
+/*******************************************************************************
+
+	File open/close related functions.
+
+ *******************************************************************************/
+RTMP_OS_FD RtmpOSFileOpen(char *pPath,  int flag, int mode)
+{
+	struct file	*filePtr;
+
+	filePtr = filp_open(pPath, flag, 0);
+	if (IS_ERR(filePtr))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s(): Error %ld opening %s\n", __func__, -PTR_ERR(filePtr), pPath));
+	}
+
+	return (RTMP_OS_FD)filePtr;
+}
+
+int RtmpOSFileClose(RTMP_OS_FD osfd)
+{
+	filp_close(osfd, NULL);
+	return 0;
+}
+
+
+void RtmpOSFileSeek(RTMP_OS_FD osfd, int offset)
+{
+	osfd->f_pos = offset;
+}
+
+
+int RtmpOSFileRead(RTMP_OS_FD osfd, char *pDataPtr, int readLen)
+{
+	// The object must have a read method
+	if (osfd->f_op && osfd->f_op->read)
+	{
+		return osfd->f_op->read(osfd,  pDataPtr, readLen, &osfd->f_pos);
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
+		return -1;
+	}
+}
+
+
+int RtmpOSFileWrite(RTMP_OS_FD osfd, char *pDataPtr, int writeLen)
+{
+	return osfd->f_op->write(osfd, pDataPtr, (size_t)writeLen, &osfd->f_pos);
+}
+
+
+void RtmpOSFSInfoChange(RTMP_OS_FS_INFO *pOSFSInfo, BOOLEAN bSet)
+{
+	if (bSet)
+	{
+		// Save uid and gid used for filesystem access.
+		// Set user and group to 0 (root)
+		pOSFSInfo->fsuid = current_fsuid();
+		pOSFSInfo->fsgid = current_fsgid();
+		pOSFSInfo->fs = get_fs();
+		set_fs(KERNEL_DS);
+	}
+	else
+	{
+		set_fs(pOSFSInfo->fs);
+	}
+}
+
+
+
+/*******************************************************************************
+
+	Task create/management/kill related functions.
+
+ *******************************************************************************/
+NDIS_STATUS RtmpOSTaskKill(
+	IN RTMP_OS_TASK *pTask)
+{
+	RTMP_ADAPTER *pAd;
+	int ret = NDIS_STATUS_FAILURE;
+
+	pAd = (RTMP_ADAPTER *)pTask->priv;
+
+#ifdef KTHREAD_SUPPORT
+	if (pTask->kthread_task)
+	{
+		kthread_stop(pTask->kthread_task);
+		ret = NDIS_STATUS_SUCCESS;
+	}
+#else
+	CHECK_PID_LEGALITY(pTask->taskPID)
+	{
+		printk("Terminate the task(%s) with pid(%d)!\n", pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
+		mb();
+		pTask->task_killed = 1;
+		mb();
+		ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
+		if (ret)
+		{
+			printk(KERN_WARNING "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
+				pTask->taskName, GET_PID_NUMBER(pTask->taskPID), ret);
+		}
+		else
+		{
+			wait_for_completion(&pTask->taskComplete);
+			pTask->taskPID = THREAD_PID_INIT_VALUE;
+			pTask->task_killed = 0;
+			ret = NDIS_STATUS_SUCCESS;
+		}
+	}
+#endif
+
+	return ret;
+
+}
+
+
+INT RtmpOSTaskNotifyToExit(
+	IN RTMP_OS_TASK *pTask)
+{
+
+#ifndef KTHREAD_SUPPORT
+	complete_and_exit(&pTask->taskComplete, 0);
+#endif
+
+	return 0;
+}
+
+
+void RtmpOSTaskCustomize(
+	IN RTMP_OS_TASK *pTask)
+{
+
+#ifndef KTHREAD_SUPPORT
+
+	daemonize((PSTRING)&pTask->taskName[0]/*"%s",pAd->net_dev->name*/);
 
 	allow_signal(SIGTERM);
 	allow_signal(SIGKILL);
 	current->flags |= PF_NOFREEZE;
 
 	/* signal that we've started the thread */
-	complete(pNotify);
+	complete(&pTask->taskComplete);
+
+#endif
 }
 
+
+NDIS_STATUS RtmpOSTaskAttach(
+	IN RTMP_OS_TASK *pTask,
+	IN int (*fn)(void *),
+	IN void *arg)
+{
+	NDIS_STATUS status = NDIS_STATUS_SUCCESS;
+	pid_t pid_number = -1;
+
+#ifdef KTHREAD_SUPPORT
+	pTask->task_killed = 0;
+	pTask->kthread_task = NULL;
+	pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
+	if (IS_ERR(pTask->kthread_task))
+		status = NDIS_STATUS_FAILURE;
+#else
+	pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
+	if (pid_number < 0)
+	{
+		DBGPRINT (RT_DEBUG_ERROR, ("Attach task(%s) failed!\n", pTask->taskName));
+		status = NDIS_STATUS_FAILURE;
+	}
+	else
+	{
+		pTask->taskPID = GET_PID(pid_number);
+
+		// Wait for the thread to start
+		wait_for_completion(&pTask->taskComplete);
+		status = NDIS_STATUS_SUCCESS;
+	}
+#endif
+	return status;
+}
+
+
+NDIS_STATUS RtmpOSTaskInit(
+	IN RTMP_OS_TASK *pTask,
+	IN PSTRING		pTaskName,
+	IN VOID			*pPriv)
+{
+	int len;
+
+	ASSERT(pTask);
+
+#ifndef KTHREAD_SUPPORT
+	NdisZeroMemory((PUCHAR)(pTask), sizeof(RTMP_OS_TASK));
+#endif
+
+	len = strlen(pTaskName);
+	len = len > (RTMP_OS_TASK_NAME_LEN -1) ? (RTMP_OS_TASK_NAME_LEN-1) : len;
+	NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
+	pTask->priv = pPriv;
+
+#ifndef KTHREAD_SUPPORT
+	RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+
+	init_completion (&pTask->taskComplete);
+#endif
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
 void RTMP_IndicateMediaState(
 	IN	PRTMP_ADAPTER	pAd)
 {
@@ -1000,3 +1239,259 @@ void RTMP_IndicateMediaState(
 	}
 }
 
+int RtmpOSWrielessEventSend(
+	IN RTMP_ADAPTER *pAd,
+	IN UINT32		eventType,
+	IN INT			flags,
+	IN PUCHAR		pSrcMac,
+	IN PUCHAR		pData,
+	IN UINT32		dataLen)
+{
+	union iwreq_data    wrqu;
+
+       memset(&wrqu, 0, sizeof(wrqu));
+
+	if (flags>-1)
+	       wrqu.data.flags = flags;
+
+	if (pSrcMac)
+		memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
+
+	if ((pData!= NULL) && (dataLen > 0))
+		wrqu.data.length = dataLen;
+
+       wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
+	return 0;
+}
+
+
+int RtmpOSNetDevAddrSet(
+	IN PNET_DEV pNetDev,
+	IN PUCHAR	pMacAddr)
+{
+	struct net_device *net_dev;
+	RTMP_ADAPTER *pAd;
+
+	net_dev = pNetDev;
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	// work-around for the SuSE due to it has it's own interface name management system.
+	{
+		NdisZeroMemory(pAd->StaCfg.dev_name, 16);
+		NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
+	}
+
+	NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
+
+	return 0;
+}
+
+
+
+/*
+  *	Assign the network dev name for created Ralink WiFi interface.
+  */
+static int RtmpOSNetDevRequestName(
+	IN RTMP_ADAPTER *pAd,
+	IN PNET_DEV dev,
+	IN PSTRING pPrefixStr,
+	IN INT	devIdx)
+{
+	PNET_DEV		existNetDev;
+	STRING		suffixName[IFNAMSIZ];
+	STRING		desiredName[IFNAMSIZ];
+	int	ifNameIdx, prefixLen, slotNameLen;
+	int Status;
+
+
+	prefixLen = strlen(pPrefixStr);
+	ASSERT((prefixLen < IFNAMSIZ));
+
+	for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++)
+	{
+		memset(suffixName, 0, IFNAMSIZ);
+		memset(desiredName, 0, IFNAMSIZ);
+		strncpy(&desiredName[0], pPrefixStr, prefixLen);
+
+		sprintf(suffixName, "%d", ifNameIdx);
+
+		slotNameLen = strlen(suffixName);
+		ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
+		strcat(desiredName, suffixName);
+
+		existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
+		if (existNetDev == NULL)
+			break;
+		else
+			RtmpOSNetDeviceRefPut(existNetDev);
+	}
+
+	if(ifNameIdx < 32)
+	{
+		strcpy(&dev->name[0], &desiredName[0]);
+		Status = NDIS_STATUS_SUCCESS;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR,
+					("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", pPrefixStr));
+		Status = NDIS_STATUS_FAILURE;
+	}
+
+	return Status;
+}
+
+
+void RtmpOSNetDevClose(
+	IN PNET_DEV pNetDev)
+{
+	dev_close(pNetDev);
+}
+
+
+void RtmpOSNetDevFree(PNET_DEV pNetDev)
+{
+	ASSERT(pNetDev);
+
+	free_netdev(pNetDev);
+}
+
+
+INT RtmpOSNetDevAlloc(
+	IN PNET_DEV *new_dev_p,
+	IN UINT32	privDataSize)
+{
+	// assign it as null first.
+	*new_dev_p = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Allocate a net device with private data size=%d!\n", privDataSize));
+	*new_dev_p = alloc_etherdev(privDataSize);
+	if (*new_dev_p)
+		return NDIS_STATUS_SUCCESS;
+	else
+		return NDIS_STATUS_FAILURE;
+}
+
+
+PNET_DEV RtmpOSNetDevGetByName(PNET_DEV pNetDev, PSTRING pDevName)
+{
+	PNET_DEV	pTargetNetDev = NULL;
+
+	pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
+
+	return pTargetNetDev;
+}
+
+
+void RtmpOSNetDeviceRefPut(PNET_DEV pNetDev)
+{
+	/*
+		every time dev_get_by_name is called, and it has returned a valid struct
+		net_device*, dev_put should be called afterwards, because otherwise the
+		machine hangs when the device is unregistered (since dev->refcnt > 1).
+	*/
+	if(pNetDev)
+		dev_put(pNetDev);
+}
+
+
+INT RtmpOSNetDevDestory(
+	IN RTMP_ADAPTER *pAd,
+	IN PNET_DEV		pNetDev)
+{
+
+	// TODO: Need to fix this
+	printk("WARNING: This function(%s) not implement yet!!!\n", __func__);
+	return 0;
+}
+
+
+void RtmpOSNetDevDetach(PNET_DEV pNetDev)
+{
+	unregister_netdev(pNetDev);
+}
+
+
+int RtmpOSNetDevAttach(
+	IN PNET_DEV pNetDev,
+	IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook)
+{
+	int ret, rtnl_locked = FALSE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
+	// If we need hook some callback function to the net device structrue, now do it.
+	if (pDevOpHook)
+	{
+		PRTMP_ADAPTER pAd = NULL;
+
+		GET_PAD_FROM_NET_DEV(pAd, pNetDev);
+
+		pNetDev->netdev_ops = pDevOpHook->netdev_ops;
+
+		/* OS specific flags, here we used to indicate if we are virtual interface */
+		pNetDev->priv_flags = pDevOpHook->priv_flags;
+
+
+		if (pAd->OpMode == OPMODE_STA)
+		{
+			pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
+		}
+
+
+		// copy the net device mac address to the net_device structure.
+		NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], MAC_ADDR_LEN);
+
+		rtnl_locked = pDevOpHook->needProtcted;
+	}
+
+	if (rtnl_locked)
+		ret = register_netdevice(pNetDev);
+	else
+		ret = register_netdev(pNetDev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
+	if (ret == 0)
+		return NDIS_STATUS_SUCCESS;
+	else
+		return NDIS_STATUS_FAILURE;
+}
+
+
+PNET_DEV RtmpOSNetDevCreate(
+	IN RTMP_ADAPTER *pAd,
+	IN INT			devType,
+	IN INT			devNum,
+	IN INT			privMemSize,
+	IN PSTRING		pNamePrefix)
+{
+	struct net_device *pNetDev = NULL;
+	int status;
+
+
+	/* allocate a new network device */
+	status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize*/);
+	if (status != NDIS_STATUS_SUCCESS)
+	{
+		/* allocation fail, exit */
+		DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (%s)...\n", pNamePrefix));
+		return NULL;
+	}
+
+
+	/* find a available interface name, max 32 interfaces */
+	status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
+	if (status != NDIS_STATUS_SUCCESS)
+	{
+		/* error! no any available ra name can be used! */
+		DBGPRINT(RT_DEBUG_ERROR, ("Assign interface name (%s with suffix 0~32) failed...\n", pNamePrefix));
+		RtmpOSNetDevFree(pNetDev);
+
+		return NULL;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("The name of the new %s interface is %s...\n", pNamePrefix, pNetDev->name));
+	}
+
+	return pNetDev;
+}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 456 - 354
drivers/staging/rt2860/rt_linux.h


+ 236 - 514
drivers/staging/rt2860/rt_main_dev.c

@@ -33,20 +33,18 @@
     Revision History:
     Who         When            What
     --------    ----------      ----------------------------------------------
-	Sample		Mar/21/07		Merge RT2870 and RT2860 drivers.
 */
 
 #include "rt_config.h"
 
-#define FORTY_MHZ_INTOLERANT_INTERVAL	(60*1000) // 1 min
+
 
 /*---------------------------------------------------------------------*/
 /* Private Variables Used                                              */
 /*---------------------------------------------------------------------*/
-//static RALINK_TIMER_STRUCT     PeriodicTimer;
 
-char *mac = "";		   // default 00:00:00:00:00:00
-char *hostname = "";		   // default CMPC
+PSTRING mac = "";		   // default 00:00:00:00:00:00
+PSTRING hostname = "";		   // default CMPC
 module_param (mac, charp, 0);
 MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
 
@@ -54,31 +52,16 @@ MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
 /*---------------------------------------------------------------------*/
 /* Prototypes of Functions Used                                        */
 /*---------------------------------------------------------------------*/
-extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
-extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
-extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
-
-#ifdef RT2860
-extern void init_thread_task(PRTMP_ADAPTER pAd);
-#endif
 
 // public function prototype
-INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
-							IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
+int rt28xx_close(IN struct net_device *net_dev);
+int rt28xx_open(struct net_device *net_dev);
 
 // private function prototype
-static int rt28xx_init(IN struct net_device *net_dev);
-INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
-
-static void CfgInitHook(PRTMP_ADAPTER pAd);
+static INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
 
-extern	const struct iw_handler_def rt28xx_iw_handler_def;
 
-// This function will be called when query /proc
-struct iw_statistics *rt28xx_get_wireless_stats(
-    IN struct net_device *net_dev);
-
-struct net_device_stats *RT28xx_get_ether_stats(
+static struct net_device_stats *RT28xx_get_ether_stats(
     IN  struct net_device *net_dev);
 
 /*
@@ -103,7 +86,9 @@ Note:
 */
 int MainVirtualIF_close(IN struct net_device *net_dev)
 {
-    RTMP_ADAPTER *pAd = net_dev->ml_priv;
+    RTMP_ADAPTER *pAd = NULL;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
 	// Sanity check for pAd
 	if (pAd == NULL)
@@ -112,6 +97,40 @@ int MainVirtualIF_close(IN struct net_device *net_dev)
 	netif_carrier_off(pAd->net_dev);
 	netif_stop_queue(pAd->net_dev);
 
+	{
+		BOOLEAN			Cancelled;
+
+		if (INFRA_ON(pAd) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+		{
+			MLME_DISASSOC_REQ_STRUCT	DisReq;
+			MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+			if (MsgElem)
+			{
+			COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
+			DisReq.Reason =  REASON_DEAUTH_STA_LEAVING;
+
+			MsgElem->Machine = ASSOC_STATE_MACHINE;
+			MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+			MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+			NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+			// Prevent to connect AP again in STAMlmePeriodicExec
+			pAd->MlmeAux.AutoReconnectSsidLen= 32;
+			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+			MlmeDisassocReqAction(pAd, MsgElem);
+			kfree(MsgElem);
+			}
+
+			RTMPusecDelay(1000);
+		}
+
+		RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
+	}
 
 	VIRTUAL_IF_DOWN(pAd);
 
@@ -142,7 +161,9 @@ Note:
 */
 int MainVirtualIF_open(IN struct net_device *net_dev)
 {
-    RTMP_ADAPTER *pAd = net_dev->ml_priv;
+    RTMP_ADAPTER *pAd = NULL;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
 	// Sanity check for pAd
 	if (pAd == NULL)
@@ -184,83 +205,46 @@ Note:
 int rt28xx_close(IN PNET_DEV dev)
 {
 	struct net_device * net_dev = (struct net_device *)dev;
-    RTMP_ADAPTER	*pAd = net_dev->ml_priv;
-	BOOLEAN 		Cancelled = FALSE;
+    RTMP_ADAPTER	*pAd = NULL;
+	BOOLEAN			Cancelled;
 	UINT32			i = 0;
-#ifdef RT2870
-	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+#ifdef RTMP_MAC_USB
+	DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
 	DECLARE_WAITQUEUE(wait, current);
 
 	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
-#endif // RT2870 //
-
+#endif // RTMP_MAC_USB //
 
     DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
 
+	Cancelled = FALSE;
 	// Sanity check for pAd
 	if (pAd == NULL)
 		return 0; // close ok
 
 	{
+#ifdef RTMP_PCI_SUPPORT
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
+#endif // RTMP_PCI_SUPPORT //
+
 		// If dirver doesn't wake up firmware here,
 		// NICLoadFirmware will hang forever when interface is up again.
-#ifdef RT2860
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
-			RTMP_SET_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
-			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
-#endif
-#ifdef RT2870
 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#endif
         {
-#ifdef RT2860
-		    AsicForceWakeup(pAd, RTMP_HALT);
-#endif
-#ifdef RT2870
 		    AsicForceWakeup(pAd, TRUE);
-#endif
         }
 
-		if (INFRA_ON(pAd) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-		{
-			MLME_DISASSOC_REQ_STRUCT	DisReq;
-			MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
-
-			COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
-			DisReq.Reason =  REASON_DEAUTH_STA_LEAVING;
-
-			MsgElem->Machine = ASSOC_STATE_MACHINE;
-			MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
-			MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
-			NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
-
-			// Prevent to connect AP again in STAMlmePeriodicExec
-			pAd->MlmeAux.AutoReconnectSsidLen= 32;
-			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
-			MlmeDisassocReqAction(pAd, MsgElem);
-			kfree(MsgElem);
-
-			RTMPusecDelay(1000);
-		}
-
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
-#endif // RT2870 //
-
-#ifdef CCX_SUPPORT
-		RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
-#endif
-
-		RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
+#endif // RTMP_MAC_USB //
 
 		MlmeRadioOff(pAd);
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 		pAd->bPCIclkOff = FALSE;
-#endif
+#endif // RTMP_MAC_PCI //
 	}
 
 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
@@ -269,12 +253,12 @@ int rt28xx_close(IN PNET_DEV dev)
 	{
 		while (pAd->DeQueueRunning[i] == TRUE)
 		{
-			printk("Waiting for TxQueue[%d] done..........\n", i);
+			DBGPRINT(RT_DEBUG_TRACE, ("Waiting for TxQueue[%d] done..........\n", i));
 			RTMPusecDelay(1000);
 		}
 	}
 
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 	// ensure there are no more active urbs.
 	add_wait_queue (&unlink_wakeup, &wait);
 	pAd->wait = &unlink_wakeup;
@@ -299,290 +283,89 @@ int rt28xx_close(IN PNET_DEV dev)
 	}
 	pAd->wait = NULL;
 	remove_wait_queue (&unlink_wakeup, &wait);
-#endif // RT2870 //
-
-#ifdef RT2870
-	// We need clear timerQ related structure before exits of the timer thread.
-	RT2870_TimerQ_Exit(pAd);
-	// Close kernel threads or tasklets
-	RT28xxThreadTerminate(pAd);
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
 
 	// Stop Mlme state machine
 	MlmeHalt(pAd);
 
-	// Close kernel threads or tasklets
-	kill_thread_task(pAd);
-
-	MacTableReset(pAd);
+	// Close net tasklets
+	RtmpNetTaskExit(pAd);
 
-	MeasureReqTabExit(pAd);
-	TpcReqTabExit(pAd);
-
-#ifdef RT2860
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
 	{
-		NICDisableInterrupt(pAd);
+		MacTableReset(pAd);
 	}
 
-	// Disable Rx, register value supposed will remain after reset
-	NICIssueReset(pAd);
 
-	// Free IRQ
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-	{
-		// Deregister interrupt function
-		RT28XX_IRQ_RELEASE(net_dev)
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
-	}
-#endif
-
-	// Free Ring or USB buffers
-	RTMPFreeTxRxRingMemory(pAd);
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-
-	// Free BA reorder resource
-	ba_reordering_resource_release(pAd);
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
-
-	return 0; // close ok
-} /* End of rt28xx_close */
-
-static int rt28xx_init(IN struct net_device *net_dev)
-{
-#ifdef RT2860
-	PRTMP_ADAPTER 			pAd = (PRTMP_ADAPTER)net_dev->ml_priv;
-#endif
-#ifdef RT2870
-	PRTMP_ADAPTER 			pAd = net_dev->ml_priv;
-#endif
-	UINT					index;
-	UCHAR					TmpPhy;
-	NDIS_STATUS				Status;
-	UINT32 		MacCsr0 = 0;
-
-	// Allocate BA Reordering memory
-	ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
-
-	// Make sure MAC gets ready.
-	index = 0;
-	do
-	{
-		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
-		pAd->MACVersion = MacCsr0;
-
-		if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
-			break;
-
-		RTMPusecDelay(10);
-	} while (index++ < 100);
+	MeasureReqTabExit(pAd);
+	TpcReqTabExit(pAd);
 
-	DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
-/*Iverson patch PCIE L1 issue */
 
-	// Disable DMA
-	RT28XXDMADisable(pAd);
+	// Close kernel threads
+	RtmpMgmtTaskExit(pAd);
 
-	// Load 8051 firmware
-	Status = NICLoadFirmware(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
+#ifdef RTMP_MAC_PCI
 	{
-		DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
-		goto err1;
-	}
-
-	NICLoadRateSwitchingParams(pAd);
+			BOOLEAN brc;
+			//	ULONG			Value;
 
-	// Disable interrupts here which is as soon as possible
-	// This statement should never be true. We might consider to remove it later
-#ifdef RT2860
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
 	{
-		NICDisableInterrupt(pAd);
+				RTMP_ASIC_INTERRUPT_DISABLE(pAd);
 	}
-#endif
 
-	Status = RTMPAllocTxRxRingMemory(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
-		goto err1;
-	}
+			// Receive packets to clear DMA index after disable interrupt.
+			//RTMPHandleRxDoneInterrupt(pAd);
+			// put to radio off to save power when driver unload.  After radiooff, can't write /read register.  So need to finish all
+			// register access before Radio off.
 
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
 
-	// initialize MLME
-	//
-
-	Status = MlmeInit(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
+			brc=RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
+			if (brc==FALSE)
 	{
-		DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
-		goto err2;
+				DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __func__));
 	}
-
-	// Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
-	//
-	UserCfgInit(pAd);
-
-#ifdef RT2870
-	// We need init timerQ related structure before create the timer thread.
-	RT2870_TimerQ_Init(pAd);
-#endif // RT2870 //
-
-	RT28XX_TASK_THREAD_INIT(pAd, Status);
-	if (Status != NDIS_STATUS_SUCCESS)
-		goto err1;
-
-	CfgInitHook(pAd);
-
-	NdisAllocateSpinLock(&pAd->MacTabLock);
-
-	MeasureReqTabInit(pAd);
-	TpcReqTabInit(pAd);
-
-	//
-	// Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
-	//
-	Status = NICInitializeAdapter(pAd, TRUE);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
-		if (Status != NDIS_STATUS_SUCCESS)
-		goto err3;
-	}
-
-	// Read parameters from Config File
-	Status = RTMPReadParametersHook(pAd);
-
-	printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
-	if (Status != NDIS_STATUS_SUCCESS)
-	{
-		DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
-		goto err4;
 	}
 
-#ifdef RT2870
-	pAd->CommonCfg.bMultipleIRP = FALSE;
-
-	if (pAd->CommonCfg.bMultipleIRP)
-		pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
-	else
-		pAd->CommonCfg.NumOfBulkInIRP = 1;
-#endif // RT2870 //
-
-
-   	//Init Ba Capability parameters.
-	pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
-	pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
-	pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
-	// UPdata to HT IE
-	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
-
-	printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
-
-	// We should read EEPROM for all cases.  rt2860b
-	NICReadEEPROMParameters(pAd, mac);
-
-	printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
-
-	NICInitAsicFromEEPROM(pAd); //rt2860b
 
-	// Set PHY to appropriate mode
-	TmpPhy = pAd->CommonCfg.PhyMode;
-	pAd->CommonCfg.PhyMode = 0xff;
-	RTMPSetPhyMode(pAd, TmpPhy);
-	SetCommonHT(pAd);
-
-	// No valid channels.
-	if (pAd->ChannelListNum == 0)
+/*
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
 	{
-		printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
-		goto err4;
+		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
 	}
 
-	printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
-           pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
-           pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);
-
-#ifdef RT2870
-    //Init RT30xx RFRegisters after read RFIC type from EEPROM
-	NICInitRT30xxRFRegisters(pAd);
-#endif // RT2870 //
-
-
-		//
-	// Initialize RF register to default value
-	//
-	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-#ifndef RT2870
-	// 8051 firmware require the signal during booting time.
-	AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00);
-#endif
+	// Disable Rx, register value supposed will remain after reset
+	NICIssueReset(pAd);
+*/
+#endif // RTMP_MAC_PCI //
 
-	if (pAd && (Status != NDIS_STATUS_SUCCESS))
-	{
-		//
-		// Undo everything if it failed
-		//
+	// Free IRQ
 		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
 		{
+#ifdef RTMP_MAC_PCI
+		// Deregister interrupt function
+		RtmpOSIRQRelease(net_dev);
+#endif // RTMP_MAC_PCI //
 			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
 		}
-	}
-	else if (pAd)
-	{
-		// Microsoft HCT require driver send a disconnect event after driver initialization.
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
-
-
-#ifdef RT2870
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
-
-		//
-		// Support multiple BulkIn IRP,
-		// the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
-		//
-		for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
-		{
-			RTUSBBulkReceive(pAd);
-			DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
-		}
-#endif // RT2870 //
-	}// end of else
 
+	// Free Ring or USB buffers
+	RTMPFreeTxRxRingMemory(pAd);
 
-	DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
 
-	return TRUE;
+	// Free BA reorder resource
+	ba_reordering_resource_release(pAd);
 
 
-err4:
-err3:
-	MlmeHalt(pAd);
-err2:
-	RTMPFreeTxRxRingMemory(pAd);
-err1:
-	os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
-	RT28XX_IRQ_RELEASE(net_dev);
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
 
-	// shall not set ml_priv to NULL here because the ml_priv didn't been free yet.
-	//net_dev->ml_priv = 0;
+/*+++Modify by woody to solve the bulk fail+++*/
+	{
+	}
 
-	printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
-	return FALSE;
-} /* End of rt28xx_init */
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
+	return 0; // close ok
+} /* End of rt28xx_close */
 
 
 /*
@@ -603,10 +386,11 @@ Note:
 int rt28xx_open(IN PNET_DEV dev)
 {
 	struct net_device * net_dev = (struct net_device *)dev;
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
+	PRTMP_ADAPTER pAd = NULL;
 	int retval = 0;
- 	POS_COOKIE pObj;
+	//POS_COOKIE pObj;
 
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
 	// Sanity check for pAd
 	if (pAd == NULL)
@@ -616,37 +400,32 @@ int rt28xx_open(IN PNET_DEV dev)
 		return -1;
 	}
 
-	// Init
- 	pObj = (POS_COOKIE)pAd->OS_Cookie;
+#ifdef RTMP_PCI_SUPPORT
+        RTMPInitPCIeLinkCtrlValue(pAd);
+#endif // RTMP_PCI_SUPPORT //
 
-	// reset Adapter flags
-	RTMP_CLEAR_FLAGS(pAd);
+
+	if (net_dev->priv_flags == INT_MAIN)
+	{
+		if (pAd->OpMode == OPMODE_STA)
+			net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
+	}
 
 	// Request interrupt service routine for PCI device
 	// register the interrupt routine with the os
-	RT28XX_IRQ_REQUEST(net_dev);
-
+	RtmpOSIRQRequest(net_dev);
 
-	// Init BssTab & ChannelInfo tabbles for auto channel select.
 
+	// Init IRQ parameters stored in pAd
+	RTMP_IRQ_INIT(pAd);
 
 	// Chip & other init
-	if (rt28xx_init(net_dev) == FALSE)
+	if (rt28xx_init(pAd, mac, hostname) == FALSE)
 		goto err;
 
-	NdisZeroMemory(pAd->StaCfg.dev_name, 16);
-	NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
-
-	// Set up the Mac address
-	NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6);
-
-	// Init IRQ parameters
-	RT28XX_IRQ_INIT(pAd);
-
-	// Various AP function init
 
 	// Enable Interrupt
-	RT28XX_IRQ_ENABLE(pAd);
+	RTMP_IRQ_ENABLE(pAd);
 
 	// Now Enable RxTx
 	RTMPEnableRxTx(pAd);
@@ -658,12 +437,26 @@ int rt28xx_open(IN PNET_DEV dev)
 	printk("0x1300 = %08x\n", reg);
 	}
 
-#ifdef RT2860
-        RTMPInitPCIeLinkCtrlValue(pAd);
-#endif
+	{
+//	u32 reg;
+//	UINT8  byte;
+//	u16 tmp;
+
+//	RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);
+
+//	tmp = 0x0805;
+//	reg  = (reg & 0xffff0000) | tmp;
+//	RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);
+
+	}
+
+
 	return (retval);
 
 err:
+//+++Add by shiang, move from rt28xx_init() to here.
+	RtmpOSIRQRelease(net_dev);
+//---Add by shiang, move from rt28xx_init() to here.
 	return (-1);
 } /* End of rt28xx_open */
 
@@ -678,155 +471,33 @@ static const struct net_device_ops rt2860_netdev_ops = {
 	.ndo_start_xmit		= rt28xx_send_packets,
 };
 
-/* Must not be called for mdev and apdev */
-static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
+PNET_DEV RtmpPhyNetDevInit(
+	IN RTMP_ADAPTER *pAd,
+	IN RTMP_OS_NETDEV_OP_HOOK *pNetDevHook)
 {
-	NDIS_STATUS Status;
-	INT     i=0;
-	CHAR    slot_name[IFNAMSIZ];
-	struct net_device   *device;
-
-	if (pAd->OpMode == OPMODE_STA)
-	{
-		dev->wireless_handlers = &rt28xx_iw_handler_def;
-	}
-
-	dev->priv_flags = INT_MAIN;
-	dev->netdev_ops = &rt2860_netdev_ops;
-	// find available device name
-	for (i = 0; i < 8; i++)
-	{
-		sprintf(slot_name, "wlan%d", i);
-
-		device = dev_get_by_name(dev_net(dev), slot_name);
-		if (device != NULL)
-			dev_put(device);
+	struct net_device	*net_dev = NULL;
+//	NDIS_STATUS		Status;
 
-		if (device == NULL)
-			break;
-	}
-
-	if(i == 8)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
-		Status = NDIS_STATUS_FAILURE;
-	}
-	else
-	{
-		sprintf(dev->name, "wlan%d", i);
-		Status = NDIS_STATUS_SUCCESS;
-	}
-
-	return Status;
-
-}
-
-/*
-========================================================================
-Routine Description:
-    Probe RT28XX chipset.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-	_dev_id_p			Point to the PCI or USB device ID
-
-Return Value:
-    0					Probe OK
-	-ENODEV				Probe Fail
-
-Note:
-========================================================================
-*/
-INT __devinit   rt28xx_probe(
-    IN  void *_dev_p,
-    IN  void *_dev_id_p,
-	IN  UINT argc,
-	OUT PRTMP_ADAPTER *ppAd)
-{
-    struct  net_device	*net_dev;
-    PRTMP_ADAPTER       pAd = (PRTMP_ADAPTER) NULL;
-    INT                 status;
-	PVOID				handle;
-#ifdef RT2860
-	struct pci_dev *dev_p = (struct pci_dev *)_dev_p;
-#endif
-#ifdef RT2870
-	struct usb_interface *intf = (struct usb_interface *)_dev_p;
-	struct usb_device *dev_p = interface_to_usbdev(intf);
-
-	dev_p = usb_get_dev(dev_p);
-#endif // RT2870 //
-
-    DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
-
-    net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
+	net_dev = RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(PRTMP_ADAPTER), INF_MAIN_DEV_NAME);
     if (net_dev == NULL)
     {
-        printk("alloc_netdev failed\n");
-
-        goto err_out;
+		printk("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
+		return NULL;
     }
 
-	netif_stop_queue(net_dev);
-
-/* for supporting Network Manager */
-/* Set the sysfs physical device reference for the network logical device
- * if set prior to registration will cause a symlink during initialization.
- */
-    SET_NETDEV_DEV(net_dev, &(dev_p->dev));
-
-	// Allocate RTMP_ADAPTER miniport adapter structure
-	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
-	if (handle == NULL)
-		goto err_out_free_netdev;;
-	RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
-
-	status = RTMPAllocAdapterBlock(handle, &pAd);
-	if (status != NDIS_STATUS_SUCCESS)
-		goto err_out_free_netdev;
+	NdisZeroMemory((unsigned char *)pNetDevHook, sizeof(RTMP_OS_NETDEV_OP_HOOK));
+	pNetDevHook->netdev_ops = &rt2860_netdev_ops;
+	pNetDevHook->priv_flags = INT_MAIN;
+	pNetDevHook->needProtcted = FALSE;
 
 	net_dev->ml_priv = (PVOID)pAd;
-    pAd->net_dev = net_dev; // must be before RT28XXNetDevInit()
-
-	RT28XXNetDevInit(_dev_p, net_dev, pAd);
-
-    pAd->StaCfg.OriDevType = net_dev->type;
-
-	// Post config
-	if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
-		goto err_out_unmap;
-
-	pAd->OpMode = OPMODE_STA;
-
-	// sample move
-	if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS)
-		goto err_out_unmap;
-
-    // Register this device
-    status = register_netdev(net_dev);
-    if (status)
-        goto err_out_unmap;
-
-    // Set driver data
-	RT28XX_DRVDATA_SET(_dev_p);
-
-	*ppAd = pAd;
-    return 0; // probe ok
-
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-err_out_unmap:
-	RTMPFreeAdapter(pAd);
-	RT28XX_UNMAP();
+	pAd->net_dev = net_dev;
 
-err_out_free_netdev:
-	free_netdev(net_dev);
+	netif_stop_queue(net_dev);
 
-err_out:
-	RT28XX_PUT_DEVICE(dev_p);
+	return net_dev;
 
-	return -ENODEV; /* probe fail */
-} /* End of rt28xx_probe */
+}
 
 
 /*
@@ -849,10 +520,14 @@ Note:
 int rt28xx_packet_xmit(struct sk_buff *skb)
 {
 	struct net_device *net_dev = skb->dev;
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
+	PRTMP_ADAPTER pAd = NULL;
 	int status = NETDEV_TX_OK;
 	PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
 
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	/* RT2870STA does this in RTMPSendPackets() */
+
 	{
 		// Drop send request since we are in monitor mode
 		if (MONITOR_ON(pAd))
@@ -872,12 +547,6 @@ int rt28xx_packet_xmit(struct sk_buff *skb)
 	}
 
 	RTMP_SET_PACKET_5VT(pPacket, 0);
-#ifdef CONFIG_5VT_ENHANCE
-    if (*(int*)(skb->cb) == BRIDGE_TAG) {
-		RTMP_SET_PACKET_5VT(pPacket, 1);
-    }
-#endif
-
 	STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
 
 	status = NETDEV_TX_OK;
@@ -903,11 +572,14 @@ Return Value:
 Note:
 ========================================================================
 */
-INT rt28xx_send_packets(
+static int rt28xx_send_packets(
 	IN struct sk_buff 		*skb_p,
 	IN struct net_device 	*net_dev)
 {
-    RTMP_ADAPTER *pAd = net_dev->ml_priv;
+	RTMP_ADAPTER *pAd = NULL;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
 	if (!(net_dev->flags & IFF_UP))
 	{
 		RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
@@ -918,36 +590,35 @@ INT rt28xx_send_packets(
 	RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
 
 	return rt28xx_packet_xmit(skb_p);
-
-} /* End of MBSS_VirtualIF_PacketSend */
-
-
-
-
-void CfgInitHook(PRTMP_ADAPTER pAd)
-{
-	pAd->bBroadComHT = TRUE;
-} /* End of CfgInitHook */
+}
 
 
 // This function will be called when query /proc
 struct iw_statistics *rt28xx_get_wireless_stats(
     IN struct net_device *net_dev)
 {
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
+	PRTMP_ADAPTER pAd = NULL;
 
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
 
 	pAd->iw_stats.status = 0; // Status - device dependent for now
 
 	// link quality
+	if (pAd->OpMode == OPMODE_STA)
 	pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
+
 	if(pAd->iw_stats.qual.qual > 100)
 		pAd->iw_stats.qual.qual = 100;
 
 	if (pAd->OpMode == OPMODE_STA)
-		pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
+	{
+		pAd->iw_stats.qual.level =
+			RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
+							pAd->StaCfg.RssiSample.LastRssi1,
+							pAd->StaCfg.RssiSample.LastRssi2);
+	}
 
 	pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
 
@@ -962,13 +633,12 @@ struct iw_statistics *rt28xx_get_wireless_stats(
 
 	DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
 	return &pAd->iw_stats;
-} /* End of rt28xx_get_wireless_stats */
-
+}
 
 
 void tbtt_tasklet(unsigned long data)
 {
-#define MAX_TX_IN_TBTT		(16)
+//#define MAX_TX_IN_TBTT		(16)
 
 }
 
@@ -988,13 +658,13 @@ void tbtt_tasklet(unsigned long data)
 
     ========================================================================
 */
-struct net_device_stats *RT28xx_get_ether_stats(
+static struct net_device_stats *RT28xx_get_ether_stats(
     IN  struct net_device *net_dev)
 {
     RTMP_ADAPTER *pAd = NULL;
 
 	if (net_dev)
-		pAd = net_dev->ml_priv;
+		GET_PAD_FROM_NET_DEV(pAd, net_dev);
 
 	if (pAd)
 	{
@@ -1038,3 +708,55 @@ struct net_device_stats *RT28xx_get_ether_stats(
     	return NULL;
 }
 
+
+BOOLEAN RtmpPhyNetDevExit(
+	IN RTMP_ADAPTER *pAd,
+	IN PNET_DEV net_dev)
+{
+
+
+
+	// Unregister network device
+	if (net_dev != NULL)
+	{
+		printk("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n", net_dev->name);
+		RtmpOSNetDevDetach(net_dev);
+	}
+
+	return TRUE;
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Allocate memory for adapter control block.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_FAILURE
+	NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS AdapterBlockAllocateMemory(
+	IN PVOID	handle,
+	OUT	PVOID	*ppAd)
+{
+
+	*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);
+	}
+}

+ 877 - 0
drivers/staging/rt2860/rt_pci_rbus.c

@@ -0,0 +1,877 @@
+/*
+ *************************************************************************
+ * 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:
+    rt_pci_rbus.c
+
+    Abstract:
+    Create and register network interface.
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+*/
+
+#include "rt_config.h"
+#include <linux/pci.h>
+
+IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance);
+
+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 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
+
+
+/***************************************************************************
+  *
+  *	Interface-depended memory allocation/Free related procedures.
+  *		Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc.,
+  *
+  **************************************************************************/
+// Function for TxDesc Memory allocation.
+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);
+
+}
+
+
+// Function for MgmtDesc Memory allocation.
+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);
+
+}
+
+
+// Function for RxDesc Memory allocation.
+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);
+
+}
+
+
+// Function for free allocated Desc Memory.
+void RTMP_FreeDescMemory(
+	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);
+}
+
+
+// Function for TxData DMA Memory allocation.
+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);
+}
+
+
+void RTMP_FreeFirstTxBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	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);
+}
+
+
+/*
+ * 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);
+}
+
+
+/*
+ * 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)
+{
+	struct sk_buff *pkt;
+
+	pkt = 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(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+		*VirtualAddress = (PVOID) 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);
+}
+
+
+NDIS_STATUS RtmpNetTaskInit(IN RTMP_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->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+void RtmpNetTaskExit(IN RTMP_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->tbtt_task);
+	tasklet_kill(&pObj->fifo_statistic_full_task);
+}
+
+
+NDIS_STATUS RtmpMgmtTaskInit(IN RTMP_ADAPTER *pAd)
+{
+
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Close kernel threads.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+    NONE
+
+Note:
+========================================================================
+*/
+VOID RtmpMgmtTaskExit(
+	IN RTMP_ADAPTER *pAd)
+{
+
+
+	return;
+}
+
+
+static inline 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);
+	//if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+	{
+		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);     // 1:enable
+	}
+	//else
+	//	DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n"));
+
+	if (regValue != 0)
+		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
+}
+
+
+static inline 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);
+	}
+}
+
+
+/***************************************************************************
+  *
+  *	tasklet related procedures.
+  *
+  **************************************************************************/
+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;
+
+//	printk("mgmt_dma_done_process\n");
+	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 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;
+
+//	printk("ac0_dma_done_process\n");
+	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;
+
+//	printk("ac0_dma_done_process\n");
+	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;
+
+//	printk("ac0_dma_done_process\n");
+	IntSource.word = 0;
+	IntSource.field.Ac0DmaDone = 1;
+	pAd->int_pending &= ~INT_AC0_DLY;
+
+//	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
+	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);
+}
+
+
+
+
+/***************************************************************************
+  *
+  *	interrupt handler related procedures.
+  *
+  **************************************************************************/
+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 = NULL;
+	INT_SOURCE_CSR_STRUC	IntSource;
+	POS_COOKIE pObj;
+
+	GET_PAD_FROM_NET_DEV(pAd, net_dev);
+
+	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.
+//	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+	{
+		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
+		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
+	}
+//	else
+//		DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n"));
+
+//	RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IsrAfterClear);
+//	RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &McuIsrAfterClear);
+//	DBGPRINT(RT_DEBUG_INFO, ("====> RTMPHandleInterrupt(ISR=%08x,Mcu ISR=%08x, After clear ISR=%08x, MCU ISR=%08x)\n",
+//			IntSource.word, McuIntSource.word, IsrAfterClear, McuIsrAfterClear));
+
+	// Do nothing if Reset in progress
+	if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |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
+	//
+
+#ifdef DBG
+
+#endif
+
+
+	pAd->bPCIclkOff = FALSE;
+
+	// 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));
+        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 ((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;
+	}
+
+	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_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)
+	{
+
+/*
+		if (IntSource.word & 0x2) {
+			u32 reg;
+			RTMP_IO_READ32(pAd, DELAY_INT_CFG, &reg);
+			printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg);
+		}
+*/
+		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;
+}
+
+/*
+ * 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;
+
+	if (size > 0)
+		pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
+
+}

+ 36 - 1803
drivers/staging/rt2860/rt_profile.c

@@ -23,1840 +23,73 @@
  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  *                                                                       *
  *************************************************************************
- */
 
-#include "rt_config.h"
-
-static void HTParametersHook(
-	IN	PRTMP_ADAPTER pAd,
-	IN	CHAR		  *pValueStr,
-	IN	CHAR		  *pInput);
-
-#define ETH_MAC_ADDR_STR_LEN 17  // in format of xx:xx:xx:xx:xx:xx
-
-// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
-BOOLEAN rtstrmactohex(char *s1, char *s2)
-{
-	int i = 0;
-	char *ptokS = s1, *ptokE = s1;
-
-	if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
-		return FALSE;
-
-	while((*ptokS) != '\0')
-	{
-		if((ptokE = strchr(ptokS, ':')) != NULL)
-			*ptokE++ = '\0';
-		if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
-			break; // fail
-		AtoH(ptokS, &s2[i++], 1);
-		ptokS = ptokE;
-		if (i == 6)
-			break; // parsing finished
-	}
-
-	return ( i == 6 ? TRUE : FALSE);
-
-}
-
-
-// we assume the s1 and s2 both are strings.
-BOOLEAN rtstrcasecmp(char *s1, char *s2)
-{
-	char *p1 = s1, *p2 = s2;
-
-	if (strlen(s1) != strlen(s2))
-		return FALSE;
-
-	while(*p1 != '\0')
-	{
-		if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
-			return FALSE;
-		p1++;
-		p2++;
-	}
-
-	return TRUE;
-}
-
-// we assume the s1 (buffer) and s2 (key) both are strings.
-char * rtstrstruncasecmp(char * s1, char * s2)
-{
-	INT l1, l2, i;
-	char temp1, temp2;
-
-	l2 = strlen(s2);
-	if (!l2)
-		return (char *) s1;
-
-	l1 = strlen(s1);
-
-	while (l1 >= l2)
-	{
-		l1--;
-
-		for(i=0; i<l2; i++)
-		{
-			temp1 = *(s1+i);
-			temp2 = *(s2+i);
-
-			if (('a' <= temp1) && (temp1 <= 'z'))
-				temp1 = 'A'+(temp1-'a');
-			if (('a' <= temp2) && (temp2 <= 'z'))
-				temp2 = 'A'+(temp2-'a');
-
-			if (temp1 != temp2)
-				break;
-		}
-
-		if (i == l2)
-			return (char *) s1;
-
-		s1++;
-	}
-
-	return NULL; // not found
-}
-
-//add by kathy
-
- /**
-  * strstr - Find the first substring in a %NUL terminated string
-  * @s1: The string to be searched
-  * @s2: The string to search for
-  */
-char * rtstrstr(const char * s1,const char * s2)
-{
-	INT l1, l2;
-
-	l2 = strlen(s2);
-	if (!l2)
-		return (char *) s1;
-
-	l1 = strlen(s1);
-
-	while (l1 >= l2)
-	{
-		l1--;
-		if (!memcmp(s1,s2,l2))
-			return (char *) s1;
-		s1++;
-	}
-
-	return NULL;
-}
-
-/**
- * rstrtok - Split a string into tokens
- * @s: The string to be searched
- * @ct: The characters to search for
- * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
- */
-char * __rstrtok;
-char * rstrtok(char * s,const char * ct)
-{
-	char *sbegin, *send;
-
-	sbegin  = s ? s : __rstrtok;
-	if (!sbegin)
-	{
-		return NULL;
-	}
-
-	sbegin += strspn(sbegin,ct);
-	if (*sbegin == '\0')
-	{
-		__rstrtok = NULL;
-		return( NULL );
-	}
-
-	send = strpbrk( sbegin, ct);
-	if (send && *send != '\0')
-		*send++ = '\0';
-
-	__rstrtok = send;
-
-	return (sbegin);
-}
-
-/**
- * delimitcnt - return the count of a given delimiter in a given string.
- * @s: The string to be searched.
- * @ct: The delimiter to search for.
- * Notice : We suppose the delimiter is a single-char string(for example : ";").
- */
-INT delimitcnt(char * s,const char * ct)
-{
-	INT count = 0;
-	/* point to the beginning of the line */
-	const char *token = s;
-
-	for ( ;; )
-	{
-		token = strpbrk(token, ct); /* search for delimiters */
-
-        if ( token == NULL )
-		{
-			/* advanced to the terminating null character */
-			break;
-		}
-		/* skip the delimiter */
-	    ++token;
-
-		/*
-		 * Print the found text: use len with %.*s to specify field width.
-		 */
-
-		/* accumulate delimiter count */
-	    ++count;
-	}
-    return count;
-}
+    Module Name:
+	rt_profile.c
 
-/*
-  * converts the Internet host address from the standard numbers-and-dots notation
-  * into binary data.
-  * returns nonzero if the address is valid, zero if not.
-  */
-int rtinet_aton(const char *cp, unsigned int *addr)
-{
-	unsigned int 	val;
-	int         	base, n;
-	char        	c;
-	unsigned int    parts[4];
-	unsigned int    *pp = parts;
+    Abstract:
 
-	for (;;)
-    {
-         /*
-          * Collect number up to ``.''.
-          * Values are specified as for C:
-          *	0x=hex, 0=octal, other=decimal.
-          */
-         val = 0;
-         base = 10;
-         if (*cp == '0')
-         {
-             if (*++cp == 'x' || *cp == 'X')
-                 base = 16, cp++;
-             else
-                 base = 8;
-         }
-         while ((c = *cp) != '\0')
-         {
-             if (isdigit((unsigned char) c))
-             {
-                 val = (val * base) + (c - '0');
-                 cp++;
-                 continue;
-             }
-             if (base == 16 && isxdigit((unsigned char) c))
-             {
-                 val = (val << 4) +
-                     (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
-                 cp++;
-                 continue;
-             }
-             break;
-         }
-         if (*cp == '.')
-         {
-             /*
-              * Internet format: a.b.c.d a.b.c   (with c treated as 16-bits)
-              * a.b     (with b treated as 24 bits)
-              */
-             if (pp >= parts + 3 || val > 0xff)
-                 return 0;
-             *pp++ = val, cp++;
-         }
-         else
-             break;
-     }
-
-     /*
-      * Check for trailing junk.
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
       */
-     while (*cp)
-         if (!isspace((unsigned char) *cp++))
-             return 0;
-
-     /*
-      * Concoct the address according to the number of parts specified.
-      */
-     n = pp - parts + 1;
-     switch (n)
-     {
-
-         case 1:         /* a -- 32 bits */
-             break;
-
-         case 2:         /* a.b -- 8.24 bits */
-             if (val > 0xffffff)
-                 return 0;
-             val |= parts[0] << 24;
-             break;
-
-         case 3:         /* a.b.c -- 8.8.16 bits */
-             if (val > 0xffff)
-                 return 0;
-             val |= (parts[0] << 24) | (parts[1] << 16);
-             break;
-
-         case 4:         /* a.b.c.d -- 8.8.8.8 bits */
-             if (val > 0xff)
-                 return 0;
-             val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
-             break;
-     }
-
-     *addr = htonl(val);
-     return 1;
-
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Find key section for Get key parameter.
-
-    Arguments:
-        buffer                      Pointer to the buffer to start find the key section
-        section                     the key of the secion to be find
-
-    Return Value:
-        NULL                        Fail
-        Others                      Success
-    ========================================================================
-*/
-PUCHAR  RTMPFindSection(
-    IN  PCHAR   buffer)
-{
-    CHAR temp_buf[32];
-    PUCHAR  ptr;
-
-    strcpy(temp_buf, "Default");
-
-    if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
-            return (ptr+strlen("\n"));
-        else
-            return NULL;
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Get key parameter.
 
-    Arguments:
-        key                         Pointer to key string
-        dest                        Pointer to destination
-        destsize                    The datasize of the destination
-        buffer                      Pointer to the buffer to start find the key
-
-    Return Value:
-        TRUE                        Success
-        FALSE                       Fail
-
-    Note:
-        This routine get the value with the matched key (case case-sensitive)
-    ========================================================================
-*/
-INT RTMPGetKeyParameter(
-    IN  PCHAR   key,
-    OUT PCHAR   dest,
-    IN  INT     destsize,
-    IN  PCHAR   buffer)
-{
-    UCHAR *temp_buf1 = NULL;
-    UCHAR *temp_buf2 = NULL;
-    CHAR *start_ptr;
-    CHAR *end_ptr;
-    CHAR *ptr;
-    CHAR *offset = 0;
-    INT  len;
-
-	//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
-
-	if(temp_buf1 == NULL)
-        return (FALSE);
-
-	//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
-	if(temp_buf2 == NULL)
-	{
-		os_free_mem(NULL, temp_buf1);
-        return (FALSE);
-	}
-
-    //find section
-    if((offset = RTMPFindSection(buffer)) == NULL)
-    {
-    	os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf1, "\n");
-    strcat(temp_buf1, key);
-    strcat(temp_buf1, "=");
-
-    //search key
-    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    start_ptr+=strlen("\n");
-    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
-       end_ptr=start_ptr+strlen(start_ptr);
-
-    if (end_ptr<start_ptr)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
-    temp_buf2[end_ptr-start_ptr]='\0';
-    len = strlen(temp_buf2);
-    strcpy(temp_buf1, temp_buf2);
-    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf2, start_ptr+1);
-    ptr = temp_buf2;
-    //trim space or tab
-    while(*ptr != 0x00)
-    {
-        if( (*ptr == ' ') || (*ptr == '\t') )
-            ptr++;
-        else
-           break;
-    }
-
-    len = strlen(ptr);
-    memset(dest, 0x00, destsize);
-    strncpy(dest, ptr, len >= destsize ?  destsize: len);
-
-	os_free_mem(NULL, temp_buf1);
-    os_free_mem(NULL, temp_buf2);
-    return TRUE;
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Get key parameter.
-
-    Arguments:
-        key                         Pointer to key string
-        dest                        Pointer to destination
-        destsize                    The datasize of the destination
-        buffer                      Pointer to the buffer to start find the key
+#include "rt_config.h"
 
-    Return Value:
-        TRUE                        Success
-        FALSE                       Fail
 
-    Note:
-        This routine get the value with the matched key (case case-sensitive).
-        It is called for parsing SSID and any key string.
-    ========================================================================
-*/
-INT RTMPGetCriticalParameter(
-    IN  PCHAR   key,
-    OUT PCHAR   dest,
-    IN  INT     destsize,
-    IN  PCHAR   buffer)
+NDIS_STATUS	RTMPReadParametersHook(
+	IN	PRTMP_ADAPTER pAd)
 {
-    UCHAR *temp_buf1 = NULL;
-    UCHAR *temp_buf2 = NULL;
-    CHAR *start_ptr;
-    CHAR *end_ptr;
-    CHAR *ptr;
-    CHAR *offset = 0;
-    INT  len;
+	PSTRING					src = NULL;
+	RTMP_OS_FD				srcf;
+	RTMP_OS_FS_INFO			osFSInfo;
+	INT						retval = NDIS_STATUS_FAILURE;
+	PSTRING					buffer;
 
-	//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
-
-	if(temp_buf1 == NULL)
-        return (FALSE);
-
-	//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
-	if(temp_buf2 == NULL)
-	{
-		os_free_mem(NULL, temp_buf1);
-        return (FALSE);
-	}
-
-    //find section
-    if((offset = RTMPFindSection(buffer)) == NULL)
-    {
-    	os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf1, "\n");
-    strcat(temp_buf1, key);
-    strcat(temp_buf1, "=");
-
-    //search key
-    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    start_ptr+=strlen("\n");
-    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
-       end_ptr=start_ptr+strlen(start_ptr);
-
-    if (end_ptr<start_ptr)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
+	buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	if(buffer == NULL)
+		return NDIS_STATUS_FAILURE;
+	memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
 
-    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
-    temp_buf2[end_ptr-start_ptr]='\0';
-    len = strlen(temp_buf2);
-    strcpy(temp_buf1, temp_buf2);
-    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
     {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf2, start_ptr+1);
-    ptr = temp_buf2;
-
-    //trim tab
-    /* We cannot trim space(' ') for SSID and key string. */
-    while(*ptr != 0x00)
     {
-        //if( (*ptr == ' ') || (*ptr == '\t') )
-        if( (*ptr == '\t') )
-            ptr++;
-        else
-           break;
+			src = STA_PROFILE_PATH;
     }
-
-    len = strlen(ptr);
-    memset(dest, 0x00, destsize);
-    strncpy(dest, ptr, len >= destsize ?  destsize: len);
-
-	os_free_mem(NULL, temp_buf1);
-    os_free_mem(NULL, temp_buf2);
-    return TRUE;
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Get multiple key parameter.
-
-    Arguments:
-        key                         Pointer to key string
-        dest                        Pointer to destination
-        destsize                    The datasize of the destination
-        buffer                      Pointer to the buffer to start find the key
-
-    Return Value:
-        TRUE                        Success
-        FALSE                       Fail
-
-    Note:
-        This routine get the value with the matched key (case case-sensitive)
-    ========================================================================
-*/
-INT RTMPGetKeyParameterWithOffset(
-    IN  PCHAR   key,
-    OUT PCHAR   dest,
-    OUT	USHORT	*end_offset,
-    IN  INT     destsize,
-    IN  PCHAR   buffer,
-    IN	BOOLEAN	bTrimSpace)
-{
-    UCHAR *temp_buf1 = NULL;
-    UCHAR *temp_buf2 = NULL;
-    CHAR *start_ptr;
-    CHAR *end_ptr;
-    CHAR *ptr;
-    CHAR *offset = 0;
-    INT  len;
-
-	if (*end_offset >= MAX_INI_BUFFER_SIZE)
-		return (FALSE);
-
-	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
-
-	if(temp_buf1 == NULL)
-        return (FALSE);
-
-	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
-	if(temp_buf2 == NULL)
-	{
-		os_free_mem(NULL, temp_buf1);
-        return (FALSE);
 	}
 
-    //find section
-	if(*end_offset == 0)
+	if (src && *src)
     {
-		if ((offset = RTMPFindSection(buffer)) == NULL)
+		RtmpOSFSInfoChange(&osFSInfo, TRUE);
+		srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
+		if (IS_FILE_OPEN_ERR(srcf))
 		{
-			os_free_mem(NULL, temp_buf1);
-	    	os_free_mem(NULL, temp_buf2);
-    	    return (FALSE);
-		}
+			DBGPRINT(RT_DEBUG_ERROR, ("Open file \"%s\" failed!\n", src));
     }
 	else
-		offset = buffer + (*end_offset);
-
-    strcpy(temp_buf1, "\n");
-    strcat(temp_buf1, key);
-    strcat(temp_buf1, "=");
-
-    //search key
-    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
     {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    start_ptr+=strlen("\n");
-    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
-       end_ptr=start_ptr+strlen(start_ptr);
-
-    if (end_ptr<start_ptr)
+			retval =RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE);
+			if (retval > 0)
     {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
+				RTMPSetProfileParameters(pAd, buffer);
+				retval = NDIS_STATUS_SUCCESS;
     }
-
-	*end_offset = end_ptr - buffer;
-
-    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
-    temp_buf2[end_ptr-start_ptr]='\0';
-    len = strlen(temp_buf2);
-    strcpy(temp_buf1, temp_buf2);
-    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
-    {
-		os_free_mem(NULL, temp_buf1);
-    	os_free_mem(NULL, temp_buf2);
-        return (FALSE);
-    }
-
-    strcpy(temp_buf2, start_ptr+1);
-    ptr = temp_buf2;
-    //trim space or tab
-    while(*ptr != 0x00)
-    {
-        if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
-            ptr++;
-        else
-           break;
-    }
-
-    len = strlen(ptr);
-    memset(dest, 0x00, destsize);
-    strncpy(dest, ptr, len >= destsize ?  destsize: len);
-
-	os_free_mem(NULL, temp_buf1);
-    os_free_mem(NULL, temp_buf2);
-    return TRUE;
-}
-
-
-static int rtmp_parse_key_buffer_from_file(IN  PRTMP_ADAPTER pAd,IN  char *buffer,IN  ULONG KeyType,IN  INT BSSIdx,IN  INT KeyIdx)
-{
-	PUCHAR		keybuff;
-	INT			i = BSSIdx, idx = KeyIdx;
-	ULONG		KeyLen;
-	UCHAR		CipherAlg = CIPHER_WEP64;
-
-	keybuff = buffer;
-	KeyLen = strlen(keybuff);
-
-	if (KeyType == 1)
-	{//Ascii
-		if( (KeyLen == 5) || (KeyLen == 13))
-		{
-			pAd->SharedKey[i][idx].KeyLen = KeyLen;
-			NdisMoveMemory(pAd->SharedKey[i][idx].Key, keybuff, KeyLen);
-			if (KeyLen == 5)
-				CipherAlg = CIPHER_WEP64;
-			else
-				CipherAlg = CIPHER_WEP128;
-			pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("I/F(wlan%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
-			return 1;
-		}
-		else
-		{//Invalid key length
-			DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length! KeyLen = %ld!\n", idx+1, KeyLen));
-			return 0;
-		}
-	}
-	else
-	{//Hex type
-		if( (KeyLen == 10) || (KeyLen == 26))
-		{
-			pAd->SharedKey[i][idx].KeyLen = KeyLen / 2;
-			AtoH(keybuff, pAd->SharedKey[i][idx].Key, KeyLen / 2);
-			if (KeyLen == 10)
-				CipherAlg = CIPHER_WEP64;
-			else
-				CipherAlg = CIPHER_WEP128;
-			pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("I/F(wlan%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
-			return 1;
-		}
-		else
-		{//Invalid key length
-			DBGPRINT(RT_DEBUG_ERROR, ("I/F(wlan%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen));
-			return 0;
-		}
-	}
-}
-static void rtmp_read_key_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
-{
-	char		tok_str[16];
-	PUCHAR		macptr;
-	INT			i = 0, idx;
-	ULONG		KeyType[MAX_MBSSID_NUM];
-	ULONG		KeyIdx;
-
-	NdisZeroMemory(KeyType, MAX_MBSSID_NUM);
-
-	//DefaultKeyID
-	if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer))
-	{
-		{
-			KeyIdx = simple_strtol(tmpbuf, 0, 10);
-			if((KeyIdx >= 1 ) && (KeyIdx <= 4))
-				pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
-			else
-				pAd->StaCfg.DefaultKeyId = 0;
-
-			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
-		}
-	}
-
-
-	for (idx = 0; idx < 4; idx++)
-	{
-		sprintf(tok_str, "Key%dType", idx + 1);
-		//Key1Type
-		if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer))
-		{
-		    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-		    {
-			    KeyType[i] = simple_strtol(macptr, 0, 10);
-		    }
-
-			{
-				sprintf(tok_str, "Key%dStr", idx + 1);
-				if (RTMPGetCriticalParameter(tok_str, tmpbuf, 128, buffer))
-				{
-					rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
-				}
-			}
-		}
-	}
-}
-
-static void rtmp_read_sta_wmm_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
-{
-	PUCHAR					macptr;
-	INT						i=0;
-	BOOLEAN					bWmmEnable = FALSE;
-
-	//WmmCapable
-	if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer))
-	{
-		if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
-		{
-			pAd->CommonCfg.bWmmCapable = TRUE;
-			bWmmEnable = TRUE;
-		}
-		else //Disable
-		{
-			pAd->CommonCfg.bWmmCapable = FALSE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
-	}
-
-	//AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
-	if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer))
-	{
-		for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-		{
-			pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
-
-			DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
-		}
-	}
-
-	if (bWmmEnable)
-	{
-		//APSDCapable
-		if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer))
-		{
-			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-				pAd->CommonCfg.bAPSDCapable = TRUE;
 			else
-				pAd->CommonCfg.bAPSDCapable = FALSE;
+				DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
 
-			DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
-		}
-
-		//APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
-		if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer))
+			retval = RtmpOSFileClose(srcf);
+			if ( retval != 0)
 		{
-			BOOLEAN apsd_ac[4];
-
-			for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-			{
-				apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
-
-				DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d  %d\n", i,  apsd_ac[i]));
-			}
-
-			pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
-			pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
-			pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
-			pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
+				retval = NDIS_STATUS_FAILURE;
+				DBGPRINT(RT_DEBUG_ERROR, ("Close file \"%s\" failed(errCode=%d)!\n", src, retval));
 		}
 	}
 
-}
-
-NDIS_STATUS	RTMPReadParametersHook(
-	IN	PRTMP_ADAPTER pAd)
-{
-	PUCHAR					src = NULL;
-	struct file				*srcf;
-	INT 					retval;
-   	mm_segment_t			orgfs;
-	CHAR					*buffer;
-	CHAR					*tmpbuf;
-	ULONG					RtsThresh;
-	ULONG					FragThresh;
-	UCHAR	                keyMaterial[40];
-
-	PUCHAR					macptr;
-	INT						i = 0;
-
-	buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	if(buffer == NULL)
-        return NDIS_STATUS_FAILURE;
-
-	tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
-	if(tmpbuf == NULL)
-	{
-		kfree(buffer);
-        return NDIS_STATUS_FAILURE;
-	}
-
-	src = STA_PROFILE_PATH;
-
-    orgfs = get_fs();
-    set_fs(KERNEL_DS);
-
-	if (src && *src)
-	{
-		srcf = filp_open(src, O_RDONLY, 0);
-		if (IS_ERR(srcf))
-		{
-			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
-		}
-		else
-		{
-			// The object must have a read method
-			if (srcf->f_op && srcf->f_op->read)
-			{
-				memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
-				retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
-				if (retval < 0)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
-				}
-				else
-				{
-					// set file parameter to portcfg
-					//CountryRegion
-					if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer))
-					{
-						pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
-					}
-					//CountryRegionABand
-					if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer))
-					{
-						pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
-					}
-					//CountryCode
-					if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer))
-					{
-						NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
-
-						if (strlen(pAd->CommonCfg.CountryCode) != 0)
-						{
-							pAd->CommonCfg.bCountryFlag = TRUE;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
-					}
-					//ChannelGeography
-					if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer))
-					{
-						UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-						if (Geography <= BOTH)
-						{
-							pAd->CommonCfg.Geography = Geography;
-							pAd->CommonCfg.CountryCode[2] =
-								(pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
-							DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
-						}
-					}
-					else
-					{
-						pAd->CommonCfg.Geography = BOTH;
-						pAd->CommonCfg.CountryCode[2] = ' ';
-					}
-
-					{
-						//SSID
-						if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer))
-						{
-							if (strlen(tmpbuf) <= 32)
-							{
-			 					pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
-								NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
-								NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
-								pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
-								NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
-								NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
-								pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
-								NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
-								NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
-								DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __func__, tmpbuf));
-							}
-						}
-					}
-
-					{
-						//NetworkType
-						if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer))
-						{
-							pAd->bConfigChanged = TRUE;
-							if (strcmp(tmpbuf, "Adhoc") == 0)
-								pAd->StaCfg.BssType = BSS_ADHOC;
-							else //Default Infrastructure mode
-								pAd->StaCfg.BssType = BSS_INFRA;
-							// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
-							pAd->StaCfg.WpaState = SS_NOTUSE;
-							DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __func__, pAd->StaCfg.BssType));
-						}
-					}
-
-					//Channel
-					if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer))
-					{
-						pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
-					}
-					//WirelessMode
-					if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer))
-					{
-						int value  = 0, maxPhyMode = PHY_11G;
-
-						maxPhyMode = PHY_11N_5G;
-
-						value = simple_strtol(tmpbuf, 0, 10);
-
-						if (value <= maxPhyMode)
-						{
-							pAd->CommonCfg.PhyMode = value;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
-					}
-                    //BasicRate
-					if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer))
-					{
-						pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
-					}
-					//BeaconPeriod
-					if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer))
-					{
-						pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
-						DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
-					}
-                    //TxPower
-					if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer))
-					{
-						pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
-
-						pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
-
-						DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
-					}
-					//BGProtection
-					if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer))
-					{
-						switch (simple_strtol(tmpbuf, 0, 10))
-						{
-							case 1: //Always On
-								pAd->CommonCfg.UseBGProtection = 1;
-								break;
-							case 2: //Always OFF
-								pAd->CommonCfg.UseBGProtection = 2;
-								break;
-							case 0: //AUTO
-							default:
-								pAd->CommonCfg.UseBGProtection = 0;
-								break;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
-					}
-					//OLBCDetection
-					if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer))
-					{
-						switch (simple_strtol(tmpbuf, 0, 10))
-						{
-							case 1: //disable OLBC Detection
-								pAd->CommonCfg.DisableOLBCDetect = 1;
-								break;
-							case 0: //enable OLBC Detection
-								pAd->CommonCfg.DisableOLBCDetect = 0;
-								break;
-							default:
-								pAd->CommonCfg.DisableOLBCDetect= 0;
-								break;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
-					}
-					//TxPreamble
-					if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer))
-					{
-						switch (simple_strtol(tmpbuf, 0, 10))
-						{
-							case Rt802_11PreambleShort:
-								pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
-								break;
-							case Rt802_11PreambleLong:
-							default:
-								pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
-								break;
-						}
-						DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
-					}
-					//RTSThreshold
-					if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer))
-					{
-						RtsThresh = simple_strtol(tmpbuf, 0, 10);
-						if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
-							pAd->CommonCfg.RtsThreshold  = (USHORT)RtsThresh;
-						else
-							pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
-
-						DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
-					}
-					//FragThreshold
-					if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer))
-					{
-						FragThresh = simple_strtol(tmpbuf, 0, 10);
-						pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
-
-						if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
-						{ //illegal FragThresh so we set it to default
-							pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
-							pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
-						}
-						else if (FragThresh % 2 == 1)
-						{
-							// The length of each fragment shall always be an even number of octets, except for the last fragment
-							// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
-							pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
-						}
-						else
-						{
-							pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
-						}
-						//pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
-						DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
-					}
-					//TxBurst
-					if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer))
-					{
-						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-							pAd->CommonCfg.bEnableTxBurst = TRUE;
-						else //Disable
-							pAd->CommonCfg.bEnableTxBurst = FALSE;
-						DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
-					}
-
-#ifdef AGGREGATION_SUPPORT
-					//PktAggregate
-					if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
-					{
-						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-							pAd->CommonCfg.bAggregationCapable = TRUE;
-						else //Disable
-							pAd->CommonCfg.bAggregationCapable = FALSE;
-#ifdef PIGGYBACK_SUPPORT
-						pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
-#endif // PIGGYBACK_SUPPORT //
-						DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
-					}
-#else
-					pAd->CommonCfg.bAggregationCapable = FALSE;
-					pAd->CommonCfg.bPiggyBackCapable = FALSE;
-#endif // AGGREGATION_SUPPORT //
-
-					// WmmCapable
-					rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
-
-					//ShortSlot
-					if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
-					{
-						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
-							pAd->CommonCfg.bUseShortSlotTime = TRUE;
-						else //Disable
-							pAd->CommonCfg.bUseShortSlotTime = FALSE;
-
-						DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
-					}
-					//IEEE80211H
-					if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
-					{
-					    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
-					    {
-    						if(simple_strtol(macptr, 0, 10) != 0)  //Enable
-    							pAd->CommonCfg.bIEEE80211H = TRUE;
-    						else //Disable
-    							pAd->CommonCfg.bIEEE80211H = FALSE;
-
-    						DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
-					    }
-					}
-					//CSPeriod
-					if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
-					{
-					    if(simple_strtol(tmpbuf, 0, 10) != 0)
-							pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
-						else
-							pAd->CommonCfg.RadarDetect.CSPeriod = 0;
-
-   						DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
-					}
-
-					//RDRegion
-					if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
-					{
-						if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
-						}
-						else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-						}
-						else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
-						}
-						else  if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
-						}
-						else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-						}
-						else
-						{
-							pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
-							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-						}
-
-						DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
-					}
-					else
-					{
-						pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
-						pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
-					}
-
-					//WirelessEvent
-					if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
-					{
-					    if(simple_strtol(tmpbuf, 0, 10) != 0)
-							pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
-						else
-							pAd->CommonCfg.bWirelessEvent = 0;	// disable
-   						DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
-					}
-					if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
-					{
-					    if(simple_strtol(tmpbuf, 0, 10) != 0)
-							pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
-						else
-							pAd->CommonCfg.bWiFiTest = 0;	// disable
-
-   						DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
-					}
-					//AuthMode
-					if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
-					{
-						{
-							if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
-							else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-							else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
-							else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
-							else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
-							else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
-							else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
-							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
-				                        else
-				                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-
-				                        pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-
-							DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
-						}
-					}
-					//EncrypType
-					if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
-					{
-						{
-							if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
-								pAd->StaCfg.WepStatus	= Ndis802_11WEPEnabled;
-							else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
-								pAd->StaCfg.WepStatus	= Ndis802_11Encryption2Enabled;
-							else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
-								pAd->StaCfg.WepStatus	= Ndis802_11Encryption3Enabled;
-							else
-								pAd->StaCfg.WepStatus	= Ndis802_11WEPDisabled;
-
-							// Update all wepstatus related
-							pAd->StaCfg.PairCipher		= pAd->StaCfg.WepStatus;
-							pAd->StaCfg.GroupCipher 	= pAd->StaCfg.WepStatus;
-							pAd->StaCfg.OrigWepStatus 	= pAd->StaCfg.WepStatus;
-							pAd->StaCfg.bMixCipher 		= FALSE;
-
-							DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
-						}
-					}
-
-					{
-						if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
-						{
-							int     err=0;
-
-							tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
-
-							if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
-								(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-								(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
-								)
-							{
-								err = 1;
-							}
-							else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
-							{
-								PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
-								NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
-
-							}
-							else if (strlen(tmpbuf) == 64)
-							{
-								AtoH(tmpbuf, keyMaterial, 32);
-								NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
-							}
-							else
-							{
-								err = 1;
-								DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __func__));
-							}
-
-							if (err == 0)
-	                        			{
-	                        				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-									(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-								{
-									// Start STA supplicant state machine
-									pAd->StaCfg.WpaState = SS_START;
-								}
-								else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-								{
-									pAd->StaCfg.WpaState = SS_NOTUSE;
-								}
-
-								DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __func__, tmpbuf));
-							}
-						}
-					}
-
-					//DefaultKeyID, KeyType, KeyStr
-					rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
-
-					HTParametersHook(pAd, tmpbuf, buffer);
-
-					{
-						//PSMode
-#ifdef RT2860
-						if (RTMPGetKeyParameter("PSMode", tmpbuf, 32, buffer))
-#endif
-#ifdef RT2870
-						if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
-#endif
-						{
-							if (pAd->StaCfg.BssType == BSS_INFRA)
-							{
-								if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
-								{
-									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-									// to exclude certain situations.
-									//	   MlmeSetPsm(pAd, PWR_SAVE);
-									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
-									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
-									pAd->StaCfg.DefaultListenCount = 5;
-								}
-								else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
-									|| (strcmp(tmpbuf, "FAST_PSP") == 0))
-								{
-									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-									// to exclude certain situations.
-									//	   MlmeSetPsmBit(pAd, PWR_SAVE);
-									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
-									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
-									pAd->StaCfg.DefaultListenCount = 3;
-								}
-								else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
-									|| (strcmp(tmpbuf, "LEGACY_PSP") == 0))
-								{
-									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
-									// to exclude certain situations.
-									//	   MlmeSetPsmBit(pAd, PWR_SAVE);
-									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
-									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
-									pAd->StaCfg.DefaultListenCount = 3;
-								}
-								else
-								{ //Default Ndis802_11PowerModeCAM
-									// clear PSM bit immediately
-									MlmeSetPsmBit(pAd, PWR_ACTIVE);
-									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
-										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
-									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
-								}
-								DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
-							}
-						}
-						// FastRoaming
-						if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
-						{
-							if (simple_strtol(tmpbuf, 0, 10) == 0)
-								pAd->StaCfg.bFastRoaming = FALSE;
-							else
-								pAd->StaCfg.bFastRoaming = TRUE;
-
-							DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
-						}
-						// RoamThreshold
-						if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
-						{
-							long lInfo = simple_strtol(tmpbuf, 0, 10);
-
-							if (lInfo > 90 || lInfo < 60)
-								pAd->StaCfg.dBmToRoam = -70;
-							else
-								pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
-
-							DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d  dBm\n", pAd->StaCfg.dBmToRoam));
-						}
-
-						if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
-						{
-							if(simple_strtol(tmpbuf, 0, 10) == 0)
-								pAd->StaCfg.bTGnWifiTest = FALSE;
-							else
-								pAd->StaCfg.bTGnWifiTest = TRUE;
-								DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
-						}
-					}
-				}
-			}
-			else
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
-			}
-
-			retval=filp_close(srcf,NULL);
-
-			if (retval)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
-			}
-		}
+		RtmpOSFSInfoChange(&osFSInfo, FALSE);
 	}
 
-	set_fs(orgfs);
-
 	kfree(buffer);
-	kfree(tmpbuf);
-
-	return (NDIS_STATUS_SUCCESS);
-}
-
-static void	HTParametersHook(
-	IN	PRTMP_ADAPTER pAd,
-	IN	CHAR		  *pValueStr,
-	IN	CHAR		  *pInput)
-{
-
-	INT Value;
-
-    if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bHTProtect = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bHTProtect = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
 
-    if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bMIMOPSEnable = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bMIMOPSEnable = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-
-    if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value > MMPS_ENABLE)
-        {
-			pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
-        }
-        else
-        {
-            //TODO: add mimo power saving mechanism
-            pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
-			//pAd->CommonCfg.BACapability.field.MMPSmode = Value;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode  = %d\n", Value));
-    }
-
-    if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bBADecline = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bBADecline = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-
-    if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.bDisableReordering = FALSE;
-        }
-        else
-        {
-            pAd->CommonCfg.bDisableReordering = TRUE;
-        }
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-    if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
-    {
-        Value = simple_strtol(pValueStr, 0, 10);
-        if (Value == 0)
-        {
-            pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-	    pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
-        }
-        else
-        {
-            pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
-	    pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-        }
-        pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
-	pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
-        DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA  = %s\n", (Value==0) ? "Disable" : "Enable"));
-    }
-
-	// Tx_+HTC frame
-    if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->HTCEnable = FALSE;
-		}
-		else
-		{
-            		pAd->HTCEnable = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
-	}
-
-	// Enable HT Link Adaptation Control
-	if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->bLinkAdapt = FALSE;
-		}
-		else
-		{
-			pAd->HTCEnable = TRUE;
-			pAd->bLinkAdapt = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
-	}
-
-	// Reverse Direction Mechanism
-    if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.bRdg = FALSE;
-		}
-		else
-		{
-			pAd->HTCEnable = TRUE;
-            pAd->CommonCfg.bRdg = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
-	}
-
-
-
-
-	// Tx A-MSUD ?
-    if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
-		}
-		else
-		{
-            pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
-	}
-
-	// MPDU Density
-    if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value <=7 && Value >= 0)
-		{
-			pAd->CommonCfg.BACapability.field.MpduDensity = Value;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
-		}
-		else
-		{
-			pAd->CommonCfg.BACapability.field.MpduDensity = 4;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
-		}
-	}
-
-	// Max Rx BA Window Size
-    if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value >=1 && Value <= 64)
-		{
-			pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
-			pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
-		}
-		else
-		{
-            pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
-			pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
-			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
-		}
-
-	}
-
-	// Guard Interval
-	if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == GI_400)
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
-		}
-		else
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
-	}
-
-	// HT Operation Mode : Mixed Mode , Green Field
-	if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == HTMODE_GF)
-		{
-
-			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_GF;
-		}
-		else
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_MM;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
-	}
-
-	// Fixed Tx mode : CCK, OFDM
-	if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
-	{
-		UCHAR	fix_tx_mode;
-
-		{
-			fix_tx_mode = FIXED_TXMODE_HT;
-
-			if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
-			{
-				fix_tx_mode = FIXED_TXMODE_OFDM;
-			}
-			else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
-			{
-		        fix_tx_mode = FIXED_TXMODE_CCK;
-			}
-			else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
-			{
-		        fix_tx_mode = FIXED_TXMODE_HT;
-		}
-		else
-		{
-				Value = simple_strtol(pValueStr, 0, 10);
-				// 1 : CCK
-				// 2 : OFDM
-				// otherwise : HT
-				if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
-					fix_tx_mode = Value;
-				else
-					fix_tx_mode = FIXED_TXMODE_HT;
-		}
-
-			pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
-			DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
-
-		}
-	}
-
-
-	// Channel Width
-	if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == BW_40)
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_40;
-		}
-		else
-		{
-            pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
-		}
-
-#ifdef MCAST_RATE_SPECIFIC
-		pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
-#endif // MCAST_RATE_SPECIFIC //
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
-	}
-
-	if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-
-		if (Value == 0)
-		{
-
-			pAd->CommonCfg.RegTransmitSetting.field.EXTCHA  = EXTCHA_BELOW;
-		}
-		else
-		{
-            pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
-	}
-
-	// MSC
-	if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
-	{
-		{
-			Value = simple_strtol(pValueStr, 0, 10);
-
-			if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
-		{
-				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = Value;
-				pAd->StaCfg.bAutoTxRateSwitch = FALSE;
-				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
-		}
-		else
-		{
-				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = MCS_AUTO;
-				pAd->StaCfg.bAutoTxRateSwitch = TRUE;
-				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
-		}
-	}
-	}
-
-	// STBC
-    if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == STBC_USE)
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
-		}
-		else
-		{
-			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
-	}
-
-	// 40_Mhz_Intolerant
-	if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
-	{
-		Value = simple_strtol(pValueStr, 0, 10);
-		if (Value == 0)
-		{
-			pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
-		}
-		else
-		{
-			pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
-	}
-	//HT_TxStream
-	if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
-	{
-		switch (simple_strtol(pValueStr, 0, 10))
-		{
-			case 1:
-				pAd->CommonCfg.TxStream = 1;
-				break;
-			case 2:
-				pAd->CommonCfg.TxStream = 2;
-				break;
-			case 3: // 3*3
-			default:
-				pAd->CommonCfg.TxStream = 3;
-
-				if (pAd->MACVersion < RALINK_2883_VERSION)
-					pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
-				break;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
-	}
-	//HT_RxStream
-	if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
-	{
-		switch (simple_strtol(pValueStr, 0, 10))
-		{
-			case 1:
-				pAd->CommonCfg.RxStream = 1;
-				break;
-			case 2:
-				pAd->CommonCfg.RxStream = 2;
-				break;
-			case 3:
-			default:
-				pAd->CommonCfg.RxStream = 3;
-
-				if (pAd->MACVersion < RALINK_2883_VERSION)
-					pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
-				break;
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
-	}
+	return (retval);
 
 }
+

+ 828 - 0
drivers/staging/rt2860/rt_usb.c

@@ -0,0 +1,828 @@
+/*
+ *************************************************************************
+ * 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:
+	rtusb_bulk.c
+
+	Abstract:
+
+	Revision History:
+	Who			When		What
+	--------	----------	----------------------------------------------
+	Name		Date		Modification logs
+
+*/
+
+#include "rt_config.h"
+
+ void dump_urb(struct urb* purb)
+{
+	printk("urb                  :0x%08lx\n", (unsigned long)purb);
+	printk("\tdev                   :0x%08lx\n", (unsigned long)purb->dev);
+	printk("\t\tdev->state          :0x%d\n", purb->dev->state);
+	printk("\tpipe                  :0x%08x\n", purb->pipe);
+	printk("\tstatus                :%d\n", purb->status);
+	printk("\ttransfer_flags        :0x%08x\n", purb->transfer_flags);
+	printk("\ttransfer_buffer       :0x%08lx\n", (unsigned long)purb->transfer_buffer);
+	printk("\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length);
+	printk("\tactual_length         :%d\n", purb->actual_length);
+	printk("\tsetup_packet          :0x%08lx\n", (unsigned long)purb->setup_packet);
+	printk("\tstart_frame           :%d\n", purb->start_frame);
+	printk("\tnumber_of_packets     :%d\n", purb->number_of_packets);
+	printk("\tinterval              :%d\n", purb->interval);
+	printk("\terror_count           :%d\n", purb->error_count);
+	printk("\tcontext               :0x%08lx\n", (unsigned long)purb->context);
+	printk("\tcomplete              :0x%08lx\n\n", (unsigned long)purb->complete);
+}
+
+/*
+========================================================================
+Routine Description:
+    Create kernel threads & tasklets.
+
+Arguments:
+    *net_dev			Pointer to wireless net device interface
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_FAILURE
+
+Note:
+========================================================================
+*/
+NDIS_STATUS	 RtmpMgmtTaskInit(
+	IN RTMP_ADAPTER *pAd)
+{
+	RTMP_OS_TASK *pTask;
+	NDIS_STATUS status;
+
+	/*
+		Creat TimerQ Thread, We need init timerQ related structure before create the timer thread.
+	*/
+	RtmpTimerQInit(pAd);
+
+	pTask = &pAd->timerTask;
+	RtmpOSTaskInit(pTask, "RtmpTimerTask", pAd);
+	status = RtmpOSTaskAttach(pTask, RtmpTimerQThread, pTask);
+	if (status == NDIS_STATUS_FAILURE)
+	{
+		printk (KERN_WARNING "%s: unable to start RtmpTimerQThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	/* Creat MLME Thread */
+	pTask = &pAd->mlmeTask;
+	RtmpOSTaskInit(pTask, "RtmpMlmeTask", pAd);
+	status = RtmpOSTaskAttach(pTask, MlmeThread, pTask);
+	if (status == NDIS_STATUS_FAILURE)
+	{
+		printk (KERN_WARNING "%s: unable to start MlmeThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	/* Creat Command Thread */
+	pTask = &pAd->cmdQTask;
+	RtmpOSTaskInit(pTask, "RtmpCmdQTask", pAd);
+	status = RtmpOSTaskAttach(pTask, RTUSBCmdThread, pTask);
+	if (status == NDIS_STATUS_FAILURE)
+	{
+		printk (KERN_WARNING "%s: unable to start RTUSBCmdThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
+		return NDIS_STATUS_FAILURE;
+	}
+
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+
+/*
+========================================================================
+Routine Description:
+    Close kernel threads.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+    NONE
+
+Note:
+========================================================================
+*/
+VOID RtmpMgmtTaskExit(
+	IN RTMP_ADAPTER *pAd)
+{
+	INT			ret;
+	RTMP_OS_TASK	*pTask;
+
+	// Sleep 50 milliseconds so pending io might finish normally
+	RTMPusecDelay(50000);
+
+	// We want to wait until all pending receives and sends to the
+	// device object. We cancel any
+	// irps. Wait until sends and receives have stopped.
+	RTUSBCancelPendingIRPs(pAd);
+
+	// We need clear timerQ related structure before exits of the timer thread.
+	RtmpTimerQExit(pAd);
+
+	/* Terminate Mlme Thread */
+	pTask = &pAd->mlmeTask;
+	ret = RtmpOSTaskKill(pTask);
+	if (ret == NDIS_STATUS_FAILURE)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
+					RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName));
+	}
+
+	/* Terminate cmdQ thread */
+	pTask = &pAd->cmdQTask;
+#ifdef KTHREAD_SUPPORT
+	if (pTask->kthread_task)
+#else
+	CHECK_PID_LEGALITY(pTask->taskPID)
+#endif
+	{
+		mb();
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+		mb();
+		//RTUSBCMDUp(pAd);
+		ret = RtmpOSTaskKill(pTask);
+		if (ret == NDIS_STATUS_FAILURE)
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
+					RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName));
+		}
+		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN;
+	}
+
+	/* Terminate timer thread */
+	pTask = &pAd->timerTask;
+	ret = RtmpOSTaskKill(pTask);
+	if (ret == NDIS_STATUS_FAILURE)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
+					RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName));
+	}
+
+
+}
+
+
+static void rtusb_dataout_complete(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	purbb_t				pUrb;
+	POS_COOKIE			pObj;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId;
+	NTSTATUS			Status;
+	unsigned long		IrqFlags;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+	pObj			= (POS_COOKIE) pAd->OS_Cookie;
+	Status			= pUrb->status;
+
+	// Store BulkOut PipeId
+	BulkOutPipeId = pHTTXContext->BulkOutPipeId;
+	pAd->BulkOutDataOneSecCount++;
+
+	//DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
+	//		pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+	pHTTXContext->IRPPending = FALSE;
+	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		pAd->BulkOutComplete++;
+
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+		pAd->Counters8023.GoodTransmits++;
+		//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+		FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
+		//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+
+	}
+	else	// STATUS_OTHER
+	{
+		PUCHAR	pBuf;
+
+		pAd->BulkOutCompleteOther++;
+
+		pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
+
+		if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+									fRTMP_ADAPTER_HALT_IN_PROGRESS |
+									fRTMP_ADAPTER_NIC_NOT_EXIST |
+									fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = BulkOutPipeId;
+			pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
+		}
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
+		//DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
+
+	}
+
+	//
+	// bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
+	// bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
+	//
+	//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+	if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
+		(pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
+		!RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
+	{
+		// Indicate There is data avaliable
+		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+	}
+	//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+	// Always call Bulk routine, even reset bulk.
+	// The protection of rest bulk should be in BulkOut routine
+	RTUSBKickBulkOut(pAd);
+}
+
+
+static void rtusb_null_frame_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER	pAd;
+	PTX_CONTEXT		pNullContext;
+	purbb_t			pUrb;
+	NTSTATUS		Status;
+	unsigned long	irqFlag;
+
+
+	pUrb			= (purbb_t)data;
+	pNullContext	= (PTX_CONTEXT)pUrb->context;
+	pAd			= pNullContext->pAd;
+	Status			= pUrb->status;
+
+	// Reset Null frame context flags
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+	pNullContext->IRPPending	= FALSE;
+	pNullContext->InUse		= FALSE;
+	pAd->BulkOutPending[0] = FALSE;
+	pAd->watchDogTxPendingCnt[0] = 0;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	}
+	else	// STATUS_OTHER
+	{
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+		}
+	}
+
+	// Always call Bulk routine, even reset bulk.
+	// The protectioon of rest bulk should be in BulkOut routine
+	RTUSBKickBulkOut(pAd);
+}
+
+
+static void rtusb_rts_frame_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER	pAd;
+	PTX_CONTEXT		pRTSContext;
+	purbb_t			pUrb;
+	NTSTATUS		Status;
+	unsigned long	irqFlag;
+
+
+	pUrb		= (purbb_t)data;
+	pRTSContext	= (PTX_CONTEXT)pUrb->context;
+	pAd			= pRTSContext->pAd;
+	Status		= pUrb->status;
+
+	// Reset RTS frame context flags
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+	pRTSContext->IRPPending = FALSE;
+	pRTSContext->InUse		= FALSE;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	}
+	else	// STATUS_OTHER
+	{
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+		}
+	}
+
+	RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+	pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
+	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+
+	// Always call Bulk routine, even reset bulk.
+	// The protectioon of rest bulk should be in BulkOut routine
+	RTUSBKickBulkOut(pAd);
+
+
+}
+
+
+static void rtusb_pspoll_frame_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER	pAd;
+	PTX_CONTEXT		pPsPollContext;
+	purbb_t			pUrb;
+	NTSTATUS		Status;
+
+
+
+	pUrb			= (purbb_t)data;
+	pPsPollContext	= (PTX_CONTEXT)pUrb->context;
+	pAd				= pPsPollContext->pAd;
+	Status			= pUrb->status;
+
+	// Reset PsPoll context flags
+	pPsPollContext->IRPPending	= FALSE;
+	pPsPollContext->InUse		= FALSE;
+	pAd->watchDogTxPendingCnt[0] = 0;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	}
+	else // STATUS_OTHER
+	{
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+	}
+
+	RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
+	pAd->BulkOutPending[0] = FALSE;
+	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
+
+	// Always call Bulk routine, even reset bulk.
+	// The protectioon of rest bulk should be in BulkOut routine
+	RTUSBKickBulkOut(pAd);
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Handle received packets.
+
+Arguments:
+	data				- URB information pointer
+
+Return Value:
+    None
+
+Note:
+========================================================================
+*/
+static void rx_done_tasklet(unsigned long data)
+{
+	purbb_t				pUrb;
+	PRX_CONTEXT			pRxContext;
+	PRTMP_ADAPTER		pAd;
+	NTSTATUS			Status;
+	unsigned int		IrqFlags;
+
+	pUrb		= (purbb_t)data;
+	pRxContext	= (PRX_CONTEXT)pUrb->context;
+	pAd		= pRxContext->pAd;
+	Status = pUrb->status;
+
+
+	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+	pRxContext->InUse = FALSE;
+	pRxContext->IRPPending = FALSE;
+	pRxContext->BulkInOffset += pUrb->actual_length;
+	//NdisInterlockedDecrement(&pAd->PendingRx);
+	pAd->PendingRx--;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		pAd->BulkInComplete++;
+		pAd->NextRxBulkInPosition = 0;
+		if (pRxContext->BulkInOffset)	// As jan's comment, it may bulk-in success but size is zero.
+		{
+			pRxContext->Readable = TRUE;
+			INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
+		}
+		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+	}
+	else	 // STATUS_OTHER
+	{
+		pAd->BulkInCompleteFail++;
+		// Still read this packet although it may comtain wrong bytes.
+		pRxContext->Readable = FALSE;
+		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+		// Parsing all packets. because after reset, the index will reset to all zero.
+		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+									fRTMP_ADAPTER_BULKIN_RESET |
+									fRTMP_ADAPTER_HALT_IN_PROGRESS |
+									fRTMP_ADAPTER_NIC_NOT_EXIST))))
+		{
+
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
+							Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
+
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
+		}
+	}
+
+	ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+
+	RTUSBBulkReceive(pAd);
+
+
+	return;
+
+}
+
+
+static void rtusb_mgmt_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER	pAd;
+	PTX_CONTEXT		pMLMEContext;
+	int				index;
+	PNDIS_PACKET	pPacket;
+	purbb_t			pUrb;
+	NTSTATUS		Status;
+	unsigned long	IrqFlags;
+
+
+	pUrb			= (purbb_t)data;
+	pMLMEContext	= (PTX_CONTEXT)pUrb->context;
+	pAd			= pMLMEContext->pAd;
+	Status			= pUrb->status;
+	index			= pMLMEContext->SelfIdx;
+
+	ASSERT((pAd->MgmtRing.TxDmaIdx == index));
+
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+
+	if (Status != USB_ST_NOERROR)
+	{
+		//Bulk-Out fail status handle
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
+			// TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+		}
+	}
+
+	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+	// Reset MLME context flags
+	pMLMEContext->IRPPending = FALSE;
+	pMLMEContext->InUse = FALSE;
+	pMLMEContext->bWaitingBulkOut = FALSE;
+	pMLMEContext->BulkOutSize = 0;
+
+	pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
+	pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
+
+	// Increase MgmtRing Index
+	INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
+	pAd->MgmtRing.TxSwFreeIdx++;
+	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+	// No-matter success or fail, we free the mgmt packet.
+	if (pPacket)
+		RTMPFreeNdisPacket(pAd, pPacket);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
+			((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
+		{	// For Mgmt Bulk-Out failed, ignore it now.
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{
+
+			// Always call Bulk routine, even reset bulk.
+			// The protectioon of rest bulk should be in BulkOut routine
+			if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
+			{
+				RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+			}
+				RTUSBKickBulkOut(pAd);
+			}
+		}
+
+
+}
+
+static void rtusb_ac3_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId = 3;
+	purbb_t				pUrb;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+
+	rtusb_dataout_complete((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+		{
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+				(pHTTXContext->bCurWriting == FALSE))
+			{
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+
+	return;
+}
+
+
+static void rtusb_ac2_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId = 2;
+	purbb_t				pUrb;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+
+	rtusb_dataout_complete((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+		{
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+				(pHTTXContext->bCurWriting == FALSE))
+			{
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+
+	return;
+}
+
+
+static void rtusb_ac1_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId = 1;
+	purbb_t				pUrb;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+
+	rtusb_dataout_complete((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+		{
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+				(pHTTXContext->bCurWriting == FALSE))
+			{
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+	return;
+
+}
+
+
+static void rtusb_ac0_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId = 0;
+	purbb_t				pUrb;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+
+	rtusb_dataout_complete((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+		{
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+				/*  ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+				(pHTTXContext->bCurWriting == FALSE))
+			{
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+
+	return;
+
+}
+
+
+NDIS_STATUS RtmpNetTaskInit(
+	IN RTMP_ADAPTER *pAd)
+{
+	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	// Create receive tasklet
+	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
+	tasklet_init(&pObj->mgmt_dma_done_task, rtusb_mgmt_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac0_dma_done_task, rtusb_ac0_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac1_dma_done_task, rtusb_ac1_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac2_dma_done_task, rtusb_ac2_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac3_dma_done_task, rtusb_ac3_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->null_frame_complete_task, rtusb_null_frame_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->rts_frame_complete_task, rtusb_rts_frame_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->pspoll_frame_complete_task, rtusb_pspoll_frame_done_tasklet, (unsigned long)pAd);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+void RtmpNetTaskExit(IN RTMP_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->tbtt_task);
+	tasklet_kill(&pObj->null_frame_complete_task);
+	tasklet_kill(&pObj->rts_frame_complete_task);
+	tasklet_kill(&pObj->pspoll_frame_complete_task);
+}

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 122 - 704
drivers/staging/rt2860/rtmp.h


+ 265 - 0
drivers/staging/rt2860/rtmp_chip.h

@@ -0,0 +1,265 @@
+/*
+ *************************************************************************
+ * 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_chip.h
+
+	Abstract:
+	Ralink Wireless Chip related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+*/
+
+#ifndef	__RTMP_CHIP_H__
+#define	__RTMP_CHIP_H__
+
+#include "rtmp_type.h"
+
+#ifdef RT2860
+#include "chip/rt2860.h"
+#endif // RT2860 //
+#ifdef RT2870
+#include "chip/rt2870.h"
+#endif // RT2870 //
+#ifdef RT3070
+#include "chip/rt3070.h"
+#endif // RT3070 //
+
+// We will have a cost down version which mac version is 0x3090xxxx
+//
+// RT3090A facts
+//
+// a) 2.4 GHz
+// b) Replacement for RT3090
+// c) Internal LNA
+// d) Interference over channel #14
+// e) New BBP features (e.g., SIG re-modulation)
+//
+#define IS_RT3090A(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
+
+// We will have a cost down version which mac version is 0x3090xxxx
+#define IS_RT3090(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (IS_RT3090A(_pAd)))
+
+#define IS_RT3070(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
+#define IS_RT3071(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
+#define IS_RT2070(_pAd)		(((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27))
+
+#define IS_RT30xx(_pAd)		(((_pAd)->MACVersion & 0xfff00000) == 0x30700000||IS_RT3090A(_pAd))
+//#define IS_RT305X(_pAd)		((_pAd)->MACVersion == 0x28720200)
+
+/* RT3572, 3592, 3562, 3062 share the same MAC version */
+#define IS_RT3572(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x35720000)
+#define IS_VERSION_BEFORE_F(_pAd)			(((_pAd)->MACVersion&0xffff) <= 0x0211)
+// F version is 0x0212, E version is 0x0211. 309x can save more power after F version.
+#define IS_VERSION_AFTER_F(_pAd)			((((_pAd)->MACVersion&0xffff) >= 0x0212) || (((_pAd)->b3090ESpecialChip == TRUE)))
+//
+// RT3390 facts
+//
+// a) Base on RT3090 (RF IC: RT3020)
+// b) 2.4 GHz
+// c) 1x1
+// d) Single chip
+// e) Internal components: PA and LNA
+//
+//RT3390,RT3370
+#define IS_RT3390(_pAd)				(((_pAd)->MACVersion & 0xFFFF0000) == 0x33900000)
+
+// ------------------------------------------------------
+// PCI registers - base address 0x0000
+// ------------------------------------------------------
+#define CHIP_PCI_CFG		0x0000
+#define CHIP_PCI_EECTRL		0x0004
+#define CHIP_PCI_MCUCTRL	0x0008
+
+#define OPT_14			0x114
+
+#define RETRY_LIMIT		10
+
+
+
+// ------------------------------------------------------
+// BBP & RF	definition
+// ------------------------------------------------------
+#define	BUSY		                1
+#define	IDLE		                0
+
+
+//-------------------------------------------------------------------------
+// EEPROM definition
+//-------------------------------------------------------------------------
+#define EEDO                        0x08
+#define EEDI                        0x04
+#define EECS                        0x02
+#define EESK                        0x01
+#define EERL                        0x80
+
+#define EEPROM_WRITE_OPCODE         0x05
+#define EEPROM_READ_OPCODE          0x06
+#define EEPROM_EWDS_OPCODE          0x10
+#define EEPROM_EWEN_OPCODE          0x13
+
+#define NUM_EEPROM_BBP_PARMS		19			// Include NIC Config 0, 1, CR, TX ALC step, BBPs
+#define NUM_EEPROM_TX_G_PARMS		7
+#define EEPROM_NIC1_OFFSET          0x34		// The address is from NIC config 0, not BBP register ID
+#define EEPROM_NIC2_OFFSET          0x36		// The address is from NIC config 0, not BBP register ID
+#define EEPROM_BBP_BASE_OFFSET		0xf0		// The address is from NIC config 0, not BBP register ID
+#define EEPROM_G_TX_PWR_OFFSET		0x52
+#define EEPROM_G_TX2_PWR_OFFSET		0x60
+#define EEPROM_LED1_OFFSET			0x3c
+#define EEPROM_LED2_OFFSET			0x3e
+#define EEPROM_LED3_OFFSET			0x40
+#define EEPROM_LNA_OFFSET			0x44
+#define EEPROM_RSSI_BG_OFFSET		0x46
+#define EEPROM_TXMIXER_GAIN_2_4G	0x48
+#define EEPROM_RSSI_A_OFFSET		0x4a
+#define EEPROM_TXMIXER_GAIN_5G		0x4c
+#define EEPROM_DEFINE_MAX_TXPWR		0x4e
+#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G	0xde	// 20MHZ 2.4G tx power.
+#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G	0xee	// 40MHZ 2.4G tx power.
+#define EEPROM_TXPOWER_BYRATE_20MHZ_5G		0xfa	// 20MHZ 5G tx power.
+#define EEPROM_TXPOWER_BYRATE_40MHZ_5G		0x10a	// 40MHZ 5G tx power.
+#define EEPROM_A_TX_PWR_OFFSET      0x78
+#define EEPROM_A_TX2_PWR_OFFSET      0xa6
+//#define EEPROM_Japan_TX_PWR_OFFSET      0x90 // 802.11j
+//#define EEPROM_Japan_TX2_PWR_OFFSET      0xbe
+//#define EEPROM_TSSI_REF_OFFSET	0x54
+//#define EEPROM_TSSI_DELTA_OFFSET	0x24
+//#define EEPROM_CCK_TX_PWR_OFFSET  0x62
+//#define EEPROM_CALIBRATE_OFFSET	0x7c
+#define EEPROM_VERSION_OFFSET       0x02
+#define EEPROM_FREQ_OFFSET			0x3a
+#define EEPROM_TXPOWER_BYRATE	0xde	// 20MHZ power.
+#define EEPROM_TXPOWER_DELTA		0x50	// 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
+#define VALID_EEPROM_VERSION        1
+
+
+/*
+  *   EEPROM operation related marcos
+  */
+#define RT28xx_EEPROM_READ16(_pAd, _offset, _value)			\
+	(_pAd)->chipOps.eeread((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (PUSHORT)&(_value))
+
+#define RT28xx_EEPROM_WRITE16(_pAd, _offset, _value)		\
+	(_pAd)->chipOps.eewrite((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (USHORT)(_value))
+
+
+
+// -------------------------------------------------------------------
+//  E2PROM data layout
+// -------------------------------------------------------------------
+
+//
+// MCU_LEDCS: MCU LED Control Setting.
+//
+typedef union  _MCU_LEDCS_STRUC {
+	struct	{
+		UCHAR		LedMode:7;
+		UCHAR		Polarity:1;
+	} field;
+	UCHAR				word;
+} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
+
+
+//
+// EEPROM antenna select format
+//
+typedef	union	_EEPROM_ANTENNA_STRUC	{
+	struct	{
+		USHORT		RxPath:4;	// 1: 1R, 2: 2R, 3: 3R
+		USHORT		TxPath:4;	// 1: 1T, 2: 2T
+		USHORT      RfIcType:4;             // see E2PROM document
+		USHORT      Rsv:4;
+	}	field;
+	USHORT			word;
+}	EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
+
+typedef	union _EEPROM_NIC_CINFIG2_STRUC	{
+	struct {
+		USHORT		HardwareRadioControl:1;	// 1:enable, 0:disable
+		USHORT		DynamicTxAgcControl:1;			//
+		USHORT		ExternalLNAForG:1;				//
+		USHORT		ExternalLNAForA:1;			// external LNA enable for 2.4G
+		USHORT		CardbusAcceleration:1;	// !!! NOTE: 0 - enable, 1 - disable
+		USHORT		BW40MSidebandForG:1;
+		USHORT		BW40MSidebandForA:1;
+		USHORT		EnableWPSPBC:1;                 // WPS PBC Control bit
+		USHORT		BW40MAvailForG:1;			// 0:enable, 1:disable
+		USHORT		BW40MAvailForA:1;			// 0:enable, 1:disable
+		USHORT		Rsv1:1;					// must be 0
+		USHORT		AntDiversity:1;			// Antenna diversity
+		USHORT		Rsv2:3;					// must be 0
+		USHORT		DACTestBit:1;			// control if driver should patch the DAC issue
+	}	field;
+	USHORT			word;
+}	EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
+
+//
+// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
+//
+typedef	union	_EEPROM_TX_PWR_STRUC	{
+	struct	{
+		CHAR	Byte0;				// Low Byte
+		CHAR	Byte1;				// High Byte
+	}	field;
+	USHORT	word;
+}	EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
+
+typedef	union	_EEPROM_VERSION_STRUC	{
+	struct	{
+		UCHAR	FaeReleaseNumber;	// Low Byte
+		UCHAR	Version;			// High Byte
+	}	field;
+	USHORT	word;
+}	EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
+
+typedef	union	_EEPROM_LED_STRUC	{
+	struct	{
+		USHORT	PolarityRDY_G:1;		// Polarity RDY_G setting.
+		USHORT	PolarityRDY_A:1;		// Polarity RDY_A setting.
+		USHORT	PolarityACT:1;		// Polarity ACT setting.
+		USHORT	PolarityGPIO_0:1;	// Polarity GPIO#0 setting.
+		USHORT	PolarityGPIO_1:1;	// Polarity GPIO#1 setting.
+		USHORT	PolarityGPIO_2:1;	// Polarity GPIO#2 setting.
+		USHORT	PolarityGPIO_3:1;	// Polarity GPIO#3 setting.
+		USHORT	PolarityGPIO_4:1;	// Polarity GPIO#4 setting.
+		USHORT	LedMode:5;			// Led mode.
+		USHORT	Rsvd:3;				// Reserved
+	}	field;
+	USHORT	word;
+}	EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
+
+typedef	union	_EEPROM_TXPOWER_DELTA_STRUC	{
+	struct	{
+		UCHAR	DeltaValue:6;	// Tx Power dalta value (MAX=4)
+		UCHAR	Type:1;			// 1: plus the delta value, 0: minus the delta value
+		UCHAR	TxPowerEnable:1;// Enable
+	}	field;
+	UCHAR	value;
+}	EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
+
+#endif	// __RTMP_CHIP_H__ //

+ 144 - 145
drivers/staging/rt2860/rtmp_def.h

@@ -41,6 +41,15 @@
 
 #include "oid.h"
 
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
 //
 //  Debug information verbosity: lower values indicate higher urgency
 //
@@ -54,55 +63,28 @@
 #define NIC_TAG             ((ULONG)'0682')
 #define NIC_DBG_STRING      ("**RT28xx**")
 
+#ifdef RTMP_MAC_USB
+#define TX_RING_SIZE            8 // 1
+#define PRIO_RING_SIZE          8
+#define MGMT_RING_SIZE		32 // PRIO_RING_SIZE
+#define RX_RING_SIZE            8
+#define MAX_TX_PROCESS          4
+#define LOCAL_TXBUF_SIZE        2048
+#endif // RTMP_MAC_USB //
+
+//#define PACKED
+
 #define RALINK_2883_VERSION		((UINT32)0x28830300)
 #define RALINK_2880E_VERSION	((UINT32)0x28720200)
 #define RALINK_3070_VERSION		((UINT32)0x30700200)
 
-//
-// NDIS version in use by the NIC driver.
-// The high byte is the major version. The low byte is the minor version.
-//
-#ifdef  NDIS51_MINIPORT
-#define NIC_DRIVER_VERSION      0x0501
-#else
-#define NIC_DRIVER_VERSION      0x0500
-#endif
-
-//
-// NDIS media type, current is ethernet, change if native wireless supported
-//
-#define NIC_MEDIA_TYPE          NdisMedium802_3
-#define NIC_PCI_HDR_LENGTH      0xe2
-#define NIC_MAX_PACKET_SIZE     2304
-#define NIC_HEADER_SIZE         14
-#define MAX_MAP_REGISTERS_NEEDED 32
-#define MIN_MAP_REGISTERS_NEEDED 2   //Todo: should consider fragment issue.
-
-//
-// interface type, we use PCI
-//
-#define NIC_INTERFACE_TYPE      NdisInterfacePci
-#define NIC_INTERRUPT_MODE      NdisInterruptLevelSensitive
-
-//
-// buffer size passed in NdisMQueryAdapterResources
-// We should only need three adapter resources (IO, interrupt and memory),
-// Some devices get extra resources, so have room for 10 resources
-//                    UF_SIZE   (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))
-
-
-#define NIC_RESOURCE_B//
-// IO space length
-//
-#define NIC_MAP_IOSPACE_LENGTH  sizeof(CSR_STRUC)
-
 #define MAX_RX_PKT_LEN	1520
 
 //
 // Entry number for each DMA descriptor ring
 //
 
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 #define TX_RING_SIZE            64 //64
 #define MGMT_RING_SIZE          128
 #define RX_RING_SIZE            128 //64
@@ -110,15 +92,7 @@
 #define MAX_DMA_DONE_PROCESS    TX_RING_SIZE
 #define MAX_TX_DONE_PROCESS     TX_RING_SIZE //8
 #define LOCAL_TXBUF_SIZE        2
-#endif
-#ifdef RT2870
-#define TX_RING_SIZE            8 // 1
-#define PRIO_RING_SIZE          8
-#define MGMT_RING_SIZE       32 // PRIO_RING_SIZE
-#define RX_RING_SIZE            8
-#define MAX_TX_PROCESS          4
-#define LOCAL_TXBUF_SIZE        2048
-#endif // RT2870 //
+#endif // RTMP_MAC_PCI //
 
 #define MAX_RX_PROCESS          128 //64 //32
 #define NUM_OF_LOCAL_TXBUF      2
@@ -143,16 +117,43 @@
 #define MAX_RX_PROCESS_CNT	(RX_RING_SIZE)
 
 
+/*
+	WMM Note: If memory of your system is not much, please reduce the definition;
+	or when you do WMM test, the queue for low priority AC will be full, i.e.
+	TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in
+	WLAN, maybe no any packet buffer can be got in Ethernet driver.
+
+	Sometimes no packet buffer can be got in Ethernet driver, the system will
+	send flow control packet to the sender to slow down its sending rate.
+	So no WMM can be saw in the air.
+*/
+
+/*
+	Need to use 64 in vxworks for test case WMM A5-T07
+	Two dnlink (10Mbps) from a WMM station to a non-WMM station.
+	If use 256, queue is not enough.
+	And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to
+	clConfig.clNum = RX_RING_SIZE * 4;
+*/
+// TODO: For VxWorks the size is 256. Shall we cahnge the value as 256 for all OS?????
 #define MAX_PACKETS_IN_QUEUE				(512) //(512)    // to pass WMM A5-WPAPSK
+
 #define MAX_PACKETS_IN_MCAST_PS_QUEUE		32
 #define MAX_PACKETS_IN_PS_QUEUE				128	//32
 #define WMM_NUM_OF_AC                       4  /* AC0, AC1, AC2, and AC3 */
 
+
+#ifdef RTMP_EFUSE_SUPPORT
+//2008/09/11:KH add to support efuse<--
 #define MAX_EEPROM_BIN_FILE_SIZE					1024
+#define EFUSE_BUFFER_PATH						"/tmp/RT30xxEEPROM.bin"
+//2008/09/11:KH add to support efuse-->
+#endif // RTMP_EFUSE_SUPPORT //
 
 // RxFilter
 #define STANORMAL	 0x17f97
 #define APNORMAL	 0x15f97
+#define PSPXLINK	 0x17f93
 //
 //  RTMP_ADAPTER flags
 //
@@ -203,9 +204,9 @@
 #define fOP_STATUS_TX_AMSDU_INUSED			0x00002000
 #define fOP_STATUS_MAX_RETRY_ENABLED		0x00004000
 #define fOP_STATUS_WAKEUP_NOW               0x00008000
-#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE       0x00020000
+#define fOP_STATUS_PCIE_DEVICE       0x00020000
+#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE fOP_STATUS_PCIE_DEVICE
 
-#ifdef RT2860
 //
 //  RTMP_ADAPTER PSFlags : related to advanced power save.
 //
@@ -218,7 +219,8 @@
 // Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which  doesn't indicate unicate nor multicast packets for me
 //. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine.
 #define fRTMP_PS_GO_TO_SLEEP_NOW         0x00000008
-#endif
+#define fRTMP_PS_TOGGLE_L1		0x00000010	// Use Toggle L1 mechanism for rt28xx PCIe
+
 
 #define CCKSETPROTECT		0x1
 #define OFDMSETPROTECT		0x2
@@ -266,6 +268,7 @@
 #define fRX_FILTER_ACCEPT_MULTICAST         NDIS_PACKET_TYPE_MULTICAST
 #define fRX_FILTER_ACCEPT_BROADCAST         NDIS_PACKET_TYPE_BROADCAST
 #define fRX_FILTER_ACCEPT_ALL_MULTICAST     NDIS_PACKET_TYPE_ALL_MULTICAST
+#define fRX_FILTER_ACCEPT_PROMISCUOUS       NDIS_PACKET_TYPE_PROMISCUOUS
 
 //
 // Error code section
@@ -321,17 +324,15 @@
 #define MAX_APCLI_NUM				0
 
 #define MAX_MBSSID_NUM				1
-#if defined(RT2860) || defined(RT30xx)
 #ifdef MBSS_SUPPORT
 #undef	MAX_MBSSID_NUM
 #define MAX_MBSSID_NUM				(8 - MAX_MESH_NUM - MAX_APCLI_NUM)
 #endif // MBSS_SUPPORT //
-#endif
 
 /* sanity check for apidx */
 #define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
     { if (apidx > MAX_MBSSID_NUM) { \
-          printk("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __func__, apidx); \
+          DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __func__, apidx)); \
 	  apidx = MAIN_MBSSID; } }
 
 #define VALID_WCID(_wcid)	((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
@@ -397,6 +398,7 @@
 #define HASH_TABLE_SIZE                 256
 #define MAX_VIE_LEN                     1024   // New for WPA cipher suite variable IE sizes.
 #define MAX_SUPPORT_MCS             32
+#define MAX_NUM_OF_BBP_LATCH             140
 
 //============================================================
 // ASIC WCID Table definition.
@@ -515,6 +517,9 @@
 #define MLME_QOS_UNSPECIFY                32
 #define MLME_REQUEST_DECLINED             37
 #define MLME_REQUEST_WITH_INVALID_PARAM   38
+#define MLME_INVALID_GROUP_CIPHER	  41
+#define MLME_INVALID_PAIRWISE_CIPHER	  42
+#define MLME_INVALID_AKMP			  43
 #define MLME_DLS_NOT_ALLOW_IN_QBSS        48
 #define MLME_DEST_STA_NOT_IN_QBSS         49
 #define MLME_DEST_STA_IS_NOT_A_QSTA       50
@@ -569,6 +574,7 @@
 // For 802.11n D3.03
 //#define IE_NEW_EXT_CHA_OFFSET             62    // 802.11n d1. New extension channel offset elemet
 #define IE_SECONDARY_CH_OFFSET		62	// 802.11n D3.03	Secondary Channel Offset element
+#define IE_WAPI							68		// WAPI information element
 #define IE_2040_BSS_COEXIST               72    // 802.11n D3.0.3
 #define IE_2040_BSS_INTOLERANT_REPORT     73    // 802.11n D3.03
 #define IE_OVERLAPBSS_SCAN_PARM           74    // 802.11n D3.03
@@ -605,17 +611,22 @@
 #define SYNC_STATE_MACHINE              4
 #define MLME_CNTL_STATE_MACHINE         5
 #define WPA_PSK_STATE_MACHINE           6
-#define LEAP_STATE_MACHINE              7
+//#define LEAP_STATE_MACHINE              7
 #define AIRONET_STATE_MACHINE           8
 #define ACTION_STATE_MACHINE           9
 
 // AP MLME state machines
 #define AP_ASSOC_STATE_MACHINE          11
 #define AP_AUTH_STATE_MACHINE           12
-#define AP_AUTH_RSP_STATE_MACHINE       13
 #define AP_SYNC_STATE_MACHINE           14
 #define AP_CNTL_STATE_MACHINE           15
-#define AP_WPA_STATE_MACHINE            16
+#define WSC_STATE_MACHINE            17
+#define WSC_UPNP_STATE_MACHINE		    18
+
+
+#define WPA_STATE_MACHINE			23
+
+
 
 //
 // STA's CONTROL/CONNECT state machine: states, events, total function #
@@ -630,9 +641,9 @@
 #define CNTL_WAIT_AUTH2                 7
 #define CNTL_WAIT_OID_LIST_SCAN         8
 #define CNTL_WAIT_OID_DISASSOC          9
-#ifdef RT2870
+#ifdef RTMP_MAC_USB
 #define CNTL_WAIT_SCAN_FOR_CONNECT      10
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
 
 #define MT2_ASSOC_CONF                  34
 #define MT2_AUTH_CONF                   35
@@ -646,6 +657,7 @@
 #define MT2_GET_CONF                    43
 #define MT2_SET_CONF                    44
 #define MT2_RESET_CONF                  45
+#define MT2_FT_OTD_CONF					46
 #define MT2_MLME_ROAMING_REQ            52
 
 #define CNTL_FUNC_SIZE                  1
@@ -691,8 +703,11 @@
 #define MT2_PEER_BA_CATE             3
 #define MT2_PEER_PUBLIC_CATE             4
 #define MT2_PEER_RM_CATE             5
+/* "FT_CATEGORY_BSS_TRANSITION equal to 6" is defined file of "dot11r_ft.h" */
 #define MT2_PEER_HT_CATE             7	//	7.4.7
 #define MAX_PEER_CATE_MSG                   7
+
+
 #define MT2_MLME_ADD_BA_CATE             8
 #define MT2_MLME_ORI_DELBA_CATE             9
 #define MT2_MLME_REC_DELBA_CATE             10
@@ -822,35 +837,8 @@
 #define DLS_FUNC_SIZE					(MAX_DLS_STATE * MAX_DLS_MSG)
 
 //
-// STA's WPA-PSK State machine: states, events, total function #
+// WSC State machine: states, events, total function #
 //
-#define WPA_PSK_IDLE					0
-#define MAX_WPA_PSK_STATE				1
-
-#define WPA_MACHINE_BASE                0
-#define MT2_EAPPacket                   0
-#define MT2_EAPOLStart                  1
-#define MT2_EAPOLLogoff                 2
-#define MT2_EAPOLKey                    3
-#define MT2_EAPOLASFAlert               4
-#define MAX_WPA_PSK_MSG                 5
-
-#define	WPA_PSK_FUNC_SIZE				(MAX_WPA_PSK_STATE * MAX_WPA_PSK_MSG)
-
-//
-// STA's CISCO-AIRONET State machine: states, events, total function #
-//
-#define AIRONET_IDLE					0
-#define	AIRONET_SCANNING				1
-#define MAX_AIRONET_STATE				2
-
-#define AIRONET_MACHINE_BASE		    0
-#define MT2_AIRONET_MSG				    0
-#define MT2_AIRONET_SCAN_REQ		    1
-#define MT2_AIRONET_SCAN_DONE		    2
-#define MAX_AIRONET_MSG				    3
-
-#define	AIRONET_FUNC_SIZE				(MAX_AIRONET_STATE * MAX_AIRONET_MSG)
 
 //
 // AP's CONTROL/CONNECT state machine: states, events, total function #
@@ -882,23 +870,12 @@
 #define AP_AUTH_MACHINE_BASE            0
 #define APMT2_MLME_DEAUTH_REQ           0
 #define APMT2_CLS2ERR                   1
-#define AP_MAX_AUTH_MSG                 2
-
-#define AP_AUTH_FUNC_SIZE               (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
-
-//
-// AP's AUTH-RSP state machine: states, events, total function #
-//
-#define AP_AUTH_RSP_IDLE                0
-#define AP_MAX_AUTH_RSP_STATE           1
-
-#define AP_AUTH_RSP_MACHINE_BASE        0
-#define APMT2_AUTH_CHALLENGE_TIMEOUT    0
-#define APMT2_PEER_AUTH_ODD             1
 #define APMT2_PEER_DEAUTH               2
-#define AP_MAX_AUTH_RSP_MSG             3
+#define APMT2_PEER_AUTH_REQ				3
+#define APMT2_PEER_AUTH_CONFIRM			4
+#define AP_MAX_AUTH_MSG                 5
 
-#define AP_AUTH_RSP_FUNC_SIZE           (AP_MAX_AUTH_RSP_STATE * AP_MAX_AUTH_RSP_MSG)
+#define AP_AUTH_FUNC_SIZE               (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
 
 //
 // AP's SYNC state machine: states, events, total function #
@@ -919,20 +896,22 @@
 #define AP_SYNC_FUNC_SIZE               (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
 
 //
-// AP's WPA state machine: states, events, total function #
+// Common WPA state machine: states, events, total function #
 //
-#define AP_WPA_PTK                      0
-#define AP_MAX_WPA_PTK_STATE            1
+#define WPA_PTK                      0
+#define MAX_WPA_PTK_STATE            1
+
+#define WPA_MACHINE_BASE             0
+#define MT2_EAPPacket                0
+#define MT2_EAPOLStart               1
+#define MT2_EAPOLLogoff              2
+#define MT2_EAPOLKey                 3
+#define MT2_EAPOLASFAlert            4
+#define MAX_WPA_MSG                  5
+
+#define WPA_FUNC_SIZE                (MAX_WPA_PTK_STATE * MAX_WPA_MSG)
 
-#define AP_WPA_MACHINE_BASE             0
-#define APMT2_EAPPacket                 0
-#define APMT2_EAPOLStart                1
-#define APMT2_EAPOLLogoff               2
-#define APMT2_EAPOLKey                  3
-#define APMT2_EAPOLASFAlert             4
-#define AP_MAX_WPA_MSG                  5
 
-#define AP_WPA_FUNC_SIZE                (AP_MAX_WPA_PTK_STATE * AP_MAX_WPA_MSG)
 
 // =============================================================================
 
@@ -1178,12 +1157,16 @@
 #define REGION_4_A_BAND                   4       // 149, 153, 157, 161, 165
 #define REGION_5_A_BAND                   5       // 149, 153, 157, 161
 #define REGION_6_A_BAND                   6       // 36, 40, 44, 48
-#define REGION_7_A_BAND                   7       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165
+#define REGION_7_A_BAND                   7       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173
 #define REGION_8_A_BAND                   8       // 52, 56, 60, 64
 #define REGION_9_A_BAND                   9       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165
 #define REGION_10_A_BAND                  10	  // 36, 40, 44, 48, 149, 153, 157, 161, 165
 #define REGION_11_A_BAND                  11	  // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161
-#define REGION_MAXIMUM_A_BAND             11
+#define REGION_12_A_BAND                  12       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
+#define REGION_13_A_BAND                  13       // 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161
+#define REGION_14_A_BAND                  14       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165
+#define REGION_15_A_BAND                  15       // 149, 153, 157, 161, 165, 169, 173
+#define REGION_MAXIMUM_A_BAND             15
 
 // pTxD->CipherAlg
 #define CIPHER_NONE                 0
@@ -1196,15 +1179,6 @@
 #define CIPHER_TKIP_NO_MIC          7       // MIC appended by driver: not a valid value in hardware key table
 #define CIPHER_SMS4					8
 
-// 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
 
 // LED Status.
 #define LED_LINK_DOWN               0
@@ -1219,7 +1193,8 @@
 // value domain of pAd->LedCntl.LedMode and E2PROM
 #define LED_MODE_DEFAULT            0
 #define LED_MODE_TWO_LED			1
-#define LED_MODE_SIGNAL_STREGTH		8  // EEPROM define =8
+//#define LED_MODE_SIGNAL_STREGTH		8  // EEPROM define =8
+#define LED_MODE_SIGNAL_STREGTH		0x40 // EEPROM define = 64
 
 // RC4 init value, used fro WEP & TKIP
 #define PPPINITFCS32                0xffffffff   /* Initial FCS value */
@@ -1305,7 +1280,12 @@
 #define INT_APCLI                   0x0400
 #define INT_MESH                   	0x0500
 
-// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode)
+#define INF_MAIN_DEV_NAME		"wlan"
+#define INF_MBSSID_DEV_NAME		"ra"
+#define INF_WDS_DEV_NAME		"wds"
+#define INF_APCLI_DEV_NAME		"apcli"
+#define INF_MESH_DEV_NAME		"mesh"
+
 
 // WEP Key TYPE
 #define WEP_HEXADECIMAL_TYPE    0
@@ -1380,7 +1360,7 @@
 #define	MAX_NUM_OF_INIT_DLS_ENTRY   1
 #define	MAX_NUM_OF_DLS_ENTRY        MAX_NUMBER_OF_DLS_ENTRY
 
-//Block ACK , rt2860, kathy
+//Block ACK, kathy
 #define MAX_TX_REORDERBUF		64
 #define MAX_RX_REORDERBUF		64
 #define DEFAULT_TX_TIMEOUT		30
@@ -1392,29 +1372,13 @@
 #define IW_ESSID_MAX_SIZE   		32
 #endif
 
-#ifdef MCAST_RATE_SPECIFIC
-#define MCAST_DISABLE	0
-#define MCAST_CCK		1
-#define MCAST_OFDM		2
-#define MCAST_HTMIX		3
-#endif // MCAST_RATE_SPECIFIC //
-
-#ifdef RT2860
-// For AsicRadioOff/AsicRadioOn/AsicForceWakeup function
-// This is to indicate from where to call this function.
-#define DOT11POWERSAVE		0	// TO do .11 power save sleep
-#define GUIRADIO_OFF		1	// To perform Radio OFf command from GUI
-#define RTMP_HALT			2	// Called from Halt handler.
-#define GUI_IDLE_POWER_SAVE	3	// Call to sleep before link up with AP
-#define FROM_TX				4	// Force wake up from Tx packet.
-#endif
-#ifdef RT2870
 // For AsicRadioOff/AsicRadioOn function
 #define DOT11POWERSAVE		0
 #define GUIRADIO_OFF		1
 #define RTMP_HALT		    2
 #define GUI_IDLE_POWER_SAVE		3
-#endif
+// --
+
 
 // definition for WpaSupport flag
 #define WPA_SUPPLICANT_DISABLE				0
@@ -1458,6 +1422,41 @@
 #define cpu2be16(x) SWAP16((x))
 #define be2cpu16(x) SWAP16((x))
 
+
+#define ABS(_x, _y) ((_x) > (_y)) ? ((_x) -(_y)) : ((_y) -(_x))
+
+
+#define A2Dec(_X, _p)				\
+{									\
+	UCHAR *p;						\
+	_X = 0;							\
+	p = _p;							\
+	while (((*p >= '0') && (*p <= '9')))		\
+	{												\
+		if ((*p >= '0') && (*p <= '9'))		\
+			_X = _X * 10 + *p - 48;					\
+		p++;										\
+	}												\
+}
+
+
+#define A2Hex(_X, _p)				\
+do{									\
+	char *__p;						\
+	(_X) = 0;							\
+	__p = (char *)(_p);							\
+	while (((*__p >= 'a') && (*__p <= 'f')) || ((*__p >= 'A') && (*__p <= 'F')) || ((*__p >= '0') && (*__p <= '9')))		\
+	{												\
+		if ((*__p >= 'a') && (*__p <= 'f'))				\
+			(_X) = (_X) * 16 + *__p - 87;					\
+		else if ((*__p >= 'A') && (*__p <= 'F'))		\
+			(_X) = (_X) * 16 + *__p - 55;					\
+		else if ((*__p >= '0') && (*__p <= '9'))		\
+			(_X) = (_X) * 16 + *__p - 48;					\
+		__p++;										\
+	}												\
+}while(0)
+
 #endif  // __RTMP_DEF_H__
 
 

+ 102 - 0
drivers/staging/rt2860/rtmp_dot11.h

@@ -0,0 +1,102 @@
+/*
+ *************************************************************************
+ * 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 __DOT11_BASE_H__
+#define __DOT11_BASE_H__
+
+#include "rtmp_type.h"
+
+
+// 4-byte HTC field.  maybe included in any frame except non-QOS data frame.  The Order bit must set 1.
+typedef struct PACKED {
+    UINT32		MA:1;	//management action payload exist in (QoS Null+HTC)
+    UINT32		TRQ:1;	//sounding request
+    UINT32		MRQ:1;	//MCS feedback. Request for a MCS feedback
+    UINT32		MRSorASI:3;	// MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
+    UINT32		MFS:3;	//SET to the received value of MRS. 0x111 for unsolicited MFB.
+    UINT32		MFBorASC:7;	//Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
+    UINT32		CalPos:2;	// calibration position
+    UINT32		CalSeq:2;  //calibration sequence
+    UINT32		FBKReq:2;	//feedback request
+    UINT32		CSISTEERING:2;	//CSI/ STEERING
+    UINT32		ZLFAnnouce:1;	// ZLF announcement
+    UINT32		rsv:5;  //calibration sequence
+    UINT32		ACConstraint:1;	//feedback request
+    UINT32		RDG:1;	//RDG / More PPDU
+} HT_CONTROL, *PHT_CONTROL;
+
+// 2-byte QOS CONTROL field
+typedef struct PACKED {
+    USHORT      TID:4;
+    USHORT      EOSP:1;
+    USHORT      AckPolicy:2;  //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP  3: BA
+    USHORT      AMsduPresent:1;
+    USHORT      Txop_QueueSize:8;
+} QOS_CONTROL, *PQOS_CONTROL;
+
+
+// 2-byte Frame control field
+typedef	struct	PACKED {
+	USHORT		Ver:2;				// Protocol version
+	USHORT		Type:2;				// MSDU type
+	USHORT		SubType:4;			// MSDU subtype
+	USHORT		ToDs:1;				// To DS indication
+	USHORT		FrDs:1;				// From DS indication
+	USHORT		MoreFrag:1;			// More fragment bit
+	USHORT		Retry:1;			// Retry status bit
+	USHORT		PwrMgmt:1;			// Power management bit
+	USHORT		MoreData:1;			// More data bit
+	USHORT		Wep:1;				// Wep data
+	USHORT		Order:1;			// Strict order expected
+} FRAME_CONTROL, *PFRAME_CONTROL;
+
+typedef	struct	PACKED _HEADER_802_11	{
+    FRAME_CONTROL   FC;
+    USHORT          Duration;
+    UCHAR           Addr1[MAC_ADDR_LEN];
+    UCHAR           Addr2[MAC_ADDR_LEN];
+	UCHAR			Addr3[MAC_ADDR_LEN];
+	USHORT			Frag:4;
+	USHORT			Sequence:12;
+	UCHAR			Octet[0];
+}	HEADER_802_11, *PHEADER_802_11;
+
+typedef struct PACKED _PSPOLL_FRAME {
+    FRAME_CONTROL   FC;
+    USHORT          Aid;
+    UCHAR           Bssid[MAC_ADDR_LEN];
+    UCHAR           Ta[MAC_ADDR_LEN];
+}   PSPOLL_FRAME, *PPSPOLL_FRAME;
+
+typedef	struct	PACKED _RTS_FRAME	{
+    FRAME_CONTROL   FC;
+    USHORT          Duration;
+    UCHAR           Addr1[MAC_ADDR_LEN];
+    UCHAR           Addr2[MAC_ADDR_LEN];
+}RTS_FRAME, *PRTS_FRAME;
+
+#endif // __DOT11_BASE_H__ //

+ 84 - 0
drivers/staging/rt2860/rtmp_iface.h

@@ -0,0 +1,84 @@
+/*
+ *************************************************************************
+ * 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:
+	rt_iface.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RTMP_IFACE_H__
+#define __RTMP_IFACE_H__
+
+
+#ifdef RTMP_PCI_SUPPORT
+#include "iface/rtmp_pci.h"
+#endif // RTMP_PCI_SUPPORT //
+#ifdef RTMP_USB_SUPPORT
+#include "iface/rtmp_usb.h"
+#endif // RTMP_USB_SUPPORT //
+
+typedef struct _INF_PCI_CONFIG_
+{
+	unsigned long	CSRBaseAddress;     // PCI MMIO Base Address, all access will use
+	unsigned int	irq_num;
+}INF_PCI_CONFIG;
+
+
+typedef struct _INF_USB_CONFIG_
+{
+	UINT8                BulkInEpAddr;		// bulk-in endpoint address
+	UINT8                BulkOutEpAddr[6];	// bulk-out endpoint address
+}INF_USB_CONFIG;
+
+
+typedef struct _INF_RBUS_CONFIG_
+{
+	unsigned long		csr_addr;
+	unsigned int		irq;
+}INF_RBUS_CONFIG;
+
+
+typedef enum _RTMP_INF_TYPE_
+{
+	RTMP_DEV_INF_UNKNOWN = 0,
+	RTMP_DEV_INF_PCI = 1,
+	RTMP_DEV_INF_USB = 2,
+	RTMP_DEV_INF_RBUS = 4,
+}RTMP_INF_TYPE;
+
+
+typedef union _RTMP_INF_CONFIG_{
+	struct _INF_PCI_CONFIG_			pciConfig;
+	struct _INF_USB_CONFIG_			usbConfig;
+	struct _INF_RBUS_CONFIG_		rbusConfig;
+}RTMP_INF_CONFIG;
+
+#endif // __RTMP_IFACE_H__ //

+ 55 - 0
drivers/staging/rt2860/rtmp_mcu.h

@@ -0,0 +1,55 @@
+/*
+ *************************************************************************
+ * 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_mcu.h
+
+	Abstract:
+	Miniport header file for mcu related information
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifndef __RTMP_MCU_H__
+#define __RTMP_MCU_H__
+
+
+INT RtmpAsicEraseFirmware(
+	IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS RtmpAsicLoadFirmware(
+	IN PRTMP_ADAPTER pAd);
+
+INT RtmpAsicSendCommandToMcu(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 Command,
+	IN UCHAR		 Token,
+	IN UCHAR		 Arg0,
+	IN UCHAR		 Arg1);
+
+#endif // __RTMP_MCU_H__ //

+ 98 - 0
drivers/staging/rt2860/rtmp_os.h

@@ -0,0 +1,98 @@
+/*
+ *************************************************************************
+ * 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_os.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+
+#ifndef __RTMP_OS_H__
+#define __RTMP_OS_H__
+
+#ifdef LINUX
+#include "rt_linux.h"
+#endif // LINUX //
+
+
+
+/*
+	This data structure mainly strip some callback function defined in
+	"struct net_device" in kernel source "include/linux/netdevice.h".
+
+	The definition of this data structure may various depends on different
+	OS. Use it carefully.
+*/
+typedef struct _RTMP_OS_NETDEV_OP_HOOK_
+{
+	const struct net_device_ops *netdev_ops;
+	void			*priv;
+	int			priv_flags;
+	unsigned char devAddr[6];
+	unsigned char	devName[16];
+	unsigned char	needProtcted;
+}RTMP_OS_NETDEV_OP_HOOK, *PRTMP_OS_NETDEV_OP_HOOK;
+
+
+typedef enum _RTMP_TASK_STATUS_
+{
+	RTMP_TASK_STAT_UNKNOWN = 0,
+	RTMP_TASK_STAT_INITED = 1,
+	RTMP_TASK_STAT_RUNNING = 2,
+	RTMP_TASK_STAT_STOPED = 4,
+}RTMP_TASK_STATUS;
+#define RTMP_TASK_CAN_DO_INSERT		(RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING)
+
+#define RTMP_OS_TASK_NAME_LEN	16
+typedef struct _RTMP_OS_TASK_
+{
+	char					taskName[RTMP_OS_TASK_NAME_LEN];
+	void					*priv;
+	//unsigned long		taskFlags;
+	RTMP_TASK_STATUS	taskStatus;
+#ifndef KTHREAD_SUPPORT
+	RTMP_OS_SEM			taskSema;
+	RTMP_OS_PID			taskPID;
+	struct completion		taskComplete;
+#endif
+	unsigned char			task_killed;
+#ifdef KTHREAD_SUPPORT
+	struct task_struct	*kthread_task;
+	wait_queue_head_t		kthread_q;
+	BOOLEAN					kthread_running;
+#endif
+}RTMP_OS_TASK;
+
+
+int RtmpOSIRQRequest(IN PNET_DEV pNetDev);
+int RtmpOSIRQRelease(IN PNET_DEV pNetDev);
+
+#endif // __RMTP_OS_H__ //

+ 156 - 0
drivers/staging/rt2860/rtmp_timer.h

@@ -0,0 +1,156 @@
+/*
+ *************************************************************************
+ * 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_timer.h
+
+    Abstract:
+	Ralink Wireless Driver timer related data structures and delcarations
+
+    Revision History:
+	Who           When                What
+	--------    ----------      ----------------------------------------------
+	Name          Date                 Modification logs
+	Shiang Tu    Aug-28-2008	init version
+
+*/
+
+#ifndef __RTMP_TIMER_H__
+#define  __RTMP_TIMER_H__
+
+#include "rtmp_os.h"
+
+
+#define DECLARE_TIMER_FUNCTION(_func)			\
+	void rtmp_timer_##_func(unsigned long data)
+
+#define GET_TIMER_FUNCTION(_func)				\
+	rtmp_timer_##_func
+
+
+/* ----------------- Timer Related MARCO ---------------*/
+// In some os or chipset, we have a lot of timer functions and will read/write register,
+//   it's not allowed in Linux USB sub-system to do it ( because of sleep issue when
+//  submit to ctrl pipe). So we need a wrapper function to take care it.
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+typedef VOID (*RTMP_TIMER_TASK_HANDLE)(
+	IN  PVOID   SystemSpecific1,
+	IN  PVOID   FunctionContext,
+	IN  PVOID   SystemSpecific2,
+	IN  PVOID   SystemSpecific3);
+#endif // RTMP_TIMER_TASK_SUPPORT //
+
+typedef struct  _RALINK_TIMER_STRUCT    {
+	RTMP_OS_TIMER		TimerObj;       // Ndis Timer object
+	BOOLEAN				Valid;			// Set to True when call RTMPInitTimer
+	BOOLEAN				State;          // True if timer cancelled
+	BOOLEAN				PeriodicType;	// True if timer is periodic timer
+	BOOLEAN				Repeat;         // True if periodic timer
+	ULONG				TimerValue;     // Timer value in milliseconds
+	ULONG				cookie;			// os specific object
+#ifdef RTMP_TIMER_TASK_SUPPORT
+	RTMP_TIMER_TASK_HANDLE	handle;
+	void					*pAd;
+#endif // RTMP_TIMER_TASK_SUPPORT //
+}RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
+
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+typedef struct _RTMP_TIMER_TASK_ENTRY_
+{
+	RALINK_TIMER_STRUCT			*pRaTimer;
+	struct _RTMP_TIMER_TASK_ENTRY_	*pNext;
+}RTMP_TIMER_TASK_ENTRY;
+
+
+#define TIMER_QUEUE_SIZE_MAX	128
+typedef struct _RTMP_TIMER_TASK_QUEUE_
+{
+	unsigned int				status;
+	unsigned char				*pTimerQPoll;
+	RTMP_TIMER_TASK_ENTRY	*pQPollFreeList;
+	RTMP_TIMER_TASK_ENTRY	*pQHead;
+	RTMP_TIMER_TASK_ENTRY	*pQTail;
+}RTMP_TIMER_TASK_QUEUE;
+
+#define BUILD_TIMER_FUNCTION(_func)										\
+void rtmp_timer_##_func(unsigned long data)										\
+{																			\
+	PRALINK_TIMER_STRUCT	_pTimer = (PRALINK_TIMER_STRUCT)data;				\
+	RTMP_TIMER_TASK_ENTRY	*_pQNode;										\
+	RTMP_ADAPTER			*_pAd;											\
+																			\
+	_pTimer->handle = _func;													\
+	_pAd = (RTMP_ADAPTER *)_pTimer->pAd;										\
+	_pQNode = RtmpTimerQInsert(_pAd, _pTimer);								\
+	if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT))	\
+		RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ);							\
+}
+#else
+#define BUILD_TIMER_FUNCTION(_func)										\
+void rtmp_timer_##_func(unsigned long data)										\
+{																			\
+	PRALINK_TIMER_STRUCT	pTimer = (PRALINK_TIMER_STRUCT) data;				\
+																			\
+	_func(NULL, (PVOID) pTimer->cookie, NULL, pTimer);							\
+	if (pTimer->Repeat)														\
+		RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);			\
+}
+#endif // RTMP_TIMER_TASK_SUPPORT //
+
+
+DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
+DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
+DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
+DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RTMP_MAC_USB
+DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
+#endif // RTMP_MAC_USB //
+
+DECLARE_TIMER_FUNCTION(BeaconTimeout);
+DECLARE_TIMER_FUNCTION(ScanTimeout);
+DECLARE_TIMER_FUNCTION(AuthTimeout);
+DECLARE_TIMER_FUNCTION(AssocTimeout);
+DECLARE_TIMER_FUNCTION(ReassocTimeout);
+DECLARE_TIMER_FUNCTION(DisassocTimeout);
+DECLARE_TIMER_FUNCTION(LinkDownExec);
+DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+DECLARE_TIMER_FUNCTION(PsPollWakeExec);
+DECLARE_TIMER_FUNCTION(RadioOnExec);
+
+#ifdef RTMP_MAC_USB
+DECLARE_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout);
+#endif // RTMP_MAC_USB //
+
+#if defined(AP_LED) || defined(STA_LED)
+DECLARE_TIMER_FUNCTION(LedCtrlMain);
+#endif
+
+
+#endif // __RTMP_TIMER_H__ //

+ 54 - 1
drivers/staging/rt2860/rtmp_type.h

@@ -38,8 +38,10 @@
 #ifndef __RTMP_TYPE_H__
 #define __RTMP_TYPE_H__
 
+
 #define PACKED  __attribute__ ((packed))
 
+#ifdef LINUX
 // Put platform dependent declaration here
 // For example, linux type definition
 typedef unsigned char		UINT8;
@@ -48,6 +50,7 @@ typedef unsigned int		UINT32;
 typedef unsigned long long	UINT64;
 typedef int					INT32;
 typedef long long 			INT64;
+#endif // LINUX //
 
 typedef unsigned char *			PUINT8;
 typedef unsigned short *		PUINT16;
@@ -56,22 +59,30 @@ typedef unsigned long long *	PUINT64;
 typedef int	*					PINT32;
 typedef long long * 			PINT64;
 
+// modified for fixing compile warning on Sigma 8634 platform
+typedef char					STRING;
 typedef signed char			CHAR;
+
 typedef signed short		SHORT;
 typedef signed int			INT;
 typedef signed long			LONG;
 typedef signed long long	LONGLONG;
 
 
+#ifdef LINUX
 typedef unsigned char		UCHAR;
 typedef unsigned short		USHORT;
 typedef unsigned int		UINT;
 typedef unsigned long		ULONG;
+#endif // LINUX //
 typedef unsigned long long	ULONGLONG;
 
 typedef unsigned char		BOOLEAN;
+#ifdef LINUX
 typedef void				VOID;
+#endif // LINUX //
 
+typedef char *				PSTRING;
 typedef VOID *				PVOID;
 typedef CHAR *				PCHAR;
 typedef UCHAR * 			PUCHAR;
@@ -90,5 +101,47 @@ typedef union _LARGE_INTEGER {
     INT64 QuadPart;
 } LARGE_INTEGER;
 
-#endif  // __RTMP_TYPE_H__
+
+//
+// Register set pair for initialzation register set definition
+//
+typedef struct  _RTMP_REG_PAIR
+{
+	ULONG   Register;
+	ULONG   Value;
+} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
+
+typedef struct  _REG_PAIR
+{
+	UCHAR   Register;
+	UCHAR   Value;
+} REG_PAIR, *PREG_PAIR;
+
+//
+// Register set pair for initialzation register set definition
+//
+typedef struct  _RTMP_RF_REGS
+{
+	UCHAR   Channel;
+	ULONG   R1;
+	ULONG   R2;
+	ULONG   R3;
+	ULONG   R4;
+} RTMP_RF_REGS, *PRTMP_RF_REGS;
+
+typedef struct _FREQUENCY_ITEM {
+	UCHAR	Channel;
+	UCHAR	N;
+	UCHAR	R;
+	UCHAR	K;
+} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
+
+
+typedef int				NTSTATUS;
+
+
+#define STATUS_SUCCESS				0x00
+#define STATUS_UNSUCCESSFUL		0x01
+
+#endif  // __RTMP_TYPE_H__ //
 

+ 189 - 0
drivers/staging/rt2860/rtusb_io.h

@@ -0,0 +1,189 @@
+/*
+ *************************************************************************
+ * 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 __RTUSB_IO_H__
+#define __RTUSB_IO_H__
+
+#include "rtmp_type.h"
+
+// New for MeetingHouse Api support
+#define CMDTHREAD_VENDOR_RESET                      0x0D730101	// cmd
+#define CMDTHREAD_VENDOR_UNPLUG                     0x0D730102	// cmd
+#define CMDTHREAD_VENDOR_SWITCH_FUNCTION            0x0D730103	// cmd
+#define CMDTHREAD_MULTI_WRITE_MAC                   0x0D730107	// cmd
+#define CMDTHREAD_MULTI_READ_MAC                    0x0D730108	// cmd
+#define CMDTHREAD_VENDOR_EEPROM_WRITE               0x0D73010A	// cmd
+#define CMDTHREAD_VENDOR_EEPROM_READ                0x0D73010B	// cmd
+#define CMDTHREAD_VENDOR_ENTER_TESTMODE             0x0D73010C	// cmd
+#define CMDTHREAD_VENDOR_EXIT_TESTMODE              0x0D73010D	// cmd
+#define CMDTHREAD_VENDOR_WRITE_BBP                  0x0D730119	// cmd
+#define CMDTHREAD_VENDOR_READ_BBP                   0x0D730118	// cmd
+#define CMDTHREAD_VENDOR_WRITE_RF                   0x0D73011A	// cmd
+#define CMDTHREAD_VENDOR_FLIP_IQ                    0x0D73011D	// cmd
+#define CMDTHREAD_RESET_BULK_OUT                    0x0D730210	// cmd
+#define CMDTHREAD_RESET_BULK_IN                     0x0D730211	// cmd
+#define CMDTHREAD_SET_PSM_BIT				0x0D730212	// cmd
+#define CMDTHREAD_SET_RADIO                         0x0D730214	// cmd
+#define CMDTHREAD_UPDATE_TX_RATE                    0x0D730216	// cmd
+#define CMDTHREAD_802_11_ADD_KEY_WEP                0x0D730218	// cmd
+#define CMDTHREAD_RESET_FROM_ERROR                  0x0D73021A	// cmd
+#define CMDTHREAD_LINK_DOWN                         0x0D73021B	// cmd
+#define CMDTHREAD_RESET_FROM_NDIS                   0x0D73021C	// cmd
+#define CMDTHREAD_CHECK_GPIO                        0x0D730215	// cmd
+#define CMDTHREAD_FORCE_WAKE_UP                     0x0D730222	// cmd
+#define CMDTHREAD_SET_BW                            0x0D730225	// cmd
+#define CMDTHREAD_SET_ASIC_WCID                     0x0D730226	// cmd
+#define CMDTHREAD_SET_ASIC_WCID_CIPHER              0x0D730227	// cmd
+#define CMDTHREAD_QKERIODIC_EXECUT                  0x0D73023D	// cmd
+#define RT_CMD_SET_KEY_TABLE                        0x0D730228  // cmd
+#define RT_CMD_SET_RX_WCID_TABLE                    0x0D730229  // cmd
+#define CMDTHREAD_SET_CLIENT_MAC_ENTRY              0x0D73023E	// cmd
+#define CMDTHREAD_SET_GROUP_KEY						0x0D73023F	// cmd
+#define CMDTHREAD_SET_PAIRWISE_KEY					0x0D730240	// cmd
+
+#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER    0x0D710105	// cmd
+#define CMDTHREAD_802_11_SET_PHY_MODE               0x0D79010C	// cmd
+#define CMDTHREAD_802_11_SET_STA_CONFIG             0x0D790111	// cmd
+#define CMDTHREAD_802_11_SET_PREAMBLE               0x0D790101	// cmd
+#define CMDTHREAD_802_11_COUNTER_MEASURE			0x0D790102	// cmd
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+#define CMDTHREAD_UPDATE_PROTECT					0x0D790103	// cmd
+// end johnli
+
+
+//CMDTHREAD_MULTI_READ_MAC
+//CMDTHREAD_MULTI_WRITE_MAC
+//CMDTHREAD_VENDOR_EEPROM_READ
+//CMDTHREAD_VENDOR_EEPROM_WRITE
+typedef	struct	_CMDHandler_TLV	{
+	USHORT		Offset;
+	USHORT		Length;
+	UCHAR		DataFirst;
+}	CMDHandler_TLV, *PCMDHandler_TLV;
+
+
+typedef	struct _CmdQElmt	{
+	UINT				command;
+	PVOID				buffer;
+	ULONG				bufferlength;
+	BOOLEAN				CmdFromNdis;
+	BOOLEAN				SetOperation;
+	struct _CmdQElmt	*next;
+}	CmdQElmt, *PCmdQElmt;
+
+typedef	struct	_CmdQ	{
+	UINT		size;
+	CmdQElmt	*head;
+	CmdQElmt	*tail;
+	UINT32		CmdQState;
+}CmdQ, *PCmdQ;
+
+
+#define EnqueueCmd(cmdq, cmdqelmt)		\
+{										\
+	if (cmdq->size == 0)				\
+		cmdq->head = cmdqelmt;			\
+	else								\
+		cmdq->tail->next = cmdqelmt;	\
+	cmdq->tail = cmdqelmt;				\
+	cmdqelmt->next = NULL;				\
+	cmdq->size++;						\
+}
+
+
+/******************************************************************************
+
+	USB Cmd to ASIC Related MACRO
+
+******************************************************************************/
+// reset MAC of a station entry to 0xFFFFFFFFFFFF
+#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid)					\
+	{	RT_SET_ASIC_WCID	SetAsicWcid;						\
+		SetAsicWcid.WCID = Wcid;								\
+		SetAsicWcid.SetTid = 0xffffffff;						\
+		SetAsicWcid.DeleteTid = 0xffffffff;						\
+		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID,	\
+				&SetAsicWcid, sizeof(RT_SET_ASIC_WCID));	}
+
+// add this entry into ASIC RX WCID search table
+#define RTMP_STA_ENTRY_ADD(pAd, pEntry)							\
+	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY,	\
+							pEntry, sizeof(MAC_TABLE_ENTRY));
+
+// 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)	\
+	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
+// end johnli
+
+// remove Pair-wise key material from ASIC
+// yet implement
+#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
+
+// add Client security information into ASIC WCID table and IVEIV table
+#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)						\
+	{	RTMP_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid);								\
+		if (pEntry->Aid >= 1) {														\
+			RT_SET_ASIC_WCID_ATTRI	SetAsicWcidAttri;								\
+			SetAsicWcidAttri.WCID = pEntry->Aid;									\
+			if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) &&				\
+				(pEntry->WepStatus == Ndis802_11Encryption1Enabled))				\
+			{																		\
+				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
+			}																		\
+			else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)					\
+			{																		\
+				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
+			}																		\
+			else SetAsicWcidAttri.Cipher = 0;										\
+            DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher));       \
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER,			\
+							&SetAsicWcidAttri, sizeof(RT_SET_ASIC_WCID_ATTRI)); } }
+
+// Insert the BA bitmap to ASIC for the Wcid entry
+#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)					\
+		do{																\
+			RT_SET_ASIC_WCID	SetAsicWcid;							\
+			SetAsicWcid.WCID = (_Aid);									\
+			SetAsicWcid.SetTid = (0x10000<<(_TID));						\
+			SetAsicWcid.DeleteTid = 0xffffffff;							\
+			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID));	\
+		}while(0)
+
+// Remove the BA bitmap from ASIC for the Wcid entry
+#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
+		do{																\
+			RT_SET_ASIC_WCID	SetAsicWcid;							\
+			SetAsicWcid.WCID = (_Wcid);									\
+			SetAsicWcid.SetTid = (0xffffffff);							\
+			SetAsicWcid.DeleteTid = (0x10000<<(_TID) );					\
+			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID));	\
+		}while(0)
+
+
+#endif // __RTUSB_IO_H__ //

+ 56 - 113
drivers/staging/rt2860/spectrum.h

@@ -23,7 +23,7 @@
  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  *                                                                       *
  *************************************************************************
-*/
+ */
 
 #ifndef __SPECTRUM_H__
 #define __SPECTRUM_H__
@@ -31,112 +31,10 @@
 #include "rtmp_type.h"
 #include "spectrum_def.h"
 
-typedef struct PACKED _TPC_REPORT_INFO
-{
-	UINT8 TxPwr;
-	UINT8 LinkMargin;
-} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
-
-typedef struct PACKED _CH_SW_ANN_INFO
-{
-	UINT8 ChSwMode;
-	UINT8 Channel;
-	UINT8 ChSwCnt;
-} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
-
-typedef union PACKED _MEASURE_REQ_MODE
-{
-	struct PACKED
-	{
-		UINT8 Rev0:1;
-		UINT8 Enable:1;
-		UINT8 Request:1;
-		UINT8 Report:1;
-		UINT8 Rev1:4;
-	} field;
-	UINT8 word;
-} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
-
-typedef struct PACKED _MEASURE_REQ
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-} MEASURE_REQ, *PMEASURE_REQ;
-
-typedef struct PACKED _MEASURE_REQ_INFO
-{
-	UINT8 Token;
-	MEASURE_REQ_MODE ReqMode;
-	UINT8 ReqType;
-	MEASURE_REQ MeasureReq;
-} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
-
-typedef union PACKED _MEASURE_BASIC_REPORT_MAP
-{
-	struct PACKED
-	{
-		UINT8 BSS:1;
-		UINT8 OfdmPreamble:1;
-		UINT8 UnidentifiedSignal:1;
-		UINT8 Radar:1;
-		UINT8 Unmeasure:1;
-		UINT8 Rev:3;
-	} field;
-	UINT8 word;
-} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
-
-typedef struct PACKED _MEASURE_BASIC_REPORT
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-	MEASURE_BASIC_REPORT_MAP Map;
-} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
-
-typedef struct PACKED _MEASURE_CCA_REPORT
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-	UINT8 CCA_Busy_Fraction;
-} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
-
-typedef struct PACKED _MEASURE_RPI_REPORT
-{
-	UINT8 ChNum;
-	UINT64 MeasureStartTime;
-	UINT16 MeasureDuration;
-	UINT8 RPI_Density[8];
-} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
-
-typedef union PACKED _MEASURE_REPORT_MODE
-{
-	struct PACKED
-	{
-		UINT8 Late:1;
-		UINT8 Incapable:1;
-		UINT8 Refused:1;
-		UINT8 Rev:5;
-	} field;
-	UINT8 word;
-} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
-
-typedef struct PACKED _MEASURE_REPORT_INFO
-{
-	UINT8 Token;
-	MEASURE_REPORT_MODE ReportMode;
-	UINT8 ReportType;
-	UINT8 Octect[0];
-} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
-
-typedef struct PACKED _QUIET_INFO
-{
-	UINT8 QuietCnt;
-	UINT8 QuietPeriod;
-	UINT8 QuietDuration;
-	UINT8 QuietOffset;
-} QUIET_INFO, *PQUIET_INFO;
+
+CHAR RTMP_GetTxPwr(
+	IN PRTMP_ADAPTER pAd,
+	IN HTTRANSMIT_SETTING HTTxMode);
 
 /*
 	==========================================================================
@@ -150,14 +48,17 @@ typedef struct PACKED _QUIET_INFO
 	Return	: None.
 	==========================================================================
  */
-VOID EnqueueMeasurementReq(
+VOID MakeMeasurementReqFrame(
 	IN PRTMP_ADAPTER pAd,
-	IN PUCHAR pDA,
+	OUT PUCHAR pOutBuffer,
+	OUT PULONG pFrameLen,
+	IN UINT8 TotalLen,
+	IN UINT8 Category,
+	IN UINT8 Action,
 	IN UINT8 MeasureToken,
 	IN UINT8 MeasureReqMode,
 	IN UINT8 MeasureReqType,
-	IN UINT8 MeasureCh,
-	IN UINT16 MeasureDuration);
+	IN UINT8 NumOfRepetitions);
 
 /*
 	==========================================================================
@@ -264,11 +165,16 @@ VOID PeerSpectrumAction(
  */
 INT Set_MeasureReq_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+	IN	PSTRING			arg);
 
 INT Set_TpcReq_Proc(
 	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			arg);
+	IN	PSTRING			arg);
+
+INT Set_PwrConstraint(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
 
 VOID MeasureReqTabInit(
 	IN PRTMP_ADAPTER pAd);
@@ -276,6 +182,38 @@ VOID MeasureReqTabInit(
 VOID MeasureReqTabExit(
 	IN PRTMP_ADAPTER pAd);
 
+PMEASURE_REQ_ENTRY MeasureReqLookUp(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken);
+
+PMEASURE_REQ_ENTRY MeasureReqInsert(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken);
+
+VOID MeasureReqDelete(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken);
+
+VOID InsertChannelRepIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN PSTRING pCountry,
+	IN UINT8 RegulatoryClass);
+
+VOID InsertTpcReportIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN UINT8 TxPwr,
+	IN UINT8 LinkMargin);
+
+VOID InsertDialogToken(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN UINT8 DialogToken);
+
 VOID TpcReqTabInit(
 	IN PRTMP_ADAPTER pAd);
 
@@ -288,5 +226,10 @@ VOID NotifyChSwAnnToPeerAPs(
 	IN PUCHAR pTA,
 	IN UINT8 ChSwMode,
 	IN UINT8 Channel);
+
+VOID RguClass_BuildBcnChList(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pBuf,
+	OUT	PULONG pBufLen);
 #endif // __SPECTRUM_H__ //
 

+ 139 - 9
drivers/staging/rt2860/spectrum_def.h

@@ -39,21 +39,15 @@
 #ifndef __SPECTRUM_DEF_H__
 #define __SPECTRUM_DEF_H__
 
-#define MAX_MEASURE_REQ_TAB_SIZE		3
+
+#define MAX_MEASURE_REQ_TAB_SIZE		32
 #define MAX_HASH_MEASURE_REQ_TAB_SIZE	MAX_MEASURE_REQ_TAB_SIZE
 
-#define MAX_TPC_REQ_TAB_SIZE			3
+#define MAX_TPC_REQ_TAB_SIZE			32
 #define MAX_HASH_TPC_REQ_TAB_SIZE		MAX_TPC_REQ_TAB_SIZE
 
 #define MIN_RCV_PWR				100		/* Negative value ((dBm) */
 
-#define RM_TPC_REQ				0
-#define RM_MEASURE_REQ			1
-
-#define RM_BASIC				0
-#define RM_CCA					1
-#define RM_RPI_HISTOGRAM		2
-
 #define TPC_REQ_AGE_OUT			500		/* ms */
 #define MQ_REQ_AGE_OUT			500		/* ms */
 
@@ -91,5 +85,141 @@ typedef struct _TPC_REQ_TAB
 	TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE];
 } TPC_REQ_TAB, *PTPC_REQ_TAB;
 
+
+/* The regulatory information */
+typedef struct _DOT11_CHANNEL_SET
+{
+	UCHAR NumberOfChannels;
+	UINT8 MaxTxPwr;
+	UCHAR ChannelList[16];
+} DOT11_CHANNEL_SET, *PDOT11_CHANNEL_SET;
+
+typedef struct _DOT11_REGULATORY_INFORMATION
+{
+	UCHAR RegulatoryClass;
+	DOT11_CHANNEL_SET ChannelSet;
+} DOT11_REGULATORY_INFORMATION, *PDOT11_REGULATORY_INFORMATION;
+
+
+
+#define RM_TPC_REQ				0
+#define RM_MEASURE_REQ			1
+
+#define RM_BASIC				0
+#define RM_CCA					1
+#define RM_RPI_HISTOGRAM		2
+#define RM_CH_LOAD				3
+#define RM_NOISE_HISTOGRAM		4
+
+
+typedef struct PACKED _TPC_REPORT_INFO
+{
+	UINT8 TxPwr;
+	UINT8 LinkMargin;
+} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
+
+typedef struct PACKED _CH_SW_ANN_INFO
+{
+	UINT8 ChSwMode;
+	UINT8 Channel;
+	UINT8 ChSwCnt;
+} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
+
+typedef union PACKED _MEASURE_REQ_MODE
+{
+	struct PACKED
+	{
+		UINT8 Parallel:1;
+		UINT8 Enable:1;
+		UINT8 Request:1;
+		UINT8 Report:1;
+		UINT8 DurationMandatory:1;
+		UINT8 :3;
+	} field;
+	UINT8 word;
+} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
+
+typedef struct PACKED _MEASURE_REQ
+{
+	UINT8 ChNum;
+	UINT64 MeasureStartTime;
+	UINT16 MeasureDuration;
+} MEASURE_REQ, *PMEASURE_REQ;
+
+typedef struct PACKED _MEASURE_REQ_INFO
+{
+	UINT8 Token;
+	MEASURE_REQ_MODE ReqMode;
+	UINT8 ReqType;
+	UINT8 Oct[0];
+} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
+
+typedef union PACKED _MEASURE_BASIC_REPORT_MAP
+{
+	struct PACKED
+	{
+		UINT8 BSS:1;
+
+		UINT8 OfdmPreamble:1;
+		UINT8 UnidentifiedSignal:1;
+		UINT8 Radar:1;
+		UINT8 Unmeasure:1;
+		UINT8 Rev:3;
+	} field;
+	UINT8 word;
+} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
+
+typedef struct PACKED _MEASURE_BASIC_REPORT
+{
+	UINT8 ChNum;
+	UINT64 MeasureStartTime;
+	UINT16 MeasureDuration;
+	MEASURE_BASIC_REPORT_MAP Map;
+} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
+
+typedef struct PACKED _MEASURE_CCA_REPORT
+{
+	UINT8 ChNum;
+	UINT64 MeasureStartTime;
+	UINT16 MeasureDuration;
+	UINT8 CCA_Busy_Fraction;
+} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
+
+typedef struct PACKED _MEASURE_RPI_REPORT
+{
+	UINT8 ChNum;
+	UINT64 MeasureStartTime;
+	UINT16 MeasureDuration;
+	UINT8 RPI_Density[8];
+} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
+
+typedef union PACKED _MEASURE_REPORT_MODE
+{
+	struct PACKED
+	{
+		UINT8 Late:1;
+		UINT8 Incapable:1;
+		UINT8 Refused:1;
+		UINT8 Rev:5;
+	} field;
+	UINT8 word;
+} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
+
+typedef struct PACKED _MEASURE_REPORT_INFO
+{
+	UINT8 Token;
+	UINT8 ReportMode;
+	UINT8 ReportType;
+	UINT8 Octect[0];
+} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
+
+typedef struct PACKED _QUIET_INFO
+{
+	UINT8 QuietCnt;
+	UINT8 QuietPeriod;
+	UINT16 QuietDuration;
+	UINT16 QuietOffset;
+} QUIET_INFO, *PQUIET_INFO;
+
 #endif // __SPECTRUM_DEF_H__ //
 

+ 0 - 1312
drivers/staging/rt2860/sta/aironet.c

@@ -1,1312 +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.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Lin	04-06-15		Initial
-*/
-#include "../rt_config.h"
-
-/*
-	==========================================================================
-	Description:
-		association	state machine init,	including state	transition and timer init
-	Parameters:
-		S -	pointer	to the association state machine
-	==========================================================================
- */
-VOID	AironetStateMachineInit(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	STATE_MACHINE		*S,
-	OUT	STATE_MACHINE_FUNC	Trans[])
-{
-	StateMachineInit(S,	Trans, MAX_AIRONET_STATE, MAX_AIRONET_MSG, (STATE_MACHINE_FUNC)Drop, AIRONET_IDLE, AIRONET_MACHINE_BASE);
-	StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_MSG, (STATE_MACHINE_FUNC)AironetMsgAction);
-	StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_SCAN_REQ, (STATE_MACHINE_FUNC)AironetRequestAction);
-	StateMachineSetAction(S, AIRONET_SCANNING, MT2_AIRONET_SCAN_DONE, (STATE_MACHINE_FUNC)AironetReportAction);
-}
-
-/*
-	==========================================================================
-	Description:
-		This is	state machine function.
-		When receiving EAPOL packets which is  for 802.1x key management.
-		Use	both in	WPA, and WPAPSK	case.
-		In this	function, further dispatch to different	functions according	to the received	packet.	 3 categories are :
-		  1.  normal 4-way pairwisekey and 2-way groupkey handshake
-		  2.  MIC error	(Countermeasures attack)  report packet	from STA.
-		  3.  Request for pairwise/group key update	from STA
-	Return:
-	==========================================================================
-*/
-VOID	AironetMsgAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MLME_QUEUE_ELEM	*Elem)
-{
-	USHORT							Length;
-	UCHAR							Index, i;
-	PUCHAR							pData;
-	PAIRONET_RM_REQUEST_FRAME		pRMReq;
-	PRM_REQUEST_ACTION				pReqElem;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("-----> AironetMsgAction\n"));
-
-	// 0. Get Aironet IAPP header first
-	pRMReq = (PAIRONET_RM_REQUEST_FRAME) &Elem->Msg[LENGTH_802_11];
-	pData  = (PUCHAR) &Elem->Msg[LENGTH_802_11];
-
-	// 1. Change endian format form network to little endian
-	Length = be2cpu16(pRMReq->IAPP.Length);
-
-	// 2.0 Sanity check, this should only happen when CCX 2.0 support is enabled
-	if (pAd->StaCfg.CCXEnable != TRUE)
-		return;
-
-	// 2.1 Radio measurement must be on
-	if (pAd->StaCfg.CCXControl.field.RMEnable != 1)
-		return;
-
-	// 2.2. Debug print all bit information
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP ID & Length %d\n", Length));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Type %x\n", pRMReq->IAPP.Type));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP SubType %x\n", pRMReq->IAPP.SubType));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Dialog Token %x\n", pRMReq->IAPP.Token));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Activation Delay %x\n", pRMReq->Delay));
-	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Measurement Offset %x\n", pRMReq->Offset));
-
-	// 3. Check IAPP frame type, it must be 0x32 for Cisco Aironet extension
-	if (pRMReq->IAPP.Type != AIRONET_IAPP_TYPE)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP type for Cisco Aironet extension\n"));
-		return;
-	}
-
-	// 4. Check IAPP frame subtype, it must be 0x01 for Cisco Aironet extension request.
-	//    Since we are acting as client only, we will disregards reply subtype.
-	if (pRMReq->IAPP.SubType != AIRONET_IAPP_SUBTYPE_REQUEST)
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP subtype for Cisco Aironet extension\n"));
-		return;
-	}
-
-	// 5. Verify Destination MAC and Source MAC, both should be all zeros.
-	if (! MAC_ADDR_EQUAL(pRMReq->IAPP.DA, ZERO_MAC_ADDR))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP DA for Cisco Aironet extension, it's not Zero\n"));
-		return;
-	}
-
-	if (! MAC_ADDR_EQUAL(pRMReq->IAPP.SA, ZERO_MAC_ADDR))
-	{
-		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP SA for Cisco Aironet extension, it's not Zero\n"));
-		return;
-	}
-
-	// 6. Reinit all report related fields
-	NdisZeroMemory(pAd->StaCfg.FrameReportBuf, 2048);
-	NdisZeroMemory(pAd->StaCfg.BssReportOffset, sizeof(USHORT) * MAX_LEN_OF_BSS_TABLE);
-	NdisZeroMemory(pAd->StaCfg.MeasurementRequest, sizeof(RM_REQUEST_ACTION) * 4);
-
-	// 7. Point to the start of first element report element
-	pAd->StaCfg.FrameReportLen   = LENGTH_802_11 + sizeof(AIRONET_IAPP_HEADER);
-	DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
-	pAd->StaCfg.LastBssIndex     = 0xff;
-	pAd->StaCfg.RMReqCnt         = 0;
-	pAd->StaCfg.ParallelReq      = FALSE;
-	pAd->StaCfg.ParallelDuration = 0;
-	pAd->StaCfg.ParallelChannel  = 0;
-	pAd->StaCfg.IAPPToken        = pRMReq->IAPP.Token;
-	pAd->StaCfg.CurrentRMReqIdx  = 0;
-	pAd->StaCfg.CLBusyBytes      = 0;
-	// Reset the statistics
-	for (i = 0; i < 8; i++)
-		pAd->StaCfg.RPIDensity[i] = 0;
-
-	Index = 0;
-
-	// 8. Save dialog token for report
-	pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
-
-	// Save Activation delay & measurement offset, Not really needed
-
-	// 9. Point to the first request element
-	pData += sizeof(AIRONET_RM_REQUEST_FRAME);
-	//    Length should exclude the CISCO Aironet SNAP header
-	Length -= (sizeof(AIRONET_RM_REQUEST_FRAME) - LENGTH_802_1_H);
-
-	// 10. Start Parsing the Measurement elements.
-	//    Be careful about multiple MR elements within one frames.
-	while (Length > 0)
-	{
-		pReqElem = (PRM_REQUEST_ACTION) pData;
-		switch (pReqElem->ReqElem.Eid)
-		{
-			case IE_MEASUREMENT_REQUEST:
-				// From the example, it seems we only need to support one request in one frame
-				// There is no multiple request in one frame.
-				// Besides, looks like we need to take care the measurement request only.
-				// The measurement request is always 4 bytes.
-
-				// Start parsing this type of request.
-				// 0. Eid is IE_MEASUREMENT_REQUEST
-				// 1. Length didn't include Eid and Length field, it always be 8.
-				// 2. Measurement Token, we nned to save it for the corresponding report.
-				// 3. Measurement Mode, Although there are definitions, but we din't see value other than
-				//    0 from test specs examples.
-				// 4. Measurement Type, this is what we need to do.
-				switch (pReqElem->ReqElem.Type)
-				{
-					case MSRN_TYPE_CHANNEL_LOAD_REQ:
-					case MSRN_TYPE_NOISE_HIST_REQ:
-					case MSRN_TYPE_BEACON_REQ:
-						// Check the Enable non-serving channel measurement control
-						if (pAd->StaCfg.CCXControl.field.DCRMEnable == 0)
-						{
-							// Check channel before enqueue the action
-							if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
-								break;
-						}
-						else
-						{
-							// If off channel measurement, check the TU duration limit
-							if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
-								if (pReqElem->Measurement.Duration > pAd->StaCfg.CCXControl.field.TuLimit)
-									break;
-						}
-
-						// Save requests and execute actions later
-						NdisMoveMemory(&pAd->StaCfg.MeasurementRequest[Index], pReqElem, sizeof(RM_REQUEST_ACTION));
-						Index += 1;
-						break;
-
-					case MSRN_TYPE_FRAME_REQ:
-						// Since it's option, we will support later
-						// FrameRequestAction(pAd, pData);
-						break;
-
-					default:
-						break;
-				}
-
-				// Point to next Measurement request
-				pData  += sizeof(RM_REQUEST_ACTION);
-				Length -= sizeof(RM_REQUEST_ACTION);
-				break;
-
-			// We accept request only, all others are dropped
-			case IE_MEASUREMENT_REPORT:
-			case IE_AP_TX_POWER:
-			case IE_MEASUREMENT_CAPABILITY:
-			default:
-				return;
-		}
-	}
-
-	// 11. Update some flags and index
-	pAd->StaCfg.RMReqCnt = Index;
-
-	if (Index)
-	{
-		MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
-		RT28XX_MLME_HANDLER(pAd);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<----- AironetMsgAction\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetRequestAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MLME_QUEUE_ELEM	*Elem)
-{
-	PRM_REQUEST_ACTION	pReq;
-
-	// 1. Point to next request element
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
-	// 2. Parse measurement type and call appropriate functions
-	if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
-		// Channel Load measurement request
-		ChannelLoadRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
-		// Noise Histogram measurement request
-		NoiseHistRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
-		// Beacon measurement request
-		BeaconRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else
-		// Unknown. Do nothing and return, this should never happen
-		return;
-
-	// 3. Peek into the next request, if it's parallel, we will update the scan time to the largest one
-	if ((pAd->StaCfg.CurrentRMReqIdx + 1) < pAd->StaCfg.RMReqCnt)
-	{
-		pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx + 1];
-		// Check for parallel bit
-		if ((pReq->ReqElem.Mode & 0x01) && (pReq->Measurement.Channel == pAd->StaCfg.CCXScanChannel))
-		{
-			// Update parallel mode request information
-			pAd->StaCfg.ParallelReq = TRUE;
-			pAd->StaCfg.CCXScanTime = ((pReq->Measurement.Duration > pAd->StaCfg.CCXScanTime) ?
-			(pReq->Measurement.Duration) : (pAd->StaCfg.CCXScanTime));
-		}
-	}
-
-	// 4. Call RT28XX_MLME_HANDLER to execute the request mlme commands, Scan request is the only one used
-	RT28XX_MLME_HANDLER(pAd);
-
-}
-
-
-/*
-	========================================================================
-
-	Routine Description:
-		Prepare channel load report action, special scan operation added
-		to support
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		pData		Start from element ID
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	ChannelLoadRequestAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PRM_REQUEST_ACTION				pReq;
-	MLME_SCAN_REQ_STRUCT			ScanReq;
-	UCHAR							ZeroSsid[32];
-	NDIS_STATUS						NStatus;
-	PUCHAR							pOutBuffer = NULL;
-	PHEADER_802_11					pNullFrame;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction ----->\n"));
-
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
-	NdisZeroMemory(ZeroSsid, 32);
-
-	// Prepare for special scan request
-	// The scan definition is different with our Active, Passive scan definition.
-	// For CCX2, Active means send out probe request with broadcast BSSID.
-	// Passive means no probe request sent, only listen to the beacons.
-	// The channel scanned is fixed as specified, no need to scan all channels.
-	// The scan wait time is specified in the request too.
-	// Passive scan Mode
-
-	// Control state machine is not idle, reject the request
-	if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
-		return;
-
-	// Fill out stuff for scan request
-	ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_CHANNEL_LOAD);
-	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
-	// Reset some internal control flags to make sure this scan works.
-	BssTableInit(&pAd->StaCfg.CCXBssTab);
-	pAd->StaCfg.ScanCnt        = 0;
-	pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
-	pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
-
-	// If it's non serving channel scan, send out a null frame with PSM bit on.
-	if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-	{
-		// Use MLME enqueue method
-		NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-		if (NStatus	!= NDIS_STATUS_SUCCESS)
-			return;
-
-		pNullFrame = (PHEADER_802_11) pOutBuffer;;
-		// Make the power save Null frame with PSM bit on
-		MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-		pNullFrame->Duration 	= 0;
-		pNullFrame->FC.Type 	= BTYPE_DATA;
-		pNullFrame->FC.PwrMgmt	= PWR_SAVE;
-
-		// Send using priority queue
-		MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-		MlmeFreeMemory(pAd, pOutBuffer);
-		DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
-		RTMPusecDelay(5000);
-	}
-
-	pAd->StaCfg.CCXReqType     = MSRN_TYPE_CHANNEL_LOAD_REQ;
-	pAd->StaCfg.CLBusyBytes    = 0;
-	// Enable Rx with promiscuous reception
-	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
-
-	// Set channel load measurement flag
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Prepare noise histogram report action, special scan operation added
-		to support
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		pData		Start from element ID
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	NoiseHistRequestAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PRM_REQUEST_ACTION				pReq;
-	MLME_SCAN_REQ_STRUCT			ScanReq;
-	UCHAR							ZeroSsid[32], i;
-	NDIS_STATUS						NStatus;
-	PUCHAR							pOutBuffer = NULL;
-	PHEADER_802_11					pNullFrame;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction ----->\n"));
-
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
-	NdisZeroMemory(ZeroSsid, 32);
-
-	// Prepare for special scan request
-	// The scan definition is different with our Active, Passive scan definition.
-	// For CCX2, Active means send out probe request with broadcast BSSID.
-	// Passive means no probe request sent, only listen to the beacons.
-	// The channel scanned is fixed as specified, no need to scan all channels.
-	// The scan wait time is specified in the request too.
-	// Passive scan Mode
-
-	// Control state machine is not idle, reject the request
-	if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
-		return;
-
-	// Fill out stuff for scan request
-	ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_NOISE);
-	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
-	// Reset some internal control flags to make sure this scan works.
-	BssTableInit(&pAd->StaCfg.CCXBssTab);
-	pAd->StaCfg.ScanCnt        = 0;
-	pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
-	pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
-	pAd->StaCfg.CCXReqType     = MSRN_TYPE_NOISE_HIST_REQ;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
-
-	// If it's non serving channel scan, send out a null frame with PSM bit on.
-	if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-	{
-		// Use MLME enqueue method
-		NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-		if (NStatus	!= NDIS_STATUS_SUCCESS)
-			return;
-
-		pNullFrame = (PHEADER_802_11) pOutBuffer;
-		// Make the power save Null frame with PSM bit on
-		MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-		pNullFrame->Duration 	= 0;
-		pNullFrame->FC.Type  	= BTYPE_DATA;
-		pNullFrame->FC.PwrMgmt	= PWR_SAVE;
-
-		// Send using priority queue
-		MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-		MlmeFreeMemory(pAd, pOutBuffer);
-		DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
-		RTMPusecDelay(5000);
-	}
-
-	// Reset the statistics
-	for (i = 0; i < 8; i++)
-		pAd->StaCfg.RPIDensity[i] = 0;
-
-	// Enable Rx with promiscuous reception
-	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
-
-	// Set channel load measurement flag
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Prepare Beacon report action, special scan operation added
-		to support
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		pData		Start from element ID
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	BeaconRequestAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PRM_REQUEST_ACTION				pReq;
-	NDIS_STATUS						NStatus;
-	PUCHAR							pOutBuffer = NULL;
-	PHEADER_802_11					pNullFrame;
-	MLME_SCAN_REQ_STRUCT			ScanReq;
-	UCHAR							ZeroSsid[32];
-
-	DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction ----->\n"));
-
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
-	NdisZeroMemory(ZeroSsid, 32);
-
-	// Prepare for special scan request
-	// The scan definition is different with our Active, Passive scan definition.
-	// For CCX2, Active means send out probe request with broadcast BSSID.
-	// Passive means no probe request sent, only listen to the beacons.
-	// The channel scanned is fixed as specified, no need to scan all channels.
-	// The scan wait time is specified in the request too.
-	if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_PASSIVE)
-	{
-		// Passive scan Mode
-		DBGPRINT(RT_DEBUG_TRACE, ("Passive Scan Mode!\n"));
-
-		// Control state machine is not idle, reject the request
-		if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
-			return;
-
-		// Fill out stuff for scan request
-		ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_PASSIVE);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
-		// Reset some internal control flags to make sure this scan works.
-		BssTableInit(&pAd->StaCfg.CCXBssTab);
-		pAd->StaCfg.ScanCnt        = 0;
-		pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
-		pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
-		pAd->StaCfg.CCXReqType     = MSRN_TYPE_BEACON_REQ;
-		DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
-
-		// If it's non serving channel scan, send out a null frame with PSM bit on.
-		if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-		{
-			// Use MLME enqueue method
-			NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-			if (NStatus	!= NDIS_STATUS_SUCCESS)
-				return;
-
-			pNullFrame = (PHEADER_802_11) pOutBuffer;
-			// Make the power save Null frame with PSM bit on
-			MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-			pNullFrame->Duration 	= 0;
-			pNullFrame->FC.Type     = BTYPE_DATA;
-			pNullFrame->FC.PwrMgmt  = PWR_SAVE;
-
-			// Send using priority queue
-			MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
-			RTMPusecDelay(5000);
-		}
-
-		pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-	}
-	else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_ACTIVE)
-	{
-		// Active scan Mode
-		DBGPRINT(RT_DEBUG_TRACE, ("Active Scan Mode!\n"));
-
-		// Control state machine is not idle, reject the request
-		if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
-			return;
-
-		// Fill out stuff for scan request
-		ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_ACTIVE);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-
-		// Reset some internal control flags to make sure this scan works.
-		BssTableInit(&pAd->StaCfg.CCXBssTab);
-		pAd->StaCfg.ScanCnt        = 0;
-		pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
-		pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
-		pAd->StaCfg.CCXReqType     = MSRN_TYPE_BEACON_REQ;
-		DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
-
-		// If it's non serving channel scan, send out a null frame with PSM bit on.
-		if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-		{
-			// Use MLME enqueue method
-			NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
-			if (NStatus	!= NDIS_STATUS_SUCCESS)
-				return;
-
-			pNullFrame = (PHEADER_802_11) pOutBuffer;
-			// Make the power save Null frame with PSM bit on
-			MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
-			pNullFrame->Duration 	= 0;
-			pNullFrame->FC.Type     = BTYPE_DATA;
-			pNullFrame->FC.PwrMgmt  = PWR_SAVE;
-
-			// Send using priority queue
-			MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
-			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
-			RTMPusecDelay(5000);
-		}
-
-		pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-	}
-	else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_BEACON_TABLE)
-	{
-		// Beacon report Mode, report all the APS in current bss table
-		DBGPRINT(RT_DEBUG_TRACE, ("Beacon Report Mode!\n"));
-
-		// Copy current BSS table to CCX table, we can omit this step later on.
-		NdisMoveMemory(&pAd->StaCfg.CCXBssTab, &pAd->ScanTab, sizeof(BSS_TABLE));
-
-		// Create beacon report from Bss table
-		AironetCreateBeaconReportFromBssTable(pAd);
-
-		// Set state to scanning
-		pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
-
-		// Enqueue report request
-		// Cisco scan request is finished, prepare beacon report
-		MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
-	}
-	else
-	{
-		// Wrong scan Mode
-		DBGPRINT(RT_DEBUG_TRACE, ("Wrong Scan Mode!\n"));
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetReportAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	MLME_QUEUE_ELEM	*Elem)
-{
-	PRM_REQUEST_ACTION	pReq;
-	ULONG				Now32;
-
-    NdisGetSystemUpTime(&Now32);
-	pAd->StaCfg.LastBeaconRxTime = Now32;
-
-	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction ----->\n"));
-
-	// 1. Parse measurement type and call appropriate functions
-	if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
-		// Channel Load measurement request
-		ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
-		// Noise Histogram measurement request
-		NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
-		// Beacon measurement request
-		BeaconReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-	else
-		// Unknown. Do nothing and return
-		;
-
-	// 2. Point to the correct index of action element, start from 0
-	pAd->StaCfg.CurrentRMReqIdx++;
-
-	// 3. Check for parallel actions
-	if (pAd->StaCfg.ParallelReq == TRUE)
-	{
-		pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
-		// Process next action right away
-		if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
-			// Channel Load measurement request
-			ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-		else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
-			// Noise Histogram measurement request
-			NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
-
-		pAd->StaCfg.ParallelReq = FALSE;
-		pAd->StaCfg.CurrentRMReqIdx++;
-	}
-
-	if (pAd->StaCfg.CurrentRMReqIdx >= pAd->StaCfg.RMReqCnt)
-	{
-		// 4. There is no more unprocessed measurement request, go for transmit this report
-		AironetFinalReportAction(pAd);
-		pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
-	}
-	else
-	{
-		pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
-
-		if (pReq->Measurement.Channel != pAd->CommonCfg.Channel)
-		{
-			RTMPusecDelay(100000);
-		}
-
-		// 5. There are more requests to be measure
-		MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
-		RT28XX_MLME_HANDLER(pAd);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetFinalReportAction(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	PUCHAR					pDest;
-	PAIRONET_IAPP_HEADER	pIAPP;
-	PHEADER_802_11			pHeader;
-	UCHAR					AckRate = RATE_2;
-	USHORT					AckDuration = 0;
-	NDIS_STATUS				NStatus;
-	PUCHAR					pOutBuffer = NULL;
-	ULONG					FrameLen = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction ----->\n"));
-
-	// 0. Set up the frame pointer, Frame was inited at the end of message action
-	pDest = &pAd->StaCfg.FrameReportBuf[LENGTH_802_11];
-
-	// 1. Update report IAPP fields
-	pIAPP = (PAIRONET_IAPP_HEADER) pDest;
-
-	// 2. Copy Cisco SNAP header
-	NdisMoveMemory(pIAPP->CiscoSnapHeader, SNAP_AIRONET, LENGTH_802_1_H);
-
-	// 3. network order for this 16bit length
-	pIAPP->Length  = cpu2be16(pAd->StaCfg.FrameReportLen - LENGTH_802_11 - LENGTH_802_1_H);
-
-	// 3.1 sanity check the report length, ignore it if there is nothing to report
-	if (be2cpu16(pIAPP->Length) <= 18)
-		return;
-
-	// 4. Type must be 0x32
-	pIAPP->Type    = AIRONET_IAPP_TYPE;
-
-	// 5. SubType for report must be 0x81
-	pIAPP->SubType = AIRONET_IAPP_SUBTYPE_REPORT;
-
-	// 6. DA is not used and must be zero, although the whole frame was cleared at the start of function
-	//    We will do it again here. We can use BSSID instead
-	COPY_MAC_ADDR(pIAPP->DA, pAd->CommonCfg.Bssid);
-
-	// 7. SA is the client reporting which must be our MAC
-	COPY_MAC_ADDR(pIAPP->SA, pAd->CurrentAddress);
-
-	// 8. Copy the saved dialog token
-	pIAPP->Token = pAd->StaCfg.IAPPToken;
-
-	// 9. Make the Report frame 802.11 header
-	//    Reuse function in wpa.c
-	pHeader = (PHEADER_802_11) pAd->StaCfg.FrameReportBuf;
-	pAd->Sequence ++;
-	WpaMacHeaderInit(pAd, pHeader, 0, pAd->CommonCfg.Bssid);
-
-	// ACK size	is 14 include CRC, and its rate	is based on real time information
-	AckRate     = pAd->CommonCfg.ExpectedACKRate[pAd->CommonCfg.MlmeRate];
-	AckDuration = RTMPCalcDuration(pAd, AckRate, 14);
-	pHeader->Duration = pAd->CommonCfg.Dsifs + AckDuration;
-
-	// Use MLME enqueue method
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-	if (NStatus	!= NDIS_STATUS_SUCCESS)
-		return;
-
-	// 10. Prepare report frame with dynamic outbuffer. Just simply copy everything.
-	MakeOutgoingFrame(pOutBuffer,                       &FrameLen,
-	                  pAd->StaCfg.FrameReportLen, pAd->StaCfg.FrameReportBuf,
-		              END_OF_ARGS);
-
-	// 11. Send using priority queue
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	ChannelLoadReportAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PMEASUREMENT_REPORT_ELEMENT	pReport;
-	PCHANNEL_LOAD_REPORT		pLoad;
-	PUCHAR						pDest;
-	UCHAR						CCABusyFraction;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction ----->\n"));
-
-	// Disable Rx with promiscuous reception, make it back to normal
-	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
-
-	// 0. Setup pointer for processing beacon & probe response
-	pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
-	pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-
-	// 1. Fill Measurement report element field.
-	pReport->Eid    = IE_MEASUREMENT_REPORT;
-	// Fixed Length at 9, not include Eid and length fields
-	pReport->Length = 9;
-	pReport->Token  = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
-	pReport->Mode   = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
-	pReport->Type   = MSRN_TYPE_CHANNEL_LOAD_REQ;
-
-	// 2. Fill channel report measurement data
-	pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
-	pLoad  = (PCHANNEL_LOAD_REPORT) pDest;
-	pLoad->Channel  = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
-	pLoad->Spare    = 0;
-	pLoad->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
-
-	// 3. Calculate the CCA Busy Fraction
-	//    (Bytes + ACK size) * 8 / Tx speed * 255 / 1000 / measurement duration, use 24 us Tx speed
-	//     =  (Bytes + ACK) / 12 / duration
-	//     9 is the good value for pAd->StaCfg.CLFactor
-	// CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 9 / pLoad->Duration);
-	CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / pAd->StaCfg.CLFactor / pLoad->Duration);
-	if (CCABusyFraction < 10)
-			CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 3 / pLoad->Duration) + 1;
-
-	pLoad->CCABusy = CCABusyFraction;
-	DBGPRINT(RT_DEBUG_TRACE, ("CLBusyByte %ld, Duration %d, Result, %d\n", pAd->StaCfg.CLBusyBytes, pLoad->Duration, CCABusyFraction));
-
-	DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
-	pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(CHANNEL_LOAD_REPORT));
-	DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
-
-	// 4. Clear channel load measurement flag
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
-	// 5. reset to idle state
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	NoiseHistReportAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	PMEASUREMENT_REPORT_ELEMENT	pReport;
-	PNOISE_HIST_REPORT			pNoise;
-	PUCHAR						pDest;
-	UCHAR						i,NoiseCnt;
-	USHORT						TotalRPICnt, TotalRPISum;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction ----->\n"));
-
-	// 0. Disable Rx with promiscuous reception, make it back to normal
-	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
-	// 1. Setup pointer for processing beacon & probe response
-	pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
-	pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-
-	// 2. Fill Measurement report element field.
-	pReport->Eid    = IE_MEASUREMENT_REPORT;
-	// Fixed Length at 16, not include Eid and length fields
-	pReport->Length = 16;
-	pReport->Token  = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
-	pReport->Mode   = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
-	pReport->Type   = MSRN_TYPE_NOISE_HIST_REQ;
-
-	// 3. Fill noise histogram report measurement data
-	pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
-	pNoise  = (PNOISE_HIST_REPORT) pDest;
-	pNoise->Channel  = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
-	pNoise->Spare    = 0;
-	pNoise->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
-	// 4. Fill Noise histogram, the total RPI counts should be 0.4 * TU
-	//    We estimate 4000 normal packets received durning 10 seconds test.
-	//    Adjust it if required.
-	// 3 is a good value for pAd->StaCfg.NHFactor
-	// TotalRPICnt = pNoise->Duration * 3 / 10;
-	TotalRPICnt = pNoise->Duration * pAd->StaCfg.NHFactor / 10;
-	TotalRPISum = 0;
-
-	for (i = 0; i < 8; i++)
-	{
-		TotalRPISum += pAd->StaCfg.RPIDensity[i];
-		DBGPRINT(RT_DEBUG_TRACE, ("RPI %d Conuts %d\n", i, pAd->StaCfg.RPIDensity[i]));
-	}
-
-	// Double check if the counter is larger than our expectation.
-	// We will replace it with the total number plus a fraction.
-	if (TotalRPISum > TotalRPICnt)
-		TotalRPICnt = TotalRPISum + pNoise->Duration / 20;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Total RPI Conuts %d\n", TotalRPICnt));
-
-	// 5. Initialize noise count for the total summation of 0xff
-	NoiseCnt = 0;
-	for (i = 1; i < 8; i++)
-	{
-		pNoise->Density[i] = (UCHAR) (pAd->StaCfg.RPIDensity[i] * 255 / TotalRPICnt);
-		if ((pNoise->Density[i] == 0) && (pAd->StaCfg.RPIDensity[i] != 0))
-			pNoise->Density[i]++;
-		NoiseCnt += pNoise->Density[i];
-		DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[%d]  = 0x%02x\n", i, pNoise->Density[i]));
-	}
-
-	// 6. RPI[0] represents the rest of counts
-	pNoise->Density[0] = 0xff - NoiseCnt;
-	DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[0]  = 0x%02x\n", pNoise->Density[0]));
-
-	pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(NOISE_HIST_REPORT));
-
-	// 7. Clear channel load measurement flag
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
-
-	// 8. reset to idle state
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Prepare Beacon report action,
-
-	Arguments:
-		pAd	Pointer	to our adapter
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-VOID	BeaconReportAction(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Index)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction ----->\n"));
-
-	// Looks like we don't have anything thing need to do here.
-	// All measurement report already finished in AddBeaconReport
-	// The length is in the FrameReportLen
-
-	// reset Beacon index for next beacon request
-	pAd->StaCfg.LastBssIndex = 0xff;
-
-	// reset to idle state
-	pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction <-----\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Index		Current BSSID in CCXBsstab entry index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetAddBeaconReport(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	ULONG				Index,
-	IN	PMLME_QUEUE_ELEM	pElem)
-{
-	PVOID						pMsg;
-	PUCHAR						pSrc, pDest;
-	UCHAR						ReqIdx;
-	ULONG						MsgLen;
-	USHORT						Length;
-	PFRAME_802_11				pFrame;
-	PMEASUREMENT_REPORT_ELEMENT	pReport;
-	PEID_STRUCT			        pEid;
-	PBEACON_REPORT				pBeaconReport;
-	PBSS_ENTRY					pBss;
-
-	// 0. Setup pointer for processing beacon & probe response
-	pMsg   = pElem->Msg;
-	MsgLen = pElem->MsgLen;
-	pFrame = (PFRAME_802_11) pMsg;
-	pSrc   = pFrame->Octet;				// Start from AP TSF
-	pBss   = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
-	ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
-
-	// 1 Check the Index, if we already create this entry, only update the average RSSI
-	if ((Index <= pAd->StaCfg.LastBssIndex) && (pAd->StaCfg.LastBssIndex != 0xff))
-	{
-		pDest  = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.BssReportOffset[Index]];
-		// Point to bss report information
-		pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
-		pBeaconReport = (PBEACON_REPORT) pDest;
-
-		// Update Rx power, in dBm
-		// Get the original RSSI readback from BBP
-		pBeaconReport->RxPower += pAd->BbpRssiToDbmDelta;
-		// Average the Rssi reading
-		pBeaconReport->RxPower  = (pBeaconReport->RxPower + pBss->Rssi) / 2;
-		// Get to dBm format
-		pBeaconReport->RxPower -= pAd->BbpRssiToDbmDelta;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
-			pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
-			pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
-		DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld] Rssi %d, Avg Rssi %d\n", Index, (pBss->Rssi - pAd->BbpRssiToDbmDelta), pBeaconReport->RxPower - 256));
-		DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.BssReportOffset[Index]));
-
-		// Update other information here
-
-		// Done
-		return;
-	}
-
-	// 2. Update reported Index
-	pAd->StaCfg.LastBssIndex = Index;
-
-	// 3. Setup the buffer address for copying this BSSID into reporting frame
-	//    The offset should start after 802.11 header and report frame header.
-	pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
-
-	// 4. Save the start offset of each Bss in report frame
-	pAd->StaCfg.BssReportOffset[Index] = pAd->StaCfg.FrameReportLen;
-
-	// 5. Fill Measurement report fields
-	pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-	pReport->Eid = IE_MEASUREMENT_REPORT;
-	pReport->Length = 0;
-	pReport->Token  = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
-	pReport->Mode   = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
-	pReport->Type   = MSRN_TYPE_BEACON_REQ;
-	Length          = sizeof(MEASUREMENT_REPORT_ELEMENT);
-	pDest          += sizeof(MEASUREMENT_REPORT_ELEMENT);
-
-	// 6. Start thebeacon report format
-	pBeaconReport = (PBEACON_REPORT) pDest;
-	pDest        += sizeof(BEACON_REPORT);
-	Length       += sizeof(BEACON_REPORT);
-
-	// 7. Copy Channel number
-	pBeaconReport->Channel        = pBss->Channel;
-	pBeaconReport->Spare          = 0;
-	pBeaconReport->Duration       = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
-	pBeaconReport->PhyType        = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
-	// 8. Rx power, in dBm
-	pBeaconReport->RxPower        = pBss->Rssi - pAd->BbpRssiToDbmDelta;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
-		pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
-		pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
-	DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld], Rssi %d\n", Index, pBeaconReport->RxPower - 256));
-	DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.FrameReportLen));
-
-	pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
-	COPY_MAC_ADDR(pBeaconReport->BSSID, pFrame->Hdr.Addr3);
-	NdisMoveMemory(pBeaconReport->ParentTSF, pSrc, 4);
-	NdisMoveMemory(pBeaconReport->TargetTSF, &pElem->TimeStamp.u.LowPart, 4);
-	NdisMoveMemory(&pBeaconReport->TargetTSF[4], &pElem->TimeStamp.u.HighPart, 4);
-
-	// 9. Skip the beacon frame and offset to start of capabilityinfo since we already processed capabilityinfo
-	pSrc += (TIMESTAMP_LEN + 2);
-	pBeaconReport->CapabilityInfo = *(USHORT *)pSrc;
-
-	// 10. Point to start of element ID
-	pSrc += 2;
-	pEid = (PEID_STRUCT) pSrc;
-
-	// 11. Start process all variable Eid oayload and add the appropriate to the frame report
-	while (((PUCHAR) pEid + pEid->Len + 1) < ((PUCHAR) pFrame + MsgLen))
-	{
-		// Only limited EID are required to report for CCX 2. It includes SSID, Supported rate,
-		// FH paramenter set, DS parameter set, CF parameter set, IBSS parameter set,
-		// TIM (report first 4 bytes only, radio measurement capability
-		switch (pEid->Eid)
-		{
-			case IE_SSID:
-			case IE_SUPP_RATES:
-			case IE_FH_PARM:
-			case IE_DS_PARM:
-			case IE_CF_PARM:
-			case IE_IBSS_PARM:
-				NdisMoveMemory(pDest, pEid, pEid->Len + 2);
-				pDest  += (pEid->Len + 2);
-				Length += (pEid->Len + 2);
-				break;
-
-			case IE_MEASUREMENT_CAPABILITY:
-				// Since this IE is duplicated with WPA security IE, we has to do sanity check before
-				// recognize it.
-				// 1. It also has fixed 6 bytes IE length.
-				if (pEid->Len != 6)
-					break;
-				// 2. Check the Cisco Aironet OUI
-				if (NdisEqualMemory(CISCO_OUI, (pSrc + 2), 3))
-				{
-					// Matched, this is what we want
-					NdisMoveMemory(pDest, pEid, pEid->Len + 2);
-					pDest  += (pEid->Len + 2);
-					Length += (pEid->Len + 2);
-				}
-				break;
-
-			case IE_TIM:
-				if (pEid->Len > 4)
-				{
-					// May truncate and report the first 4 bytes only, with the eid & len, total should be 6
-					NdisMoveMemory(pDest, pEid, 6);
-					pDest  += 6;
-					Length += 6;
-				}
-				else
-				{
-					NdisMoveMemory(pDest, pEid, pEid->Len + 2);
-					pDest  += (pEid->Len + 2);
-					Length += (pEid->Len + 2);
-				}
-				break;
-
-			default:
-				break;
-		}
-		// 12. Move to next element ID
-		pSrc += (2 + pEid->Len);
-		pEid = (PEID_STRUCT) pSrc;
-	}
-
-	// 13. Update the length in the header, not include EID and length
-	pReport->Length = Length - 4;
-
-	// 14. Update the frame report buffer data length
-	pAd->StaCfg.FrameReportLen += Length;
-	DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Index		Current BSSID in CCXBsstab entry index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-VOID	AironetCreateBeaconReportFromBssTable(
-	IN	PRTMP_ADAPTER		pAd)
-{
-	PMEASUREMENT_REPORT_ELEMENT	pReport;
-	PBEACON_REPORT				pBeaconReport;
-	UCHAR						Index, ReqIdx;
-	USHORT						Length;
-	PUCHAR						pDest;
-	PBSS_ENTRY					pBss;
-
-	// 0. setup base pointer
-	ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
-
-	for (Index = 0; Index < pAd->StaCfg.CCXBssTab.BssNr; Index++)
-	{
-		// 1. Setup the buffer address for copying this BSSID into reporting frame
-		//    The offset should start after 802.11 header and report frame header.
-		pDest  = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
-		pBss   = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
-		Length = 0;
-
-		// 2. Fill Measurement report fields
-		pReport         = (PMEASUREMENT_REPORT_ELEMENT) pDest;
-		pReport->Eid    = IE_MEASUREMENT_REPORT;
-		pReport->Length = 0;
-		pReport->Token  = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
-		pReport->Mode   = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
-		pReport->Type   = MSRN_TYPE_BEACON_REQ;
-		Length          = sizeof(MEASUREMENT_REPORT_ELEMENT);
-		pDest          += sizeof(MEASUREMENT_REPORT_ELEMENT);
-
-		// 3. Start the beacon report format
-		pBeaconReport = (PBEACON_REPORT) pDest;
-		pDest        += sizeof(BEACON_REPORT);
-		Length       += sizeof(BEACON_REPORT);
-
-		// 4. Copy Channel number
-		pBeaconReport->Channel        = pBss->Channel;
-		pBeaconReport->Spare          = 0;
-		pBeaconReport->Duration       = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
-		pBeaconReport->PhyType        = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
-		pBeaconReport->RxPower        = pBss->Rssi - pAd->BbpRssiToDbmDelta;
-		pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
-		pBeaconReport->CapabilityInfo = pBss->CapabilityInfo;
-		COPY_MAC_ADDR(pBeaconReport->BSSID, pBss->Bssid);
-		NdisMoveMemory(pBeaconReport->ParentTSF, pBss->PTSF, 4);
-		NdisMoveMemory(pBeaconReport->TargetTSF, pBss->TTSF, 8);
-
-		// 5. Create SSID
-		*pDest++ = 0x00;
-		*pDest++ = pBss->SsidLen;
-		NdisMoveMemory(pDest, pBss->Ssid, pBss->SsidLen);
-		pDest  += pBss->SsidLen;
-		Length += (2 + pBss->SsidLen);
-
-		// 6. Create SupportRates
-		*pDest++ = 0x01;
-		*pDest++ = pBss->SupRateLen;
-		NdisMoveMemory(pDest, pBss->SupRate, pBss->SupRateLen);
-		pDest  += pBss->SupRateLen;
-		Length += (2 + pBss->SupRateLen);
-
-		// 7. DS Parameter
-		*pDest++ = 0x03;
-		*pDest++ = 1;
-		*pDest++ = pBss->Channel;
-		Length  += 3;
-
-		// 8. IBSS parameter if presents
-		if (pBss->BssType == BSS_ADHOC)
-		{
-			*pDest++ = 0x06;
-			*pDest++ = 2;
-			*(PUSHORT) pDest = pBss->AtimWin;
-			pDest   += 2;
-			Length  += 4;
-		}
-
-		// 9. Update length field, not include EID and length
-		pReport->Length = Length - 4;
-
-		// 10. Update total frame size
-		pAd->StaCfg.FrameReportLen += Length;
-	}
-}

+ 58 - 269
drivers/staging/rt2860/sta/assoc.c

@@ -149,7 +149,7 @@ VOID AssocTimeout(IN PVOID SystemSpecific1,
 		return;
 
 	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
-	RT28XX_MLME_HANDLER(pAd);
+	RTMP_MLME_HANDLER(pAd);
 }
 
 /*
@@ -177,7 +177,7 @@ VOID ReassocTimeout(IN PVOID SystemSpecific1,
 		return;
 
 	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
-	RT28XX_MLME_HANDLER(pAd);
+	RTMP_MLME_HANDLER(pAd);
 }
 
 /*
@@ -205,7 +205,7 @@ VOID DisassocTimeout(IN PVOID SystemSpecific1,
 		return;
 
 	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
-	RT28XX_MLME_HANDLER(pAd);
+	RTMP_MLME_HANDLER(pAd);
 }
 
 /*
@@ -236,7 +236,6 @@ VOID MlmeAssocReqAction(
 {
 	UCHAR			ApAddr[6];
 	HEADER_802_11	AssocHdr;
-	UCHAR			Ccx2Len = 5;
 	UCHAR			WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
 	USHORT			ListenIntv;
 	ULONG			Timeout;
@@ -247,13 +246,6 @@ VOID MlmeAssocReqAction(
 	ULONG			FrameLen = 0;
 	ULONG			tmp;
 	USHORT			VarIesOffset;
-	UCHAR			CkipFlag;
-	UCHAR			CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
-	UCHAR			AironetCkipIe = IE_AIRONET_CKIP;
-	UCHAR			AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
-	UCHAR			AironetIPAddressIE = IE_AIRONET_IPADDRESS;
-	UCHAR			AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
-	UCHAR			AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
 	USHORT			Status;
 
 	// Block all authentication request durning WPA block period
@@ -454,7 +446,8 @@ VOID MlmeAssocReqAction(
 				RSNIe = IE_WPA2;
 			}
 
-			if (pAd->StaCfg.WpaSupplicantUP != 1)
+			if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE) &&
+				(pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE))
             RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
 
             // Check for WPA PMK cache list
@@ -471,7 +464,18 @@ VOID MlmeAssocReqAction(
 						break;
 					}
 				}
-
+#ifdef RT2860
+				/*
+					When AuthMode is WPA2-Enterprise and AP reboot or STA lost AP,
+					AP would not do PMK cache with STA after STA re-connect to AP again.
+					In this case, driver doesn't need to send PMKID to AP and WpaSupplicant.
+				*/
+				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) &&
+					(NdisEqualMemory(pAd->MlmeAux.Bssid, pAd->CommonCfg.LastBssid, MAC_ADDR_LEN)))
+				{
+					FoundPMK = FALSE;
+				}
+#endif // RT2860 //
 				if (FoundPMK)
 				{
 					// Set PMK number
@@ -481,7 +485,8 @@ VOID MlmeAssocReqAction(
 				}
 			}
 
-			if (pAd->StaCfg.WpaSupplicantUP == 1)
+			if ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
+				(pAd->StaCfg.bRSN_IE_FromWpaSupplicant == TRUE))
 			{
 				MakeOutgoingFrame(pOutBuffer + FrameLen,    		&tmp,
 		                        	pAd->StaCfg.RSNIE_Len,			pAd->StaCfg.RSN_IE,
@@ -498,7 +503,8 @@ VOID MlmeAssocReqAction(
 
 			FrameLen += tmp;
 
-			if (pAd->StaCfg.WpaSupplicantUP != 1)
+			if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE) ||
+				(pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE))
 			{
 	            // Append Variable IE
 	            NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
@@ -513,53 +519,6 @@ VOID MlmeAssocReqAction(
 			pAd->StaCfg.ReqVarIELen = VarIesOffset;
 		}
 
-		// We have update that at PeerBeaconAtJoinRequest()
-		CkipFlag = pAd->StaCfg.CkipFlag;
-		if (CkipFlag != 0)
-		{
-			NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
-			CkipNegotiationBuffer[2] = 0x66;
-			// Make it try KP & MIC, since we have to follow the result from AssocRsp
-			CkipNegotiationBuffer[8] = 0x18;
-			CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
-			CkipFlag = 0x18;
-
-			MakeOutgoingFrame(pOutBuffer + FrameLen, 	&tmp,
-						1,						  		&AironetCkipIe,
-						1,						  		&AironetCkipLen,
-						AironetCkipLen, 		  		CkipNegotiationBuffer,
-						END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-		// Add CCX v2 request if CCX2 admin state is on
-		if (pAd->StaCfg.CCXControl.field.Enable == 1)
-		{
-
-			//
-			// Add AironetIPAddressIE for Cisco CCX 2.X
-			// Add CCX Version
-			//
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-						1,							&AironetIPAddressIE,
-						1,							&AironetIPAddressLen,
-						AironetIPAddressLen,		AironetIPAddressBuffer,
-						1,							&Ccx2Ie,
-						1,							&Ccx2Len,
-						Ccx2Len,				    Ccx2IeInfo,
-						END_OF_ARGS);
-			FrameLen += tmp;
-
-			// Add by James 03/06/27
-			// Set Variable IEs Length
-			pAd->StaCfg.ReqVarIELen = VarIesOffset;
-			pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset;
-
-			// OffsetResponseIEs follow ReqVarIE
-			pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen;
-			// End Add by James
-		}
-
 
 		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 		MlmeFreeMemory(pAd, pOutBuffer);
@@ -600,7 +559,6 @@ VOID MlmeReassocReqAction(
 {
 	UCHAR			ApAddr[6];
 	HEADER_802_11	ReassocHdr;
-	UCHAR			Ccx2Len = 5;
 	UCHAR			WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
 	USHORT			CapabilityInfo, ListenIntv;
 	ULONG			Timeout;
@@ -749,20 +707,6 @@ VOID MlmeReassocReqAction(
 			FrameLen += TmpLen;
 		}
 
-		// Add CCX v2 request if CCX2 admin state is on
-		if (pAd->StaCfg.CCXControl.field.Enable == 1)
-		{
-			//
-			// Add CCX Version
-			//
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-						1,							&Ccx2Ie,
-						1,							&Ccx2Len,
-						Ccx2Len,				    Ccx2IeInfo,
-						END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
 		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
 		MlmeFreeMemory(pAd, pOutBuffer);
 
@@ -800,9 +744,10 @@ VOID MlmeDisassocReqAction(
 	ULONG                 FrameLen = 0;
 	NDIS_STATUS           NStatus;
 	BOOLEAN               TimerCancelled;
-	ULONG                 Timeout = 0;
+	ULONG                 Timeout = 500;
 	USHORT                Status;
 
+
 	// skip sanity check
 	pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
 
@@ -845,11 +790,9 @@ VOID MlmeDisassocReqAction(
 	RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
 	pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
 
-    {
-        union iwreq_data    wrqu;
-        memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-        wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-    }
+
+	RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+
 }
 
 /*
@@ -876,7 +819,7 @@ VOID PeerAssocRspAction(
 	EDCA_PARM     EdcaParm;
 	HT_CAPABILITY_IE		HtCapability;
 	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
-	UCHAR			HtCapabilityLen;
+	UCHAR			HtCapabilityLen = 0;
 	UCHAR			AddHtInfoLen;
 	UCHAR			NewExtChannelOffset = 0xff;
 
@@ -889,24 +832,10 @@ VOID PeerAssocRspAction(
 			DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
 			DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",Elem->Wcid, pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
 			RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
-			if(Status == MLME_SUCCESS)
-			{
-#ifdef RT2860
-				// go to procedure listed on page 376
-				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
-					&EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
-
-                {
-                    union iwreq_data    wrqu;
-                    wext_notify_event_assoc(pAd);
 
-                    memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                    memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-                    wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
 
-                }
-#endif
-#ifdef RT2870
+			if(Status == MLME_SUCCESS)
+			{
 				UCHAR			MaxSupportedRateIn500Kbps = 0;
 				UCHAR			idx;
 
@@ -926,23 +855,14 @@ VOID PeerAssocRspAction(
 				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
 					&EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
 
-				StaAddMacTableEntry(pAd, &pAd->MacTab.Content[BSSID_WCID], MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo);
-#endif
-				pAd->StaCfg.CkipFlag = CkipFlag;
-				if (CkipFlag & 0x18)
-				{
-					NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
-					NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
-					NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
-					pAd->StaCfg.GIV[0] = RandomByte(pAd);
-					pAd->StaCfg.GIV[1] = RandomByte(pAd);
-					pAd->StaCfg.GIV[2] = RandomByte(pAd);
-					pAd->StaCfg.bCkipOn = TRUE;
-					DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
-				}
-			}
-			else
-			{
+				StaAddMacTableEntry(pAd,
+									&pAd->MacTab.Content[BSSID_WCID],
+									MaxSupportedRateIn500Kbps,
+									&HtCapability,
+									HtCapabilityLen,
+									&AddHtInfo,
+									AddHtInfoLen,
+									CapabilityInfo);
 			}
 			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
@@ -998,25 +918,19 @@ VOID PeerReassocRspAction(
 				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
 					 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
 
+
                 {
-                    union iwreq_data    wrqu;
                     wext_notify_event_assoc(pAd);
-
-                    memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                    memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-                    wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-
+                    RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, &pAd->MlmeAux.Bssid[0], NULL, 0);
                 }
 
 			}
 
-			{
 				// CkipFlag is no use for reassociate
 				pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 				MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
 			}
 		}
-	}
 	else
 	{
 		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
@@ -1123,6 +1037,10 @@ VOID AssocPostProc(
 
 			pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
 			len	 = pAd->ScanTab.BssEntry[Idx].VarIELen;
+			//KH need to check again
+			// Don't allow to go to sleep mode if authmode is WPA-related.
+			//This can make Authentication process more smoothly.
+			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 
 			while (len > 0)
 			{
@@ -1147,6 +1065,8 @@ VOID AssocPostProc(
 				pVIE += (pEid->Len + 2);
 				len  -= (pEid->Len + 2);
 			}
+
+
 		}
 
 		if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
@@ -1190,19 +1110,12 @@ VOID PeerDisassocAction(
 				RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
 			}
 
-			//
-			// Get Current System time and Turn on AdjacentAPReport
-			//
-			NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime);
-			pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
+
 			LinkDown(pAd, TRUE);
 			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
 
-            {
-                union iwreq_data    wrqu;
-                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-            }
+
+			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
 		}
 	}
 	else
@@ -1359,143 +1272,16 @@ VOID Cls3errAction(
 	COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
 }
 
- /*
-	 ==========================================================================
-	 Description:
-		 Switch between WEP and CKIP upon new association up.
-	 Parameters:
-
-	 IRQL = DISPATCH_LEVEL
-
-	 ==========================================================================
-  */
-VOID SwitchBetweenWepAndCkip(
-	IN PRTMP_ADAPTER pAd)
-{
-	int            i;
-	SHAREDKEY_MODE_STRUC  csr1;
-
-	// if KP is required. change the CipherAlg in hardware shard key table from WEP
-	// to CKIP. else remain as WEP
-	if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10))
-	{
-		// modify hardware key table so that MAC use correct algorithm to decrypt RX
-		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
-		if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64)
-			csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64;
-		else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128)
-			csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128;
-
-		if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64)
-			csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64;
-		else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128)
-			csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128;
-
-		if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64)
-			csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64;
-		else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128)
-			csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128;
-
-		if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64)
-			csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64;
-		else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128)
-			csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128;
-		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
-		DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
-
-		// modify software key table so that driver can specify correct algorithm in TXD upon TX
-		for (i=0; i<SHARE_KEY_NUM; i++)
-		{
-			if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP64)
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64;
-			else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128)
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128;
-		}
-	}
-
-	// else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP
-	// to WEP.
-	else
-	{
-		// modify hardware key table so that MAC use correct algorithm to decrypt RX
-		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
-		if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64)
-			csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64;
-		else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128)
-			csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128;
-
-		if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64)
-			csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64;
-		else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128)
-			csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128;
-
-		if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64)
-			csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64;
-		else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128)
-			csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128;
-
-		if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64)
-			csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64;
-		else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128)
-			csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128;
-
-		// modify software key table so that driver can specify correct algorithm in TXD upon TX
-		for (i=0; i<SHARE_KEY_NUM; i++)
-		{
-			if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64)
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64;
-			else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128)
-				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128;
-		}
-
-		//
-		// On WPA-NONE, must update CipherAlg.
-		// Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY
-		// and CipherAlg will be CIPHER_NONE by Windows ZeroConfig.
-		// So we need to update CipherAlg after connect.
-		//
-		if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-		{
-			for (i = 0; i < SHARE_KEY_NUM; i++)
-			{
-				if (pAd->SharedKey[BSS0][i].KeyLen != 0)
-				{
-					if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
-					{
-						pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP;
-					}
-					else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-					{
-						pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES;
-					}
-				}
-				else
-				{
-					pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
-				}
-			}
-
-			csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
-			csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg;
-			csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg;
-			csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg;
-		}
-		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
-		DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
-	}
-}
 
 int wext_notify_event_assoc(
 	IN  RTMP_ADAPTER *pAd)
 {
-    union iwreq_data    wrqu;
     char custom[IW_CUSTOM_MAX] = {0};
 
     if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
     {
-        wrqu.data.length = pAd->StaCfg.ReqVarIELen;
-        memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
-        wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom);
+		NdisMoveMemory(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
+		RtmpOSWrielessEventSend(pAd, IWEVASSOCREQIE, -1, NULL, custom, pAd->StaCfg.ReqVarIELen);
     }
     else
         DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
@@ -1504,13 +1290,15 @@ int wext_notify_event_assoc(
 
 }
 
-#ifdef RT2870
+
 BOOLEAN StaAddMacTableEntry(
 	IN  PRTMP_ADAPTER		pAd,
 	IN  PMAC_TABLE_ENTRY	pEntry,
 	IN  UCHAR				MaxSupportedRateIn500Kbps,
 	IN  HT_CAPABILITY_IE	*pHtCapability,
 	IN  UCHAR				HtCapabilityLen,
+	IN  ADD_HT_INFO_IE		*pAddHtInfo,
+	IN  UCHAR				AddHtInfoLen,
 	IN  USHORT        		CapabilityInfo)
 {
 	UCHAR            MaxSupportedRate = RATE_11;
@@ -1586,6 +1374,7 @@ BOOLEAN StaAddMacTableEntry(
 		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
 	}
 
+	NdisZeroMemory(&pEntry->HTCapability, sizeof(pEntry->HTCapability));
 	// If this Entry supports 802.11n, upgrade to HT rate.
 	if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
 	{
@@ -1605,7 +1394,9 @@ BOOLEAN StaAddMacTableEntry(
 			pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
 		}
 
-		if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+		if ((pHtCapability->HtCapInfo.ChannelWidth) &&
+			(pAd->CommonCfg.DesiredHtPhy.ChannelWidth) &&
+			((pAd->StaCfg.BssType == BSS_INFRA) || ((pAd->StaCfg.BssType == BSS_ADHOC) && (pAddHtInfo->AddHtInfo.ExtChanOffset == pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset))))
 		{
 			pEntry->MaxHTPhyMode.field.BW= BW_40;
 			pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40));
@@ -1677,14 +1468,13 @@ BOOLEAN StaAddMacTableEntry(
 			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
 		if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
 			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+		NdisMoveMemory(&pEntry->HTCapability, pHtCapability, HtCapabilityLen);
 	}
 	else
 	{
 		pAd->MacTab.fAnyStationIsLegacy = TRUE;
 	}
 
-	NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE));
-
 	pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
 	pEntry->CurrTxRate = pEntry->MaxSupportedRate;
 
@@ -1726,4 +1516,3 @@ BOOLEAN StaAddMacTableEntry(
     }
 	return TRUE;
 }
-#endif /* RT2870 */

+ 84 - 54
drivers/staging/rt2860/sta/auth.c

@@ -108,7 +108,7 @@ VOID AuthTimeout(
 
 
     MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
-    RT28XX_MLME_HANDLER(pAd);
+    RTMP_MLME_HANDLER(pAd);
 }
 
 
@@ -124,59 +124,12 @@ VOID MlmeAuthReqAction(
     IN PRTMP_ADAPTER pAd,
     IN MLME_QUEUE_ELEM *Elem)
 {
-    UCHAR              Addr[6];
-    USHORT             Alg, Seq, Status;
-    ULONG              Timeout;
-    HEADER_802_11      AuthHdr;
-    BOOLEAN            TimerCancelled;
-    NDIS_STATUS        NStatus;
-    PUCHAR             pOutBuffer = NULL;
-    ULONG              FrameLen = 0;
-
-	// Block all authentication request durning WPA block period
-	if (pAd->StaCfg.bBlockAssoc == TRUE)
-	{
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Block Auth request durning WPA block period!\n"));
-        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-        Status = MLME_STATE_MACHINE_REJECT;
-        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-	}
-    else if(MlmeAuthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr, &Timeout, &Alg))
-    {
-        // reset timer
-        RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
-        COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
-        pAd->MlmeAux.Alg  = Alg;
-        Seq = 1;
-        Status = MLME_SUCCESS;
-
-        NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
-        if(NStatus != NDIS_STATUS_SUCCESS)
-        {
-            DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", Alg));
-            pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-            Status = MLME_FAIL_NO_RESOURCE;
-            MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-            return;
-        }
-
-        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg));
-        MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid);
-        MakeOutgoingFrame(pOutBuffer,           &FrameLen,
-                          sizeof(HEADER_802_11),&AuthHdr,
-                          2,                    &Alg,
-                          2,                    &Seq,
-                          2,                    &Status,
-                          END_OF_ARGS);
-        MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-    	MlmeFreeMemory(pAd, pOutBuffer);
-
-        RTMPSetTimer(&pAd->MlmeAux.AuthTimer, Timeout);
+	if (AUTH_ReqSend(pAd, Elem, &pAd->MlmeAux.AuthTimer, "AUTH", 1, NULL, 0))
         pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
-    }
     else
     {
-        DBGPRINT_ERR(("AUTH - MlmeAuthReqAction() sanity check failed\n"));
+		USHORT Status;
+
         pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
         Status = MLME_INVALID_FORMAT;
         MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
@@ -207,7 +160,7 @@ VOID PeerAuthRspAtSeq2Action(
     ULONG         FrameLen = 0;
     USHORT        Status2;
 
-    if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
+    if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, (PCHAR)ChlgText))
     {
         if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2)
         {
@@ -217,8 +170,7 @@ VOID PeerAuthRspAtSeq2Action(
             if (Status == MLME_SUCCESS)
             {
                 // Authentication Mode "LEAP" has allow for CCX 1.X
-                if ((pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen)
-				)
+                if (pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen)
                 {
                     pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
                     MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
@@ -457,4 +409,82 @@ VOID Cls2errAction(
     COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
 }
 
+BOOLEAN	AUTH_ReqSend(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PMLME_QUEUE_ELEM	pElem,
+	IN  PRALINK_TIMER_STRUCT pAuthTimer,
+	IN  PSTRING				pSMName,
+	IN  USHORT				SeqNo,
+	IN  PUCHAR				pNewElement,
+	IN  ULONG				ElementLen)
+{
+	USHORT             Alg, Seq, Status;
+	UCHAR              Addr[6];
+    ULONG              Timeout;
+    HEADER_802_11      AuthHdr;
+    BOOLEAN            TimerCancelled;
+    NDIS_STATUS        NStatus;
+    PUCHAR             pOutBuffer = NULL;
+    ULONG              FrameLen = 0, tmp = 0;
+
+	// Block all authentication request durning WPA block period
+	if (pAd->StaCfg.bBlockAssoc == TRUE)
+	{
+        DBGPRINT(RT_DEBUG_TRACE, ("%s - Block Auth request durning WPA block period!\n", pSMName));
+        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+        Status = MLME_STATE_MACHINE_REJECT;
+        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+	}
+    else if(MlmeAuthReqSanity(pAd, pElem->Msg, pElem->MsgLen, Addr, &Timeout, &Alg))
+    {
+	/* reset timer */
+		RTMPCancelTimer(pAuthTimer, &TimerCancelled);
+
+        COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
+        pAd->MlmeAux.Alg  = Alg;
+        Seq = SeqNo;
+        Status = MLME_SUCCESS;
+
+        NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+        if(NStatus != NDIS_STATUS_SUCCESS)
+        {
+            DBGPRINT(RT_DEBUG_TRACE, ("%s - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", pSMName, Alg));
+            pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+            Status = MLME_FAIL_NO_RESOURCE;
+            MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+            return FALSE;
+        }
+
+        DBGPRINT(RT_DEBUG_TRACE, ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName, Alg));
+        MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid);
+        MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+                          sizeof(HEADER_802_11),&AuthHdr,
+                          2,                    &Alg,
+                          2,                    &Seq,
+                          2,                    &Status,
+                          END_OF_ARGS);
+
+		if (pNewElement && ElementLen)
+		{
+			MakeOutgoingFrame(pOutBuffer+FrameLen,	&tmp,
+							  ElementLen,			pNewElement,
+				  END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+        MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+		RTMPSetTimer(pAuthTimer, Timeout);
+		return TRUE;
+    }
+    else
+    {
+        DBGPRINT_ERR(("%s - MlmeAuthReqAction() sanity check failed\n", pSMName));
+		return FALSE;
+    }
+
+	return TRUE;
+}
+
 

+ 10 - 6
drivers/staging/rt2860/sta/auth_rsp.c

@@ -123,20 +123,24 @@ VOID PeerDeauthAction(
 
     if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
     {
-        if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid))
+        if (INFRA_ON(pAd)
+			&& MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid)
+			)
         {
             DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason));
 
-            {
-                union iwreq_data    wrqu;
-                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-            }
+
+		RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+
 
 			// send wireless event - for deauthentication
 			if (pAd->CommonCfg.bWirelessEvent)
 				RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
 
+			if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
+				(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
+				pAd->StaCfg.bLostAp = TRUE;
+
             LinkDown(pAd, TRUE);
         }
     }

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 227 - 259
drivers/staging/rt2860/sta/connect.c


+ 145 - 112
drivers/staging/rt2860/sta/rtmp_data.c

@@ -33,8 +33,6 @@
 	Revision History:
 	Who 		When			What
 	--------	----------		----------------------------------------------
-	John		      Aug/17/04		major modification for RT2561/2661
-	Jan Lee	      Mar/17/06		major modification for RT2860 New Ring Design
 */
 #include "../rt_config.h"
 
@@ -64,6 +62,7 @@ VOID STARxEAPOLFrameIndicate(
 				int     idx = 0;
 
 				DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
+				//pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
 				STA_PORT_SECURED(pAd);
 
                 if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)
@@ -74,7 +73,7 @@ VOID STARxEAPOLFrameIndicate(
 
                     if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
     				{
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 						MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
 
 						// Set key material and cipherAlg to Asic
@@ -88,8 +87,8 @@ VOID STARxEAPOLFrameIndicate(
 
                         pAd->IndicateMediaState = NdisMediaStateConnected;
                         pAd->ExtraInfo = GENERAL_LINK_UP;
-#endif
-#ifdef RT2870
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
 						union
 						{
 							char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1];
@@ -113,7 +112,7 @@ VOID STARxEAPOLFrameIndicate(
 						pAd->ExtraInfo = GENERAL_LINK_UP;
 						// need to enqueue cmd to thread
 						RTUSBEnqueueCmdFromNdis(pAd, OID_802_11_ADD_WEP, TRUE, &WepKey, sizeof(WepKey.keyinfo) + len - 1);
-#endif // RT2870 //
+#endif // RTMP_MAC_USB //
 						// For Preventing ShardKey Table is cleared by remove key procedure.
     					pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
 						pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
@@ -156,6 +155,7 @@ VOID STARxDataFrameAnnounce(
 	// non-EAP frame
 	if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
 	{
+
 		{
 			// drop all non-EAP DATA frame before
 			// this client's Port-Access-Control is secured
@@ -309,13 +309,13 @@ VOID STAHandleRxDataFrame(
 		if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
 		{
 			UCHAR *pData;
-			DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));
+			DBGPRINT(RT_DEBUG_INFO,("bAPSDCapable\n"));
 
 			// Qos bit 4
 			pData = (PUCHAR)pHeader + LENGTH_802_11;
 			if ((*pData >> 4) & 0x01)
 			{
-				DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
+				DBGPRINT(RT_DEBUG_INFO,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
 				pAd->CommonCfg.bInServicePeriod = FALSE;
 
 				// Force driver to fall into sleep mode when rcv EOSP frame
@@ -332,7 +332,7 @@ VOID STAHandleRxDataFrame(
 					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
 						TbttNumToNextWakeUp = NextDtim;
 
-					MlmeSetPsmBit(pAd, PWR_SAVE);
+					RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
 					// if WMM-APSD is failed, try to disable following line
 					AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
 				}
@@ -442,6 +442,23 @@ VOID STAHandleRxDataFrame(
 	}
 	pRxBlk->UserPriority = UserPriority;
 
+	/* check if need to resend PS Poll when received packet with MoreData = 1 */
+	if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1))
+	{
+		if ((((UserPriority == 0) || (UserPriority == 3)) &&
+			pAd->CommonCfg.bAPSDAC_BE == 0) ||
+			(((UserPriority == 1) || (UserPriority == 2)) &&
+			pAd->CommonCfg.bAPSDAC_BK == 0) ||
+			(((UserPriority == 4) || (UserPriority == 5)) &&
+			pAd->CommonCfg.bAPSDAC_VI == 0) ||
+			(((UserPriority == 6) || (UserPriority == 7)) &&
+			pAd->CommonCfg.bAPSDAC_VO == 0))
+		{
+			/* non-UAPSD delivery-enabled AC */
+			RTMP_PS_POLL_ENQUEUE(pAd);
+		}
+	}
+
 	// 3. Order bit: A-Ralink or HTC+
 	if (pHeader->FC.Order)
 	{
@@ -451,7 +468,7 @@ VOID STAHandleRxDataFrame(
 			RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
 		}
 		else
-#endif
+#endif // AGGREGATION_SUPPORT //
 		{
 			RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
 			// skip HTC contorl field
@@ -574,27 +591,31 @@ VOID STAHandleRxMgmtFrame(
 	do
 	{
 
+
+		/* check if need to resend PS Poll when received packet with MoreData = 1 */
+		if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1))
+		{
+			/* for UAPSD, all management frames will be VO priority */
+			if (pAd->CommonCfg.bAPSDAC_VO == 0)
+			{
+				/* non-UAPSD delivery-enabled AC */
+				RTMP_PS_POLL_ENQUEUE(pAd);
+			}
+		}
+
+		/* TODO: if MoreData == 0, station can go to sleep */
+
+
 		// We should collect RSSI not only U2M data but also my beacon
-		if (pAd->RxAnt.EvaluatePeriod == 0 &&
-		    pHeader->FC.SubType == SUBTYPE_BEACON &&
-		    MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)) {
+		if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
+			&& (pAd->RxAnt.EvaluatePeriod == 0))
+		{
 			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
 
 			pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
 			pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
 		}
 
-#ifdef RT2870
-		// collect rssi information for antenna diversity
-		if (pAd->NicConfig2.field.AntDiversity)
-		{
-			if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))))
-			{
-					COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxWI->RSSI0, RSSI_0), 0); //Note: RSSI2 not used on RT73
-					pAd->StaCfg.NumOfAvgRssiSample ++;
-			}
-		}
-#endif
 
 		// First check the size, it MUST not exceed the mlme queue size
 		if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
@@ -683,14 +704,14 @@ BOOLEAN STARxDoneInterruptHandle(
 			break;
 		}
 
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 		if (RxProcessed++ > MAX_RX_PROCESS_CNT)
 		{
 			// need to reschedule rx handle
 			bReschedule = TRUE;
 			break;
 		}
-#endif
+#endif // RTMP_MAC_PCI //
 
 		RxProcessed ++; // test
 
@@ -725,6 +746,7 @@ BOOLEAN STARxDoneInterruptHandle(
 
 		// Increase Total receive byte counter after real data received no mater any error or not
 		pAd->RalinkCounters.ReceivedByteCount +=  pRxWI->MPDUtotalByteCount;
+		pAd->RalinkCounters.OneSecReceivedByteCount +=  pRxWI->MPDUtotalByteCount;
 		pAd->RalinkCounters.RxCount ++;
 
 		INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
@@ -737,7 +759,8 @@ BOOLEAN STARxDoneInterruptHandle(
             send_monitor_packets(pAd, &RxCell);
 			break;
 		}
-		/* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */
+
+		/* STARxDoneInterruptHandle() is called in rtusb_bulk.c */
 
 		// Check for all RxD errors
 		Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
@@ -780,15 +803,6 @@ BOOLEAN STARxDoneInterruptHandle(
 		}
 	}
 
-#ifdef RT2860
-	// fRTMP_PS_GO_TO_SLEEP_NOW is set if receiving beacon.
-	if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW) && (INFRA_ON(pAd)))
-	{
-		RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-		AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp);
-		bReschedule = FALSE;
-	}
-#endif
 	return bReschedule;
 }
 
@@ -806,12 +820,7 @@ BOOLEAN STARxDoneInterruptHandle(
 VOID	RTMPHandleTwakeupInterrupt(
 	IN PRTMP_ADAPTER pAd)
 {
-#ifdef RT2860
-	AsicForceWakeup(pAd, DOT11POWERSAVE);
-#endif
-#ifdef RT2870
 	AsicForceWakeup(pAd, FALSE);
-#endif
 }
 
 /*
@@ -914,6 +923,7 @@ NDIS_STATUS STASendPacket(
 	UINT			SrcBufLen;
 	UINT			AllowFragSize;
 	UCHAR			NumberOfFrag;
+	UCHAR			RTSRequired;
 	UCHAR			QueIdx, UserPriority;
 	MAC_TABLE_ENTRY *pEntry = NULL;
 	unsigned int 	IrqFlags;
@@ -1052,7 +1062,14 @@ NDIS_STATUS STASendPacket(
 	//	   If multiple fragment required, RTS is required only for the first fragment
 	//	   if the fragment size large than RTS threshold
 	//     For RT28xx, Let ASIC send RTS/CTS
-	RTMP_SET_PACKET_RTS(pPacket, 0);
+//	RTMP_SET_PACKET_RTS(pPacket, 0);
+	if (NumberOfFrag > 1)
+		RTSRequired = (pAd->CommonCfg.FragmentThreshold > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
+	else
+		RTSRequired = (PacketInfo.TotalPacketLength > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
+
+	// Save RTS requirement to Ndis packet reserved field
+	RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
 	RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
 
 	//
@@ -1060,13 +1077,8 @@ NDIS_STATUS STASendPacket(
 	//
 	UserPriority = 0;
 	QueIdx		 = QID_AC_BE;
-#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(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
-#endif
 	{
 		USHORT Protocol;
 		UCHAR  LlcSnapLen = 0, Byte0, Byte1;
@@ -1102,6 +1114,11 @@ NDIS_STATUS STASendPacket(
 
 			// TODO: have to check ACM bit. apply TSPEC if ACM is ON
 			// TODO: downgrade UP & QueIdx before passing ACM
+			/*
+				Under WMM ACM control, we dont need to check the bit;
+				Or when a TSPEC is built for VO but we will change to issue
+				BA session for BE here, so we will not use BA to send VO packets.
+			*/
 			if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
 			{
 				UserPriority = 0;
@@ -1125,18 +1142,14 @@ NDIS_STATUS STASendPacket(
 	}
 	else
 	{
-		InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
+		InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
 	}
 	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
 
     if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
-#ifdef RT2860
-        (pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
-#endif
-#ifdef RT2870
         IS_HT_STA(pEntry))
-#endif
 	{
+	    //PMAC_TABLE_ENTRY pMacEntry = &pAd->MacTab.Content[BSSID_WCID];
 		if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
             ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
             (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
@@ -1145,10 +1158,10 @@ NDIS_STATUS STASendPacket(
 			 // 2. It is OPEN or AES mode,
 			 // then BA session can be bulit.
 			 && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
-			 	 (pEntry->WepStatus == Ndis802_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled))
+				 (pEntry->WepStatus != Ndis802_11WEPEnabled && pEntry->WepStatus != Ndis802_11Encryption2Enabled))
 			)
 		{
-			BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE);
+			BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10, FALSE);
 		}
 	}
 
@@ -1179,27 +1192,15 @@ NDIS_STATUS STASendPacket(
 
 	========================================================================
 */
-
-#ifdef RT2870
-/*
-	Actually, this function used to check if the TxHardware Queue still has frame need to send.
-	If no frame need to send, go to sleep, else, still wake up.
-*/
-#endif
+#ifdef RTMP_MAC_PCI
 NDIS_STATUS RTMPFreeTXDRequest(
 	IN		PRTMP_ADAPTER	pAd,
 	IN		UCHAR			QueIdx,
 	IN		UCHAR			NumberRequired,
 	IN		PUCHAR			FreeNumberIs)
 {
-#ifdef RT2860
 	ULONG		FreeNumber = 0;
-#endif
 	NDIS_STATUS 	Status = NDIS_STATUS_FAILURE;
-#ifdef RT2870
-	unsigned long   IrqFlags;
-	HT_TX_CONTEXT	*pHTTXContext;
-#endif
 
 	switch (QueIdx)
 	{
@@ -1208,7 +1209,6 @@ NDIS_STATUS RTMPFreeTXDRequest(
 		case QID_AC_VI:
 		case QID_AC_VO:
 		case QID_HCCA:
-#ifdef RT2860
 			if (pAd->TxRing[QueIdx].TxSwFreeIdx > pAd->TxRing[QueIdx].TxCpuIdx)
 				FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx - pAd->TxRing[QueIdx].TxCpuIdx - 1;
 			else
@@ -1216,8 +1216,49 @@ NDIS_STATUS RTMPFreeTXDRequest(
 
 			if (FreeNumber >= NumberRequired)
 				Status = NDIS_STATUS_SUCCESS;
-#endif
-#ifdef RT2870
+			break;
+
+		case QID_MGMT:
+			if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
+				FreeNumber = pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - 1;
+			else
+				FreeNumber = pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - pAd->MgmtRing.TxCpuIdx - 1;
+
+			if (FreeNumber >= NumberRequired)
+				Status = NDIS_STATUS_SUCCESS;
+			break;
+
+		default:
+			DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
+			break;
+	}
+	*FreeNumberIs = (UCHAR)FreeNumber;
+
+	return (Status);
+}
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+/*
+	Actually, this function used to check if the TxHardware Queue still has frame need to send.
+	If no frame need to send, go to sleep, else, still wake up.
+*/
+NDIS_STATUS RTMPFreeTXDRequest(
+	IN		PRTMP_ADAPTER	pAd,
+	IN		UCHAR			QueIdx,
+	IN		UCHAR			NumberRequired,
+	IN		PUCHAR			FreeNumberIs)
+{
+	//ULONG		FreeNumber = 0;
+	NDIS_STATUS	Status = NDIS_STATUS_FAILURE;
+	unsigned long   IrqFlags;
+	HT_TX_CONTEXT	*pHTTXContext;
+
+	switch (QueIdx)
+	{
+		case QID_AC_BK:
+		case QID_AC_BE:
+		case QID_AC_VI:
+		case QID_AC_VO:
 			{
 				pHTTXContext = &pAd->TxContext[QueIdx];
 				RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
@@ -1232,39 +1273,21 @@ NDIS_STATUS RTMPFreeTXDRequest(
 				}
 				RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
 			}
-#endif
 			break;
-
 		case QID_MGMT:
-#ifdef RT2860
-			if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
-				FreeNumber = pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - 1;
-			else
-				FreeNumber = pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - pAd->MgmtRing.TxCpuIdx - 1;
-
-			if (FreeNumber >= NumberRequired)
-				Status = NDIS_STATUS_SUCCESS;
-#endif
-#ifdef RT2870
 			if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
 				Status = NDIS_STATUS_FAILURE;
 			else
 				Status = NDIS_STATUS_SUCCESS;
-#endif
 			break;
-
 		default:
 			DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
 			break;
 	}
-#ifdef RT2860
-	*FreeNumberIs = (UCHAR)FreeNumber;
-#endif
 
 	return (Status);
 }
-
-
+#endif // RTMP_MAC_USB //
 
 VOID RTMPSendDisassociationFrame(
 	IN	PRTMP_ADAPTER	pAd)
@@ -1527,6 +1550,9 @@ VOID STABuildCache802_11Header(
     pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
 
 	{
+		// Check if the frame can be sent through DLS direct link interface
+		// If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
+
 		// The addr3 of normal packet send from DS is Dest Mac address.
 		if (ADHOC_ON(pAd))
 			COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
@@ -1580,13 +1606,13 @@ static inline PUCHAR STA_Build_ARalink_Frame_Header(
 
 	// padding at front of LLC header. LLC header should at 4-bytes aligment.
 	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4);
+	pHeaderBufPtr = (PUCHAR)ROUND_UP(pHeaderBufPtr, 4);
 	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
 	// For RA Aggregation,
 	// put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
 	pQEntry = pTxBlk->TxPacketList.Head;
-	pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry);
+	pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
 	nextBufLen = GET_OS_PKT_LEN(pNextPacket);
 	if (RTMP_GET_PACKET_VLAN(pNextPacket))
 		nextBufLen -= LENGTH_802_1Q;
@@ -1641,7 +1667,7 @@ static inline PUCHAR STA_Build_AMSDU_Frame_Header(
 	// @@@ MpduHeaderLen excluding padding @@@
 	//
 	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+	pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
 	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
 	return pHeaderBufPtr;
@@ -1743,7 +1769,7 @@ VOID STA_AMPDU_Frame_Tx(
 		// @@@ MpduHeaderLen excluding padding @@@
 		//
 		pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-		pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+		pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
 		pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
 		{
@@ -1790,9 +1816,7 @@ VOID STA_AMPDU_Frame_Tx(
 		//
 		// Kick out Tx
 		//
-#ifdef RT2860
 		if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-#endif
 			HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 
 		pAd->RalinkCounters.KickTxCount++;
@@ -1923,9 +1947,7 @@ VOID STA_AMSDU_Frame_Tx(
 	//
 	// Kick out Tx
 	//
-#ifdef RT2860
 	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-#endif
 		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 }
 
@@ -1991,7 +2013,7 @@ VOID STA_Legacy_Frame_Tx(
 		//
 		// build QOS Control bytes
 		//
-		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+		*(pHeaderBufPtr) = ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx]<<5));
 		*(pHeaderBufPtr+1) = 0;
 		pHeaderBufPtr +=2;
 		pTxBlk->MpduHeaderLen += 2;
@@ -1999,7 +2021,7 @@ VOID STA_Legacy_Frame_Tx(
 
 	// The remaining content of MPDU header should locate at 4-octets aligment
 	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+	pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
 	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
 	{
@@ -2045,9 +2067,7 @@ VOID STA_Legacy_Frame_Tx(
 	//
 	// Kick out Tx
 	//
-#ifdef RT2860
 	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-#endif
 		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 }
 
@@ -2158,9 +2178,7 @@ VOID STA_ARalink_Frame_Tx(
 	//
 	// Kick out Tx
 	//
-#ifdef RT2860
 	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-#endif
 		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 
 }
@@ -2181,6 +2199,7 @@ VOID STA_Fragment_Frame_Tx(
 	UINT 			NextMpduSize;
 	BOOLEAN			bVLANPkt;
 	PQUEUE_ENTRY	pQEntry;
+	HTTRANSMIT_SETTING	*pTransmit;
 
 
 	ASSERT(pTxBlk);
@@ -2243,7 +2262,7 @@ VOID STA_Fragment_Frame_Tx(
 	// LLC header should locate at 4-octets aligment
 	//
 	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
-	pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+	pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4);
 	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
 
 
@@ -2276,6 +2295,7 @@ VOID STA_Fragment_Frame_Tx(
 	//	MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
 	if (pTxBlk->CipherAlg == CIPHER_TKIP)
 	{
+		RTMPCalculateMICValue(pAd, pTxBlk->pPacket, pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, 0);
 
 		// NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
 		//			to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
@@ -2301,8 +2321,20 @@ VOID STA_Fragment_Frame_Tx(
 	else
 		EncryptionOverhead = 0;
 
+	pTransmit = pTxBlk->pTransmit;
+	// Decide the TX rate
+	if (pTransmit->field.MODE == MODE_CCK)
+		pTxBlk->TxRate = pTransmit->field.MCS;
+	else if (pTransmit->field.MODE == MODE_OFDM)
+		pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE;
+	else
+		pTxBlk->TxRate = RATE_6_5;
+
 	// decide how much time an ACK/CTS frame will consume in the air
+	if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE)
 	AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
+	else
+		AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14);
 
 	// Init the total payload length of this frame.
 	SrcRemainingBytes = pTxBlk->SrcBufLen;
@@ -2365,6 +2397,7 @@ VOID STA_Fragment_Frame_Tx(
 	//
 	// Kick out Tx
 	//
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
 	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 }
 
@@ -2428,13 +2461,13 @@ NDIS_STATUS STAHardTransmit(
 	// not to change PSM bit, just send this frame out?
 	if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
 	{
-	    DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
-#ifdef RT2860
-		AsicForceWakeup(pAd, FROM_TX);
-#endif
-#ifdef RT2870
+	    DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n"));
+#ifdef RTMP_MAC_PCI
 		AsicForceWakeup(pAd, TRUE);
-#endif
+#endif // RTMP_MAC_PCI //
+#ifdef RTMP_MAC_USB
+		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_FORCE_WAKE_UP, NULL, 0);
+#endif // RTMP_MAC_USB //
 	}
 
 	// It should not change PSM bit, when APSD turn on.
@@ -2444,7 +2477,7 @@ NDIS_STATUS STAHardTransmit(
 	{
 		if ((pAd->StaCfg.Psm == PWR_SAVE) &&
             (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
-			MlmeSetPsmBit(pAd, PWR_ACTIVE);
+			RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
 	}
 
 	switch (pTxBlk->TxFrameType)

+ 2 - 42
drivers/staging/rt2860/sta/sanity.c

@@ -117,7 +117,7 @@ BOOLEAN PeerAssocRspSanity(
 	*pHtCapabilityLen = 0;
 	*pAddHtInfoLen = 0;
     COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-    Ptr = pFrame->Octet;
+    Ptr = (PCHAR)pFrame->Octet;
     Length += LENGTH_802_11;
 
     NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
@@ -213,28 +213,7 @@ BOOLEAN PeerAssocRspSanity(
 				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
 			}
 		break;
-            case IE_AIRONET_CKIP:
-                // 0. Check Aironet IE length, it must be larger or equal to 28
-                //    Cisco's AP VxWork version(will not be supported) used this IE length as 28
-                //    Cisco's AP IOS version used this IE length as 30
-                if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
-                break;
-
-                // 1. Copy CKIP flag byte to buffer for process
-                *pCkipFlag = *(pEid->Octet + 8);
-                break;
 
-            case IE_AIRONET_IPADDRESS:
-                if (pEid->Len != 0x0A)
-                break;
-
-                // Get Cisco Aironet IP information
-                if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
-                    NdisMoveMemory(pAd->StaCfg.AironetIPAddress, pEid->Octet + 4, 4);
-                break;
-
-            // CCX2, WMM use the same IE value
-            // case IE_CCX_V2:
             case IE_VENDOR_SPECIFIC:
                 // handle WME PARAMTER ELEMENT
                 if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
@@ -250,7 +229,7 @@ BOOLEAN PeerAssocRspSanity(
                     //pEdcaParm->bMoreDataAck    = FALSE; // pEid->Octet[0] & 0x80;
                     pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
                     pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
-                    ptr = &pEid->Octet[8];
+                    ptr = (PUCHAR)&pEid->Octet[8];
                     for (i=0; i<4; i++)
                     {
                         UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
@@ -262,23 +241,7 @@ BOOLEAN PeerAssocRspSanity(
                         ptr += 4; // point to next AC
                     }
                 }
-
-                // handle CCX IE
-                else
-                {
-                    // 0. Check the size and CCX admin control
-                    if (pAd->StaCfg.CCXControl.field.Enable == 0)
-                        break;
-                    if (pEid->Len != 5)
-                        break;
-
-                    // Turn CCX2 if matched
-                    if (NdisEqualMemory(pEid->Octet, Ccx2IeInfo, 5) == 1)
-                        pAd->StaCfg.CCXEnable = TRUE;
-                    break;
-                }
                 break;
-
             default:
                 DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid));
                 break;
@@ -288,9 +251,6 @@ BOOLEAN PeerAssocRspSanity(
         pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
     }
 
-    // Force CCX2 enable to TRUE for those AP didn't replay CCX v2 IE, we still force it to be on
-    if (pAd->StaCfg.CCXControl.field.Enable == 1)
-        pAd->StaCfg.CCXEnable = TRUE;
 
     return TRUE;
 }

+ 106 - 292
drivers/staging/rt2860/sta/sync.c

@@ -37,45 +37,8 @@
 */
 #include "../rt_config.h"
 
-#ifdef RT2860
-#define AC0_DEF_TXOP		0
-#define AC1_DEF_TXOP		0
-#define AC2_DEF_TXOP		94
-#define AC3_DEF_TXOP		47
 
-VOID	AdhocTurnOnQos(
-	IN  PRTMP_ADAPTER pAd)
-{
-	// Turn on QOs if use HT rate.
-	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
-	{
-		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
-		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
-		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
-		pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
-		pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
-
-		pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
-		pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
-
-		pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
-		pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
-		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
-
-		pAd->CommonCfg.APEdcaParm.Txop[0]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[1]  = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[2]  = AC2_DEF_TXOP;
-		pAd->CommonCfg.APEdcaParm.Txop[3]  = AC3_DEF_TXOP;
-	}
-	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
-}
-#endif /* RT2860 */
-#ifdef RT2870
 #define ADHOC_ENTRY_BEACON_LOST_TIME	(2*OS_HZ)	// 2 sec
-#endif
 
 /*
 	==========================================================================
@@ -160,7 +123,7 @@ VOID BeaconTimeout(
 	}
 
 	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
-	RT28XX_MLME_HANDLER(pAd);
+	RTMP_MLME_HANDLER(pAd);
 }
 
 /*
@@ -188,8 +151,8 @@ VOID ScanTimeout(
 
 	if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
 	{
-		RT28XX_MLME_HANDLER(pAd);
-	}
+	RTMP_MLME_HANDLER(pAd);
+}
 	else
 	{
 		// To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
@@ -231,7 +194,7 @@ VOID MlmeScanReqAction(
 	// Increase the scan retry counters.
 	pAd->StaCfg.ScanCnt++;
 
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
     if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
         (IDLE_ON(pAd)) &&
 		(pAd->StaCfg.bRadio == TRUE) &&
@@ -239,30 +202,22 @@ VOID MlmeScanReqAction(
 	{
 		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
 	}
-#endif
+#endif // RTMP_MAC_PCI //
 
 	// first check the parameter sanity
 	if (MlmeScanReqSanity(pAd,
 						  Elem->Msg,
 						  Elem->MsgLen,
 						  &BssType,
-						  Ssid,
+						  (PCHAR)Ssid,
 						  &SsidLen,
 						  &ScanType))
 	{
 
 		// Check for channel load and noise hist request
 		// Suspend MSDU only at scan request, not the last two mentioned
-		if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD))
-		{
-			if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
-				RTMPSuspendMsduTransmission(pAd);			// Suspend MSDU transmission here
-		}
-		else
-		{
 			// Suspend MSDU transmission here
 			RTMPSuspendMsduTransmission(pAd);
-		}
 
 		//
 		// To prevent data lost.
@@ -304,11 +259,6 @@ VOID MlmeScanReqAction(
 		// start from the first channel
 		pAd->MlmeAux.Channel = FirstChannel(pAd);
 
-		// Change the scan channel when dealing with CCX beacon report
-		if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) ||
-			(ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE))
-			pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel;
-
 		// Let BBP register at 20MHz to do scan
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
 		BBPValue &= (~0x18);
@@ -352,7 +302,7 @@ VOID MlmeJoinReqAction(
 
 	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
 
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
     if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
         (IDLE_ON(pAd)) &&
 		(pAd->StaCfg.bRadio == TRUE) &&
@@ -360,7 +310,7 @@ VOID MlmeJoinReqAction(
 	{
 		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
 	}
-#endif
+#endif // RTMP_MAC_PCI //
 
 	// reset all the timers
 	RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
@@ -374,6 +324,7 @@ VOID MlmeJoinReqAction(
 	// If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
 	if (pBss->Hidden == 0)
 	{
+		RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
 		NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
 		pAd->MlmeAux.SsidLen = pBss->SsidLen;
 	}
@@ -382,10 +333,14 @@ VOID MlmeJoinReqAction(
 	pAd->MlmeAux.Channel = pBss->Channel;
 	pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
 
+
 	// Let BBP register at 20MHz to do scan
 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
 	BBPValue &= (~0x18);
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+#ifdef RT2860
+	pAd->CommonCfg.BBPCurrentBW = BW_20;
+#endif // RT2860 //
 	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
 
 	// switch channel and waiting for beacon timer
@@ -494,7 +449,7 @@ VOID MlmeStartReqAction(
 	TimeStamp.u.LowPart  = 0;
 	TimeStamp.u.HighPart = 0;
 
-	if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen))
+	if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, (PCHAR)Ssid, &SsidLen))
 	{
 		// reset all the timers
 		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
@@ -541,6 +496,7 @@ VOID MlmeStartReqAction(
 		{
 			pAd->MlmeAux.HtCapabilityLen = 0;
 			pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
 		}
 		// temporarily not support QOS in IBSS
 		NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
@@ -601,6 +557,8 @@ VOID PeerBeaconAtScanAction(
 	UCHAR			AddHtInfoLen;
 	UCHAR			NewExtChannelOffset = 0xff;
 
+
+	// NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
 	pFrame = (PFRAME_802_11) Elem->Msg;
 	// Init Variable IE structure
 	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
@@ -615,7 +573,7 @@ VOID PeerBeaconAtScanAction(
 								Elem->Channel,
 								Addr2,
 								Bssid,
-								Ssid,
+								(PCHAR)Ssid,
 								&SsidLen,
 								&BssType,
 								&BeaconPeriod,
@@ -661,24 +619,7 @@ VOID PeerBeaconAtScanAction(
 		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
 			HtCapabilityLen = SIZE_HT_CAP_IE;
 
-		if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel))
-		{
-			Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
-						 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability,
-						 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
-						 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
-			if (Idx != BSS_NOT_FOUND)
-			{
-				NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
-				NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
-				NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
-				if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ)
-					AironetAddBeaconReport(pAd, Idx, Elem);
-			}
-		}
-		else
-		{
-			Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+		Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (PCHAR)Ssid, SsidLen, BssType, BeaconPeriod,
 						  &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,  &HtCapability,
 						 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
 						 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
@@ -689,7 +630,7 @@ VOID PeerBeaconAtScanAction(
 				NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
 				NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
 			}
-		}
+
 	}
 	// sanity check fail, ignored
 }
@@ -731,6 +672,7 @@ VOID PeerBeaconAtJoinAction(
 	UCHAR			AddHtInfoLen;
 	UCHAR			NewExtChannelOffset = 0xff;
 	UCHAR			CentralChannel;
+	BOOLEAN			bAllowNrate = FALSE;
 
 	// Init Variable IE structure
 	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
@@ -745,7 +687,7 @@ VOID PeerBeaconAtJoinAction(
 								Elem->Channel,
 								Addr2,
 								Bssid,
-								Ssid,
+								(PCHAR)Ssid,
 								&SsidLen,
 								&BssType,
 								&BeaconPeriod,
@@ -818,7 +760,23 @@ VOID PeerBeaconAtJoinAction(
 			{
 				Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
 
+				if (Idx == BSS_NOT_FOUND)
+				{
+					CHAR Rssi = 0;
+					Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+					Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (CHAR *) Ssid, SsidLen, BssType, BeaconPeriod,
+										&Cf, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,  &HtCapability,
+										&AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
+										&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
 				if (Idx != BSS_NOT_FOUND)
+				{
+						NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
+						NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+						NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+						CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
+					}
+				}
+				else
 				{
 					//
 					// Multiple SSID case, used correct CapabilityInfo
@@ -847,13 +805,21 @@ VOID PeerBeaconAtJoinAction(
 
             NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
 
+
+			if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled))
+				|| (pAd->CommonCfg.HT_DisallowTKIP == FALSE))
+			{
+				bAllowNrate = TRUE;
+			}
+
 			pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
 			pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
 
+			RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
 			// filter out un-supported ht rates
-			if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+			if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) &&
+				((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (bAllowNrate)))
 			{
-				RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
    				RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
 
 				// StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
@@ -897,7 +863,9 @@ VOID PeerBeaconAtJoinAction(
 					pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
 
 				pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+				pAd->MlmeAux.NewExtChannelOffset = 0xff;
 				RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+				pAd->MlmeAux.HtCapabilityLen = 0;
 				RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
 			}
 
@@ -930,6 +898,8 @@ VOID PeerBeaconAtJoinAction(
 			else  //Used the default TX Power Percentage.
 				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
 
+			InitChannelRelatedValue(pAd);
+
 			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
 			Status = MLME_SUCCESS;
 			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
@@ -1116,8 +1086,6 @@ VOID PeerBeacon(
 			// Add the safeguard against the mismatch of adhoc wep status
 			if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
 			{
-				DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Not matched wep status %d %d\n", pAd->StaCfg.WepStatus, pAd->ScanTab.BssEntry[Bssidx].WepStatus));
-				DBGPRINT(RT_DEBUG_TRACE, ("bssid=%s\n", pAd->ScanTab.BssEntry[Bssidx].Bssid));
 				return;
 			}
 
@@ -1181,200 +1149,8 @@ VOID PeerBeacon(
 				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
 			}
 
-#ifdef RT2860
-			// at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps
-			// after last 11b peer left for several seconds, we'll auto switch back to 11G rate
-			// in MlmePeriodicExec()
-#endif
 			if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
 			{
-#ifdef RT2860
-				BOOLEAN	bRestart;
-                BOOLEAN	bnRestart;
-
-				bRestart = FALSE;
-                bnRestart = FALSE;
-
-				do
-				{
-					if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.MaxTxRate > RATE_11))
-					{
-						if (pAd->StaCfg.AdhocBOnlyJoined == FALSE)
-						{
-							DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11b peer joined. down-grade to 11b TX rates \n"));
-							bRestart = TRUE;
-							NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-							pAd->StaActive.SupRateLen = SupRateLen;
-							NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
-							pAd->StaActive.ExtRateLen = ExtRateLen;
-							pAd->StaCfg.AdhocBOnlyJoined = TRUE;
-							pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-							AsicSetEdcaParm(pAd, NULL);
-						}
-
-						// this timestamp is for MlmePeriodicExec() to check if all 11B peers have left
-						pAd->StaCfg.Last11bBeaconRxTime = Now;
-						break;
-					}
-
-					// Update Ht Phy.
-					if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
-					{
-						if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
-							!pAd->StaCfg.AdhocBGJoined &&
-							!pAd->StaCfg.AdhocBOnlyJoined)
-							AdhocTurnOnQos(pAd);
-
-						// Handle rate switch issue when Adhoc mode
-						if ((SupRateLen+ExtRateLen >= 8) && (HtCapability.MCSSet[0] == 0) && (HtCapability.MCSSet[1] == 0))
-						{
-							if (pAd->StaCfg.AdhocBGJoined == FALSE)
-							{
-								DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11g peer joined. down-grade to 11g TX rates \n"));
-								bRestart = TRUE;
-								NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-								pAd->StaActive.SupRateLen = SupRateLen;
-								NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
-								pAd->StaActive.ExtRateLen = ExtRateLen;
-								pAd->StaCfg.AdhocBGJoined = TRUE;
-								pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-								AsicSetEdcaParm(pAd, NULL);
-							}
-
-							// this timestamp is for MlmePeriodicExec() to check if all 11g peers have left
-							pAd->StaCfg.Last11gBeaconRxTime = Now;
-							break;
-						}
-						else if (!pAd->StaCfg.AdhocBGJoined &&
-								 !pAd->StaCfg.AdhocBOnlyJoined &&
-								 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) &&
-								 (HtCapability.HtCapInfo.ChannelWidth == BW_20))
-						{
-							if (pAd->StaCfg.Adhoc20NJoined == FALSE)
-							{
-								pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-
-								pAd->StaCfg.Adhoc20NJoined = TRUE;
-								NdisMoveMemory(&pAd->MlmeAux.HtCapability, &HtCapability, SIZE_HT_CAP_IE);
-								if (AddHtInfoLen != 0)
-									NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, AddHtInfoLen);
-								NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
-
-								RTMPCheckHt(pAd, Elem->Wcid, &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
-								COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
-								pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
-								bRestart = TRUE;
-								bnRestart = TRUE;
-							}
-							// this timestamp is for MlmePeriodicExec() to check if all 20MHz N peers have left
-							pAd->StaCfg.Last20NBeaconRxTime = Now;
-						}
-
-					}
-					else
-					{
-						RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
-						RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
-					}
-				}while (FALSE);
-
-				// If peer Adhoc is legacy mode, I don't need to call MlmeUpdateHtTxRates no matter I support HT or not
-				if ((bRestart == TRUE) && (bnRestart == FALSE))
-				{
-					MlmeUpdateTxRates(pAd, FALSE, 0);
-					MakeIbssBeacon(pAd);        // re-build BEACON frame
-					AsicEnableIbssSync(pAd);    // copy to on-chip memory
-				}
-				else if ((bRestart == TRUE) && (bnRestart == TRUE))
-				{
-					MlmeUpdateTxRates(pAd, FALSE, BSS0);
-					MlmeUpdateHtTxRates(pAd, BSS0);
-					MakeIbssBeacon(pAd);        // re-build BEACON frame
-					AsicEnableIbssSync(pAd);    // copy to on-chip memory
-				}
-
-				// At least another peer in this IBSS, declare MediaState as CONNECTED
-				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-				{
-					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-
-					pAd->IndicateMediaState = NdisMediaStateConnected;
-					RTMP_IndicateMediaState(pAd);
-	                pAd->ExtraInfo = GENERAL_LINK_UP;
-					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
-
-					// 2003/03/12 - john
-					// Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
-					// "site survey" result should always include the current connected network.
-					//
-					Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
-					if (Bssidx == BSS_NOT_FOUND)
-					{
-						Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
-									&CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
-									&AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
-									&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
-					}
-					DBGPRINT(RT_DEBUG_TRACE, ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
-				}
-
-				// Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
-				// To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
-				if (ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID))
-				{
-					UCHAR	idx;
-					MAC_TABLE_ENTRY *pEntry;
-
-					// look up the existing table
-					pEntry = MacTableLookup(pAd, Addr2);
-					if (pEntry == NULL)
-					{
-						// Another adhoc joining, add to our MAC table.
-						pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
-						if (pEntry)
-						{
-							pEntry->Sst = SST_ASSOC;
-							idx = pAd->StaCfg.DefaultKeyId;
-							// After InsertEntry, Write to ASIC on-chip table.
-							RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
-							DBGPRINT(RT_DEBUG_TRACE, ("ADHOC %x:%x:%x:%x:%x:%x  join in.Entry=%d\n", Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5], pEntry->Aid));
-
-							pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
-	                        if (HtCapabilityLen <= 0)
-	                        {
-	                            pEntry->HTPhyMode.field.STBC = 0;
-	                            pEntry->HTPhyMode.field.BW = 0;
-	                            pEntry->HTPhyMode.field.ShortGI = 0;
-	                            if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.Channel <= 14))
-	        					{
-	        						pEntry->HTPhyMode.field.MODE = MODE_CCK;
-	        					}
-	        					else
-	        					{
-	        						pEntry->HTPhyMode.field.MODE = MODE_OFDM;
-	        					}
-								MlmeUpdateTxRates(pAd, FALSE, 0);
-	                        }
-							else
-							{
-								MlmeUpdateTxRates(pAd, FALSE, 0);
-								MlmeUpdateHtTxRates(pAd, BSS0);
-							}
-
-	                        {
-	                            union iwreq_data    wrqu;
-	                            wext_notify_event_assoc(pAd);
-
-	                            memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-	                            memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-	                            wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-
-	                        }
-						}
-					}
-				}
-#endif /* RT2860 */
-#ifdef RT2870
 				UCHAR			MaxSupportedRateIn500Kbps = 0;
 				UCHAR			idx;
 				MAC_TABLE_ENTRY *pEntry;
@@ -1404,7 +1180,14 @@ VOID PeerBeacon(
 						// Another adhoc joining, add to our MAC table.
 						pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
 
-					if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE)
+					if (StaAddMacTableEntry(pAd,
+											pEntry,
+											MaxSupportedRateIn500Kbps,
+											&HtCapability,
+											HtCapabilityLen,
+											&AddHtInfo,
+											AddHtInfoLen,
+											CapabilityInfo) == FALSE)
 					{
 						DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
 						return;
@@ -1414,7 +1197,7 @@ VOID PeerBeacon(
 						(Elem->Wcid == RESERVED_WCID))
 					{
 						idx = pAd->StaCfg.DefaultKeyId;
-						RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
+						RTMP_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
 					}
 				}
 
@@ -1445,7 +1228,6 @@ VOID PeerBeacon(
 					}
 					DBGPRINT(RT_DEBUG_TRACE, ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
 				}
-#endif /* RT2870 */
 			}
 
 			if (INFRA_ON(pAd))
@@ -1534,28 +1316,32 @@ VOID PeerBeacon(
 				//  5. otherwise, put PHY back to sleep to save battery.
 				if (MessageToMe)
 				{
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
 					{
+						// Restore to correct BBP R3 value
+						if (pAd->Antenna.field.RxPath > 1)
 						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
+						// Turn clk to 80Mhz.
 					}
-#endif
+#endif // RTMP_MAC_PCI //
 					if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
 						pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
 					{
 						pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
 					}
 					else
-						RT28XX_PS_POLL_ENQUEUE(pAd);
+						RTMP_PS_POLL_ENQUEUE(pAd);
 				}
 				else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
 				{
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
 					{
+						if (pAd->Antenna.field.RxPath > 1)
 						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
 					}
-#endif
+#endif // RTMP_MAC_PCI //
 				}
 				else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)													||
 						(pAd->TxSwQueue[QID_AC_BE].Number != 0)														||
@@ -1569,12 +1355,42 @@ VOID PeerBeacon(
 				{
 					// TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
 					// can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
 					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
 					{
+						if (pAd->Antenna.field.RxPath > 1)
 						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
 					}
-#endif
+#endif // RTMP_MAC_PCI //
+				}
+				else
+				{
+					if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) ||
+						(pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) ||
+						(pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) ||
+						(pAd->CommonCfg.bACMAPSDTr[QID_AC_BE]))
+					{
+						/*
+							WMM Spec v1.0 3.6.2.4,
+							The WMM STA shall remain awake until it receives a
+							QoS Data or Null frame addressed to it, with the
+							EOSP subfield in QoS Control field set to 1.
+
+							So we can not sleep here or we will suffer a case:
+
+							PS Management Frame -->
+							Trigger frame -->
+							Beacon (TIM=0) (Beacon is closer to Trig frame) -->
+							Station goes to sleep -->
+							AP delivery queued UAPSD packets -->
+							Station can NOT receive the reply
+
+							Maybe we need a timeout timer to avoid that we do
+							NOT receive the EOSP frame.
+
+							We can not use More Data to check if SP is ended
+							due to MaxSPLength.
+						*/
 				}
 				else
 				{
@@ -1589,14 +1405,10 @@ VOID PeerBeacon(
 
 					if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
 					{
-#ifdef RT2860
 						// Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
-						RTMP_SET_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
 						pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp;
-#endif
-#ifdef RT2870
-						AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
-#endif
+		                                        AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp);
+						}
 					}
 				}
 			}
@@ -1825,6 +1637,8 @@ VOID InvalidStateWhenStart(
 VOID EnqueuePsPoll(
 	IN PRTMP_ADAPTER pAd)
 {
+
+
 	if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
     	pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
 	MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1807
drivers/staging/rt2860/sta/wpa.c


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 258 - 155
drivers/staging/rt2860/sta_ioctl.c


+ 897 - 0
drivers/staging/rt2860/usb_main_dev.c

@@ -0,0 +1,897 @@
+/*
+ *************************************************************************
+ * 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.             *
+ *                                                                       *
+ *************************************************************************/
+
+#include "rt_config.h"
+
+
+// Following information will be show when you run 'modinfo'
+// *** If you have a solution for the bug in current version of driver, please mail to me.
+// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
+MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
+MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver");
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(STA_DRIVER_VERSION);
+#endif
+
+
+/* module table */
+struct usb_device_id rtusb_usb_id[] = {
+#ifdef RT2870
+	{USB_DEVICE(0x148F,0x2770)}, /* Ralink */
+	{USB_DEVICE(0x148F,0x2870)}, /* Ralink */
+	{USB_DEVICE(0x07B8,0x2870)}, /* AboCom */
+	{USB_DEVICE(0x07B8,0x2770)}, /* AboCom */
+	{USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom 2770 */
+	{USB_DEVICE(0x083A,0x7512)}, /* Arcadyan 2770 */
+	{USB_DEVICE(0x0789,0x0162)}, /* Logitec 2870 */
+	{USB_DEVICE(0x0789,0x0163)}, /* Logitec 2870 */
+	{USB_DEVICE(0x0789,0x0164)}, /* Logitec 2870 */
+	{USB_DEVICE(0x177f,0x0302)}, /* lsusb */
+	{USB_DEVICE(0x0B05,0x1731)}, /* Asus */
+	{USB_DEVICE(0x0B05,0x1732)}, /* Asus */
+	{USB_DEVICE(0x0B05,0x1742)}, /* Asus */
+	{USB_DEVICE(0x0DF6,0x0017)}, /* Sitecom */
+	{USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */
+	{USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */
+	{USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */
+	{USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */
+	{USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */
+	{USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */
+	{USB_DEVICE(0x07D1,0x3C09)}, /* D-Link */
+	{USB_DEVICE(0x07D1,0x3C11)}, /* D-Link */
+	{USB_DEVICE(0x14B2,0x3C07)}, /* AL */
+	{USB_DEVICE(0x050D,0x8053)}, /* Belkin */
+	{USB_DEVICE(0x14B2,0x3C23)}, /* Airlink */
+	{USB_DEVICE(0x14B2,0x3C27)}, /* Airlink */
+	{USB_DEVICE(0x07AA,0x002F)}, /* Corega */
+	{USB_DEVICE(0x07AA,0x003C)}, /* Corega */
+	{USB_DEVICE(0x07AA,0x003F)}, /* Corega */
+	{USB_DEVICE(0x1044,0x800B)}, /* Gigabyte */
+	{USB_DEVICE(0x15A9,0x0006)}, /* Sparklan */
+	{USB_DEVICE(0x083A,0xB522)}, /* SMC */
+	{USB_DEVICE(0x083A,0xA618)}, /* SMC */
+	{USB_DEVICE(0x083A,0x8522)}, /* Arcadyan */
+	{USB_DEVICE(0x083A,0x7522)}, /* Arcadyan */
+	{USB_DEVICE(0x0CDE,0x0022)}, /* ZCOM */
+	{USB_DEVICE(0x0586,0x3416)}, /* Zyxel */
+	{USB_DEVICE(0x0CDE,0x0025)}, /* Zyxel */
+	{USB_DEVICE(0x1740,0x9701)}, /* EnGenius */
+	{USB_DEVICE(0x1740,0x9702)}, /* EnGenius */
+	{USB_DEVICE(0x0471,0x200f)}, /* Philips */
+	{USB_DEVICE(0x14B2,0x3C25)}, /* Draytek */
+	{USB_DEVICE(0x13D3,0x3247)}, /* AzureWave */
+	{USB_DEVICE(0x083A,0x6618)}, /* Accton */
+	{USB_DEVICE(0x15c5,0x0008)}, /* Amit */
+	{USB_DEVICE(0x0E66,0x0001)}, /* Hawking */
+	{USB_DEVICE(0x0E66,0x0003)}, /* Hawking */
+	{USB_DEVICE(0x129B,0x1828)}, /* Siemens */
+	{USB_DEVICE(0x157E,0x300E)},	/* U-Media */
+	{USB_DEVICE(0x050d,0x805c)},
+	{USB_DEVICE(0x050d,0x815c)},
+	{USB_DEVICE(0x1482,0x3C09)}, /* Abocom*/
+	{USB_DEVICE(0x14B2,0x3C09)}, /* Alpha */
+	{USB_DEVICE(0x04E8,0x2018)}, /* samsung */
+	{USB_DEVICE(0x5A57,0x0280)}, /* Zinwell */
+	{USB_DEVICE(0x5A57,0x0282)}, /* Zinwell */
+	{USB_DEVICE(0x7392,0x7718)},
+	{USB_DEVICE(0x7392,0x7717)},
+	{USB_DEVICE(0x1737,0x0070)}, /* Linksys WUSB100 */
+	{USB_DEVICE(0x1737,0x0071)}, /* Linksys WUSB600N */
+	{USB_DEVICE(0x0411,0x00e8)}, /* Buffalo WLI-UC-G300N*/
+	{USB_DEVICE(0x050d,0x815c)}, /* Belkin F5D8053 */
+#endif // RT2870 //
+#ifdef RT3070
+	{USB_DEVICE(0x148F,0x3070)}, /* Ralink 3070 */
+	{USB_DEVICE(0x148F,0x3071)}, /* Ralink 3071 */
+	{USB_DEVICE(0x148F,0x3072)}, /* Ralink 3072 */
+	{USB_DEVICE(0x0DB0,0x3820)}, /* Ralink 3070 */
+	{USB_DEVICE(0x0DF6,0x003E)}, /* Sitecom 3070 */
+	{USB_DEVICE(0x0DF6,0x0042)}, /* Sitecom 3072 */
+	{USB_DEVICE(0x14B2,0x3C12)}, /* AL 3070 */
+	{USB_DEVICE(0x18C5,0x0012)}, /* Corega 3070 */
+	{USB_DEVICE(0x083A,0x7511)}, /* Arcadyan 3070 */
+	{USB_DEVICE(0x1740,0x9703)}, /* EnGenius 3070 */
+	{USB_DEVICE(0x1740,0x9705)}, /* EnGenius 3071 */
+	{USB_DEVICE(0x1740,0x9706)}, /* EnGenius 3072 */
+	{USB_DEVICE(0x13D3,0x3273)}, /* AzureWave 3070*/
+	{USB_DEVICE(0x1044,0x800D)}, /* Gigabyte GN-WB32L 3070 */
+	{USB_DEVICE(0x2019,0xAB25)}, /* Planex Communications, Inc. RT3070 */
+	{USB_DEVICE(0x07B8,0x3070)}, /* AboCom 3070 */
+	{USB_DEVICE(0x07B8,0x3071)}, /* AboCom 3071 */
+	{USB_DEVICE(0x07B8,0x3072)}, /* Abocom 3072 */
+	{USB_DEVICE(0x7392,0x7711)}, /* Edimax 3070 */
+	{USB_DEVICE(0x1A32,0x0304)}, /* Quanta 3070 */
+	{USB_DEVICE(0x1EDA,0x2310)}, /* AirTies 3070 */
+	{USB_DEVICE(0x07D1,0x3C0A)}, /* D-Link 3072 */
+	{USB_DEVICE(0x07D1,0x3C0D)}, /* D-Link 3070 */
+	{USB_DEVICE(0x07D1,0x3C0E)}, /* D-Link 3070 */
+	{USB_DEVICE(0x07D1,0x3C0F)}, /* D-Link 3070 */
+	{USB_DEVICE(0x1D4D,0x000C)}, /* Pegatron Corporation 3070 */
+	{USB_DEVICE(0x1D4D,0x000E)}, /* Pegatron Corporation 3070 */
+	{USB_DEVICE(0x5A57,0x5257)}, /* Zinwell 3070 */
+	{USB_DEVICE(0x5A57,0x0283)}, /* Zinwell 3072 */
+	{USB_DEVICE(0x04BB,0x0945)}, /* I-O DATA 3072 */
+	{USB_DEVICE(0x203D,0x1480)}, /* Encore 3070 */
+#endif // RT3070 //
+	{ USB_DEVICE(0x0DF6, 0x003F) }, /* Sitecom WL-608 */
+	{ USB_DEVICE(0x1737, 0x0077) }, /* Linksys WUSB54GC-EU v3 */
+	{ USB_DEVICE(0x2001, 0x3C09) }, /* D-Link */
+	{ USB_DEVICE(0x2001, 0x3C0A) }, /* D-Link 3072*/
+	{ USB_DEVICE(0x2019, 0xED14) }, /* Planex Communications, Inc. */
+	{ }/* Terminating entry */
+};
+
+INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
+
+MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
+
+static void rt2870_disconnect(
+	IN struct usb_device *dev,
+	IN PRTMP_ADAPTER pAd);
+
+static int __devinit rt2870_probe(
+	IN struct usb_interface *intf,
+	IN struct usb_device *usb_dev,
+	IN const struct usb_device_id *dev_id,
+	IN RTMP_ADAPTER **ppAd);
+
+#ifndef PF_NOFREEZE
+#define PF_NOFREEZE  0
+#endif
+
+
+extern int rt28xx_close(IN struct net_device *net_dev);
+extern int rt28xx_open(struct net_device *net_dev);
+
+static BOOLEAN USBDevConfigInit(
+	IN struct usb_device	*dev,
+	IN struct usb_interface *intf,
+	IN RTMP_ADAPTER *pAd);
+
+
+/*
+========================================================================
+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)
+{
+	struct usb_interface *intf = (struct usb_interface *)_dev_p;
+	struct usb_device *dev_p = interface_to_usbdev(intf);
+	UINT32 i;
+
+
+	for(i=0; i<rtusb_usb_id_len; i++)
+	{
+		if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
+			dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
+		{
+			printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
+					dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
+			break;
+		}
+	}
+
+	if (i == rtusb_usb_id_len)
+	{
+		printk("rt2870: Error! Device Descriptor not matching!\n");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/**************************************************************************/
+/**************************************************************************/
+//tested for kernel 2.6series
+/**************************************************************************/
+/**************************************************************************/
+
+#ifdef CONFIG_PM
+static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
+static int rt2870_resume(struct usb_interface *intf);
+#endif // CONFIG_PM //
+
+static int rtusb_probe (struct usb_interface *intf,
+						const struct usb_device_id *id);
+static void rtusb_disconnect(struct usb_interface *intf);
+
+static BOOLEAN USBDevConfigInit(
+	IN struct usb_device	*dev,
+	IN struct usb_interface *intf,
+	IN RTMP_ADAPTER		*pAd)
+{
+	struct usb_host_interface *iface_desc;
+	ULONG BulkOutIdx;
+	UINT32 i;
+
+
+	/* get the active interface descriptor */
+	iface_desc = intf->cur_altsetting;
+
+	/* get # of enpoints  */
+	pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
+	DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
+
+	/* Configure Pipes */
+	BulkOutIdx = 0;
+
+	for(i=0; i<pAd->NumberOfPipes; i++)
+	{
+		if ((iface_desc->endpoint[i].desc.bmAttributes ==
+				USB_ENDPOINT_XFER_BULK) &&
+			((iface_desc->endpoint[i].desc.bEndpointAddress &
+				USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
+		{
+			pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
+			pAd->BulkInMaxPacketSize = le2cpu16(iface_desc->endpoint[i].desc.wMaxPacketSize);
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK IN MaxPacketSize = %d\n", pAd->BulkInMaxPacketSize));
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
+		}
+		else if ((iface_desc->endpoint[i].desc.bmAttributes ==
+					USB_ENDPOINT_XFER_BULK) &&
+				((iface_desc->endpoint[i].desc.bEndpointAddress &
+					USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
+		{
+			// there are 6 bulk out EP. EP6 highest priority.
+			// EP1-4 is EDCA.  EP5 is HCCA.
+			pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
+			pAd->BulkOutMaxPacketSize = le2cpu16(iface_desc->endpoint[i].desc.wMaxPacketSize);
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK OUT MaxPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x  \n", iface_desc->endpoint[i].desc.bEndpointAddress));
+		}
+	}
+
+	if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
+	{
+		printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__);
+		return FALSE;
+	}
+
+	pAd->config = &dev->config->desc;
+	usb_set_intfdata(intf, pAd);
+
+	return TRUE;
+
+}
+
+
+
+static int rtusb_probe (struct usb_interface *intf,
+						const struct usb_device_id *id)
+{
+	RTMP_ADAPTER *pAd;
+	struct usb_device *dev;
+	int rv;
+
+	dev = interface_to_usbdev(intf);
+	dev = usb_get_dev(dev);
+
+	rv = rt2870_probe(intf, dev, id, &pAd);
+	if (rv != 0)
+		usb_put_dev(dev);
+
+	return rv;
+}
+
+
+static void rtusb_disconnect(struct usb_interface *intf)
+{
+	struct usb_device   *dev = interface_to_usbdev(intf);
+	PRTMP_ADAPTER       pAd;
+
+
+	pAd = usb_get_intfdata(intf);
+	usb_set_intfdata(intf, NULL);
+
+	rt2870_disconnect(dev, pAd);
+}
+
+
+struct usb_driver rtusb_driver = {
+	.name="rt2870",
+	.probe=rtusb_probe,
+	.disconnect=rtusb_disconnect,
+	.id_table=rtusb_usb_id,
+
+#ifdef CONFIG_PM
+	suspend:	rt2870_suspend,
+	resume:		rt2870_resume,
+#endif
+	};
+
+#ifdef CONFIG_PM
+
+VOID RT2870RejectPendingPackets(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	// clear PS packets
+	// clear TxSw packets
+}
+
+static int rt2870_suspend(
+	struct usb_interface *intf,
+	pm_message_t state)
+{
+	struct net_device *net_dev;
+	PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
+	net_dev = pAd->net_dev;
+	netif_device_detach(net_dev);
+
+	pAd->PM_FlgSuspend = 1;
+	if (netif_running(net_dev)) {
+		RTUSBCancelPendingBulkInIRP(pAd);
+		RTUSBCancelPendingBulkOutIRP(pAd);
+	}
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
+	return 0;
+}
+
+static int rt2870_resume(
+	struct usb_interface *intf)
+{
+	struct net_device *net_dev;
+	PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
+
+	pAd->PM_FlgSuspend = 0;
+	net_dev = pAd->net_dev;
+	netif_device_attach(net_dev);
+	netif_start_queue(net_dev);
+	netif_carrier_on(net_dev);
+	netif_wake_queue(net_dev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
+	return 0;
+}
+#endif // CONFIG_PM //
+
+// Init driver module
+INT __init rtusb_init(void)
+{
+	printk("rtusb init --->\n");
+	return usb_register(&rtusb_driver);
+}
+
+// Deinit driver module
+VOID __exit rtusb_exit(void)
+{
+	usb_deregister(&rtusb_driver);
+	printk("<--- rtusb exit\n");
+}
+
+module_init(rtusb_init);
+module_exit(rtusb_exit);
+
+
+
+
+/*---------------------------------------------------------------------	*/
+/* function declarations												*/
+/*---------------------------------------------------------------------	*/
+
+/*
+========================================================================
+Routine Description:
+    MLME kernel thread.
+
+Arguments:
+	*Context			the pAd, driver control block pointer
+
+Return Value:
+    0					close the thread
+
+Note:
+========================================================================
+*/
+INT MlmeThread(
+	IN void *Context)
+{
+	RTMP_ADAPTER *pAd;
+	RTMP_OS_TASK *pTask;
+	int status;
+	status = 0;
+
+	pTask = (RTMP_OS_TASK *)Context;
+	pAd = (PRTMP_ADAPTER)pTask->priv;
+
+	RtmpOSTaskCustomize(pTask);
+
+	while(!pTask->task_killed)
+	{
+#ifdef KTHREAD_SUPPORT
+		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
+#else
+		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
+
+		/* unlock the device pointers */
+		if (status != 0)
+		{
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+#endif
+
+		/* lock the device pointers , need to check if required*/
+		//down(&(pAd->usbdev_semaphore));
+
+		if (!pAd->PM_FlgSuspend)
+			MlmeHandler(pAd);
+	}
+
+	/* notify the exit routine that we're actually exiting now
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
+#ifndef KTHREAD_SUPPORT
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+	complete_and_exit (&pTask->taskComplete, 0);
+#endif
+	return 0;
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+    USB command kernel thread.
+
+Arguments:
+	*Context			the pAd, driver control block pointer
+
+Return Value:
+    0					close the thread
+
+Note:
+========================================================================
+*/
+INT RTUSBCmdThread(
+	IN void * Context)
+{
+	RTMP_ADAPTER *pAd;
+	RTMP_OS_TASK *pTask;
+	int status;
+	status = 0;
+
+	pTask = (RTMP_OS_TASK *)Context;
+	pAd = (PRTMP_ADAPTER)pTask->priv;
+
+	RtmpOSTaskCustomize(pTask);
+
+	NdisAcquireSpinLock(&pAd->CmdQLock);
+	pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
+	NdisReleaseSpinLock(&pAd->CmdQLock);
+
+	while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING)
+	{
+#ifdef KTHREAD_SUPPORT
+		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
+#else
+		/* lock the device pointers */
+		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
+
+		if (status != 0)
+		{
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+#endif
+
+		if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
+			break;
+
+		if (!pAd->PM_FlgSuspend)
+			CMDHandler(pAd);
+	}
+
+	if (pAd && !pAd->PM_FlgSuspend)
+	{	// Clear the CmdQElements.
+		CmdQElmt	*pCmdQElmt = NULL;
+
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
+		while(pAd->CmdQ.size)
+		{
+			RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
+			if (pCmdQElmt)
+			{
+				if (pCmdQElmt->CmdFromNdis == TRUE)
+				{
+					if (pCmdQElmt->buffer != NULL)
+						os_free_mem(pAd, pCmdQElmt->buffer);
+					os_free_mem(pAd, (PUCHAR)pCmdQElmt);
+				}
+				else
+				{
+					if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
+						os_free_mem(pAd, pCmdQElmt->buffer);
+					os_free_mem(pAd, (PUCHAR)pCmdQElmt);
+				}
+			}
+		}
+
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+	}
+	/* notify the exit routine that we're actually exiting now
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
+
+#ifndef KTHREAD_SUPPORT
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+	complete_and_exit (&pTask->taskComplete, 0);
+#endif
+	return 0;
+
+}
+
+
+VOID RTUSBWatchDog(IN RTMP_ADAPTER *pAd)
+{
+	PHT_TX_CONTEXT		pHTTXContext;
+	int					idx;
+	ULONG				irqFlags;
+	PURB				pUrb;
+	BOOLEAN				needDumpSeq = FALSE;
+	UINT32			MACValue;
+	UINT32		TxRxQ_Pcnt;
+
+	idx = 0;
+	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+	if ((MACValue & 0xff) !=0 )
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
+		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
+		while((MACValue &0xff) != 0 && (idx++ < 10))
+		{
+		        RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+		        RTMPusecDelay(1);
+		}
+		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
+	}
+
+	if (pAd->watchDogRxOverFlowCnt >= 2)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
+		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+									fRTMP_ADAPTER_BULKIN_RESET |
+									fRTMP_ADAPTER_HALT_IN_PROGRESS |
+									fRTMP_ADAPTER_NIC_NOT_EXIST))))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
+			needDumpSeq = TRUE;
+		}
+		pAd->watchDogRxOverFlowCnt = 0;
+	}
+
+	RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt);
+
+	for (idx = 0; idx < NUM_OF_TX_RING; idx++)
+	{
+		pUrb = NULL;
+
+		RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
+		if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
+		{
+			INT actual_length=0,transfer_buffer_length=0;
+			BOOLEAN isDataPacket=FALSE;
+			pAd->watchDogTxPendingCnt[idx]++;
+
+			if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
+				 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
+				)
+			{
+				// FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
+				pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
+				if (pHTTXContext->IRPPending)
+				{	// Check TxContext.
+					pUrb = pHTTXContext->pUrb;
+
+					actual_length=pUrb->actual_length;
+					transfer_buffer_length=pUrb->transfer_buffer_length;
+					isDataPacket=TRUE;
+				}
+				else if (idx == MGMTPIPEIDX)
+				{
+					PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
+
+					//Check MgmtContext.
+					pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
+					pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
+					pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
+
+					if (pMLMEContext->IRPPending)
+					{
+						ASSERT(pMLMEContext->IRPPending);
+						pUrb = pMLMEContext->pUrb;
+					}
+					else if (pNULLContext->IRPPending)
+					{
+						ASSERT(pNULLContext->IRPPending);
+						pUrb = pNULLContext->pUrb;
+					}
+					else if (pPsPollContext->IRPPending)
+					{
+						ASSERT(pPsPollContext->IRPPending);
+						pUrb = pPsPollContext->pUrb;
+					}
+				}
+
+				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+
+
+				printk("%d:%d LTL=%d , TL=%d L:%d\n",idx,pAd->watchDogTxPendingCnt[idx],pAd->TransferedLength[idx]
+					,actual_length,transfer_buffer_length);
+
+				if (pUrb)
+				{
+					if ((isDataPacket
+					&& pAd->TransferedLength[idx]==actual_length
+					&& pAd->TransferedLength[idx]<transfer_buffer_length
+					&& actual_length!=0
+//					&& TxRxQ_Pcnt==0
+					&& pAd->watchDogTxPendingCnt[idx]>3)
+					|| isDataPacket==FALSE || pAd->watchDogTxPendingCnt[idx]>6)
+					{
+						DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
+					DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
+					// unlink it now
+					RTUSB_UNLINK_URB(pUrb);
+					// Sleep 200 microseconds to give cancellation time to work
+						//RTMPusecDelay(200);
+					needDumpSeq = TRUE;
+					}
+				}
+				else
+				{
+					DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
+				}
+			}
+			else
+			{
+				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+			}
+
+			if (isDataPacket==TRUE)
+				pAd->TransferedLength[idx]=actual_length;
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+		}
+	}
+
+	// For Sigma debug, dump the ba_reordering sequence.
+	if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
+	{
+		USHORT				Idx;
+		PBA_REC_ENTRY		pBAEntry = NULL;
+		UCHAR				count = 0;
+		struct reordering_mpdu *mpdu_blk;
+
+		Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
+
+		pBAEntry = &pAd->BATable.BARecEntry[Idx];
+		if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
+			NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+			mpdu_blk = pBAEntry->list.next;
+			while (mpdu_blk)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
+				mpdu_blk = mpdu_blk->next;
+				count++;
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
+			NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+		}
+	}
+}
+
+/*
+========================================================================
+Routine Description:
+    Release allocated resources.
+
+Arguments:
+    *dev				Point to the PCI or USB device
+	pAd					driver control block pointer
+
+Return Value:
+    None
+
+Note:
+========================================================================
+*/
+static void rt2870_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
+{
+	DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
+				dev->bus->bus_name, dev->devpath));
+	if (!pAd)
+	{
+		usb_put_dev(dev);
+		printk("rtusb_disconnect: pAd == NULL!\n");
+		return;
+	}
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+
+	// for debug, wait to show some messages to /proc system
+	udelay(1);
+
+
+	RtmpPhyNetDevExit(pAd, pAd->net_dev);
+
+	// FIXME: Shall we need following delay and flush the schedule??
+	udelay(1);
+	flush_scheduled_work();
+	udelay(1);
+
+	// free the root net_device
+	RtmpOSNetDevFree(pAd->net_dev);
+
+	RtmpRaDevCtrlExit(pAd);
+
+	// release a use of the usb device structure
+	usb_put_dev(dev);
+	udelay(1);
+
+	DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
+}
+
+
+static int __devinit rt2870_probe(
+	IN struct usb_interface *intf,
+	IN struct usb_device *usb_dev,
+	IN const struct usb_device_id *dev_id,
+	IN RTMP_ADAPTER **ppAd)
+{
+	struct  net_device		*net_dev = NULL;
+	RTMP_ADAPTER		*pAd = (RTMP_ADAPTER *) NULL;
+	INT				status, rv;
+	PVOID				handle;
+	RTMP_OS_NETDEV_OP_HOOK	netDevHook;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n"));
+
+	// Check chipset vendor/product ID
+	//if (RT28XXChipsetCheck(_dev_p) == FALSE)
+	//	goto err_out;
+
+//RtmpDevInit=============================================
+	// Allocate RTMP_ADAPTER adapter structure
+	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
+	if (handle == NULL)
+	{
+		printk("rt2870_probe(): Allocate memory for os handle failed!\n");
+		return -ENOMEM;
+	}
+	((POS_COOKIE)handle)->pUsb_Dev = usb_dev;
+
+	rv = RTMPAllocAdapterBlock(handle, &pAd);
+	if (rv != NDIS_STATUS_SUCCESS)
+	{
+		kfree(handle);
+		goto err_out;
+	}
+
+//USBDevInit==============================================
+	if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE)
+		goto err_out_free_radev;
+
+	RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB);
+
+//NetDevInit==============================================
+	net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
+	if (net_dev == NULL)
+		goto err_out_free_radev;
+
+	// Here are the net_device structure with usb specific parameters.
+	/* for supporting Network Manager.
+	  * Set the sysfs physical device reference for the network logical device if set prior to registration will
+	  * cause a symlink during initialization.
+	 */
+	SET_NETDEV_DEV(net_dev, &(usb_dev->dev));
+
+    pAd->StaCfg.OriDevType = net_dev->type;
+
+//All done, it's time to register the net device to linux kernel.
+	// Register this device
+	status = RtmpOSNetDevAttach(net_dev, &netDevHook);
+	if (status != 0)
+		goto err_out_free_netdev;
+
+#ifdef KTHREAD_SUPPORT
+	init_waitqueue_head(&pAd->mlmeTask.kthread_q);
+	init_waitqueue_head(&pAd->timerTask.kthread_q);
+	init_waitqueue_head(&pAd->cmdQTask.kthread_q);
+#endif
+
+	*ppAd = pAd;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n"));
+
+	return 0;
+
+	/* --------------------------- ERROR HANDLE --------------------------- */
+err_out_free_netdev:
+	RtmpOSNetDevFree(net_dev);
+
+err_out_free_radev:
+	RTMPFreeAdapter(pAd);
+
+err_out:
+	*ppAd = NULL;
+
+	return -1;
+
+}

+ 102 - 2
drivers/staging/rt2860/wpa.h

@@ -67,7 +67,6 @@
 // Key Descriptor Version of Key Information
 #define	DESC_TYPE_TKIP				1
 #define	DESC_TYPE_AES				2
-#define DESC_TYPE_MESH				3
 
 #define LEN_MSG1_2WAY               0x7f
 #define MAX_LEN_OF_EAP_HS           256
@@ -90,11 +89,17 @@
 #define TKIP_AP_RXMICK_OFFSET		(TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
 #define TKIP_GTK_LENGTH				((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
 #define LEN_PTK						((LEN_EAP_KEY)+(LEN_TKIP_KEY))
+#define MIN_LEN_OF_GTK				5
+#define LEN_PMK						32
+#define LEN_PMK_NAME				16
+#define LEN_NONCE					32
 
 // RSN IE Length definition
-#define MAX_LEN_OF_RSNIE         	90
+#define MAX_LEN_OF_RSNIE		255
 #define MIN_LEN_OF_RSNIE         	8
 
+#define KEY_LIFETIME				3600
+
 //EAP Packet Type
 #define	EAPPacket		0
 #define	EAPOLStart		1
@@ -119,6 +124,29 @@
 #define PEER_MSG3_RETRY_TIMER_CTR           10
 #define GROUP_MSG1_RETRY_TIMER_CTR          20
 
+//#ifdef CONFIG_AP_SUPPORT
+// WPA mechanism retry timer interval
+#define PEER_MSG1_RETRY_EXEC_INTV           1000			// 1 sec
+#define PEER_MSG3_RETRY_EXEC_INTV           3000			// 3 sec
+#define GROUP_KEY_UPDATE_EXEC_INTV          1000				// 1 sec
+#define PEER_GROUP_KEY_UPDATE_INIV			2000				// 2 sec
+
+#define ENQUEUE_EAPOL_START_TIMER			200					// 200 ms
+
+// group rekey interval
+#define TIME_REKEY                          0
+#define PKT_REKEY                           1
+#define DISABLE_REKEY                       2
+#define MAX_REKEY                           2
+
+#define MAX_REKEY_INTER                     0x3ffffff
+//#endif // CONFIG_AP_SUPPORT //
+
+#define GROUP_SUITE					0
+#define PAIRWISE_SUITE				1
+#define AKM_SUITE					2
+#define PMKID_LIST					3
+
 
 #define EAPOL_START_DISABLE					0
 #define EAPOL_START_PSK						1
@@ -129,8 +157,30 @@
 #define MIX_CIPHER_WPA2_TKIP_ON(x)      (((x) & 0x02) != 0)
 #define MIX_CIPHER_WPA2_AES_ON(x)       (((x) & 0x01) != 0)
 
+#ifndef ROUND_UP
 #define ROUND_UP(__x, __y) \
 	(((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
+#endif
+
+#define	SET_UINT16_TO_ARRARY(_V, _LEN)		\
+{											\
+	_V[0] = (_LEN & 0xFF00) >> 8;			\
+	_V[1] = (_LEN & 0xFF);					\
+}
+
+#define	INC_UINT16_TO_ARRARY(_V, _LEN)			\
+{												\
+	UINT16	var_len;							\
+												\
+	var_len = (_V[0]<<8) | (_V[1]);				\
+	var_len += _LEN;							\
+												\
+	_V[0] = (var_len & 0xFF00) >> 8;			\
+	_V[1] = (var_len & 0xFF);					\
+}
+
+#define	CONV_ARRARY_TO_UINT16(_V)	((_V[0]<<8) | (_V[1]))
+
 
 #define	ADD_ONE_To_64BIT_VAR(_V)		\
 {										\
@@ -297,6 +347,13 @@ typedef	enum	_WpaMixPairCipher
 	WPA_TKIPAES_WPA2_TKIPAES	= 0x0F,
 }	WPA_MIX_PAIR_CIPHER;
 
+// 802.1x authentication format
+typedef	struct	_IEEE8021X_FRAME	{
+	UCHAR	Version;					// 1.0
+	UCHAR	Type;						// 0 = EAP Packet
+	USHORT	Length;
+}	IEEE8021X_FRAME, *PIEEE8021X_FRAME;
+
 typedef struct PACKED _RSN_IE_HEADER_STRUCT	{
 	UCHAR		Eid;
 	UCHAR		Length;
@@ -324,4 +381,47 @@ typedef struct	PACKED _RSN_CAPABILITY	{
 	USHORT		PreAuth:1;
 }	RSN_CAPABILITY, *PRSN_CAPABILITY;
 
+
+/*========================================
+	The prototype is defined in cmm_wpa.c
+  ========================================*/
+BOOLEAN WpaMsgTypeSubst(
+	IN  UCHAR   EAPType,
+	OUT INT		*MsgType);
+
+VOID    PRF(
+	IN  UCHAR   *key,
+	IN  INT     key_len,
+	IN  UCHAR   *prefix,
+	IN  INT     prefix_len,
+	IN  UCHAR   *data,
+	IN  INT     data_len,
+	OUT UCHAR   *output,
+	IN  INT     len);
+
+int PasswordHash(
+	char *password,
+	unsigned char *ssid,
+	int ssidlength,
+	unsigned char *output);
+
+PUINT8	GetSuiteFromRSNIE(
+		IN	PUINT8	rsnie,
+		IN	UINT	rsnie_len,
+		IN	UINT8	type,
+		OUT	UINT8	*count);
+
+VOID WpaShowAllsuite(
+	IN	PUINT8	rsnie,
+	IN	UINT	rsnie_len);
+
+VOID RTMPInsertRSNIE(
+	IN PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN PUINT8 rsnie_ptr,
+	IN UINT8  rsnie_len,
+	IN PUINT8 pmkid_ptr,
+	IN UINT8  pmkid_len);
+
+
 #endif

+ 0 - 1530
drivers/staging/rt2870/2870_main_dev.c

@@ -1,1530 +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:
-    rtmp_main.c
-
-    Abstract:
-    main initialization routines
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-    Name        Date            Modification logs
-    Jan Lee		01-10-2005	    modified
-	Sample		Jun/01/07		Merge RT2870 and RT2860 drivers.
-*/
-
-#include "rt_config.h"
-
-
-// Following information will be show when you run 'modinfo'
-// *** If you have a solution for the bug in current version of driver, please mail to me.
-// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
-MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
-MODULE_DESCRIPTION(RT28xx_CHIP_NAME " Wireless LAN Linux Driver");
-MODULE_LICENSE("GPL");
-#ifdef MODULE_VERSION
-MODULE_VERSION(STA_DRIVER_VERSION);
-#endif
-MODULE_ALIAS("rt3070sta");
-
-/* Kernel thread and vars, which handles packets that are completed. Only
- * packets that have a "complete" function are sent here. This way, the
- * completion is run out of kernel context, and doesn't block the rest of
- * the stack. */
-
-extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
-									IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
-
-struct usb_device_id rtusb_usb_id[] = {
-	{ USB_DEVICE(0x148F, 0x2770) }, /* Ralink */
-	{ USB_DEVICE(0x1737, 0x0071) }, /* Linksys WUSB600N */
-	{ USB_DEVICE(0x1737, 0x0070) }, /* Linksys */
-	{ USB_DEVICE(0x148F, 0x2870) }, /* Ralink */
-	{ USB_DEVICE(0x148F, 0x3070) }, /* Ralink 3070 */
-	{ USB_DEVICE(0x148F, 0x3071) }, /* Ralink 3071 */
-	{ USB_DEVICE(0x148F, 0x3072) }, /* Ralink 3072 */
-	{ USB_DEVICE(0x0B05, 0x1731) }, /* Asus */
-	{ USB_DEVICE(0x0B05, 0x1732) }, /* Asus */
-	{ USB_DEVICE(0x0B05, 0x1742) }, /* Asus */
-	{ USB_DEVICE(0x0DF6, 0x0017) }, /* Sitecom */
-	{ USB_DEVICE(0x0DF6, 0x002B) }, /* Sitecom */
-	{ USB_DEVICE(0x0DF6, 0x002C) }, /* Sitecom */
-	{ USB_DEVICE(0x0DF6, 0x003E) }, /* Sitecom 3070 */
-	{ USB_DEVICE(0x0DF6, 0x002D) }, /* Sitecom */
-	{ USB_DEVICE(0x0DF6, 0x0039) }, /* Sitecom 2770 */
-	{ USB_DEVICE(0x0DF6, 0x003F) }, /* Sitecom WL-608 */
-	{ USB_DEVICE(0x14B2, 0x3C06) }, /* Conceptronic */
-	{ USB_DEVICE(0x14B2, 0x3C28) }, /* Conceptronic */
-	{ USB_DEVICE(0x2019, 0xED06) }, /* Planex Communications, Inc. */
-	{ USB_DEVICE(0x2019, 0xED14) }, /* Planex Communications, Inc. */
-	{ USB_DEVICE(0x2019, 0xAB25) }, /* Planex Communications, Inc. RT3070 */
-	{ USB_DEVICE(0x07D1, 0x3C09) }, /* D-Link */
-	{ USB_DEVICE(0x07D1, 0x3C11) }, /* D-Link */
-	{ USB_DEVICE(0x2001, 0x3C09) }, /* D-Link */
-	{ USB_DEVICE(0x2001, 0x3C0A) }, /* D-Link 3072*/
-	{ USB_DEVICE(0x14B2, 0x3C07) }, /* AL */
-	{ USB_DEVICE(0x14B2, 0x3C12) }, /* AL 3070 */
-	{ USB_DEVICE(0x050D, 0x8053) }, /* Belkin */
-	{ USB_DEVICE(0x050D, 0x815C) }, /* Belkin */
-	{ USB_DEVICE(0x050D, 0x825a) }, /* Belkin */
-	{ USB_DEVICE(0x14B2, 0x3C23) }, /* Airlink */
-	{ USB_DEVICE(0x14B2, 0x3C27) }, /* Airlink */
-	{ USB_DEVICE(0x07AA, 0x002F) }, /* Corega */
-	{ USB_DEVICE(0x07AA, 0x003C) }, /* Corega */
-	{ USB_DEVICE(0x07AA, 0x003F) }, /* Corega */
-	{ USB_DEVICE(0x18C5, 0x0012) }, /* Corega 3070 */
-	{ USB_DEVICE(0x1044, 0x800B) }, /* Gigabyte */
-	{ USB_DEVICE(0x1044, 0x800D) }, /* Gigabyte GN-WB32L 3070 */
-	{ USB_DEVICE(0x15A9, 0x0006) }, /* Sparklan */
-	{ USB_DEVICE(0x083A, 0xB522) }, /* SMC */
-	{ USB_DEVICE(0x083A, 0xA618) }, /* SMC */
-	{ USB_DEVICE(0x083A, 0x8522) }, /* Arcadyan */
-	{ USB_DEVICE(0x083A, 0x7512) }, /* Arcadyan 2770 */
-	{ USB_DEVICE(0x083A, 0x7522) }, /* Arcadyan */
-	{ USB_DEVICE(0x083A, 0x7511) }, /* Arcadyan 3070 */
-	{ USB_DEVICE(0x0CDE, 0x0022) }, /* ZCOM */
-	{ USB_DEVICE(0x0586, 0x3416) }, /* Zyxel */
-	{ USB_DEVICE(0x0CDE, 0x0025) }, /* Zyxel */
-	{ USB_DEVICE(0x1740, 0x9701) }, /* EnGenius */
-	{ USB_DEVICE(0x1740, 0x9702) }, /* EnGenius */
-	{ USB_DEVICE(0x1740, 0x9703) }, /* EnGenius 3070 */
-	{ USB_DEVICE(0x0471, 0x200f) }, /* Philips */
-	{ USB_DEVICE(0x14B2, 0x3C25) }, /* Draytek */
-	{ USB_DEVICE(0x13D3, 0x3247) }, /* AzureWave */
-	{ USB_DEVICE(0x13D3, 0x3273) }, /* AzureWave 3070*/
-	{ USB_DEVICE(0x083A, 0x6618) }, /* Accton */
-	{ USB_DEVICE(0x15c5, 0x0008) }, /* Amit */
-	{ USB_DEVICE(0x0E66, 0x0001) }, /* Hawking */
-	{ USB_DEVICE(0x0E66, 0x0003) }, /* Hawking */
-	{ USB_DEVICE(0x129B, 0x1828) }, /* Siemens */
-	{ USB_DEVICE(0x157E, 0x300E) }, /* U-Media */
-	{ USB_DEVICE(0x050d, 0x805c) },
-	{ USB_DEVICE(0x1482, 0x3C09) }, /* Abocom*/
-	{ USB_DEVICE(0x14B2, 0x3C09) }, /* Alpha */
-	{ USB_DEVICE(0x04E8, 0x2018) }, /* samsung */
-	{ USB_DEVICE(0x07B8, 0x3070) }, /* AboCom 3070 */
-	{ USB_DEVICE(0x07B8, 0x3071) }, /* AboCom 3071 */
-	{ USB_DEVICE(0x07B8, 0x2870) }, /* AboCom */
-	{ USB_DEVICE(0x07B8, 0x2770) }, /* AboCom */
-	{ USB_DEVICE(0x07B8, 0x3072) }, /* Abocom 3072 */
-	{ USB_DEVICE(0x7392, 0x7711) }, /* Edimax 3070 */
-	{ USB_DEVICE(0x5A57, 0x0280) }, /* Zinwell */
-	{ USB_DEVICE(0x5A57, 0x0282) }, /* Zinwell */
-	{ USB_DEVICE(0x1A32, 0x0304) }, /* Quanta 3070 */
-	{ USB_DEVICE(0x0789, 0x0162) }, /* Logitec 2870 */
-	{ USB_DEVICE(0x0789, 0x0163) }, /* Logitec 2870 */
-	{ USB_DEVICE(0x0789, 0x0164) }, /* Logitec 2870 */
-	{ USB_DEVICE(0x7392, 0x7717) }, /* Edimax */
-	{ USB_DEVICE(0x1EDA, 0x2310) }, /* AirTies 3070 */
-	{ USB_DEVICE(0x1737, 0x0077) }, /* Linksys WUSB54GC-EU v3 */
-	{ } /* Terminating entry */
-};
-
-INT const               rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
-MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
-
-#ifndef PF_NOFREEZE
-#define PF_NOFREEZE  0
-#endif
-
-
-#ifdef CONFIG_PM
-static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
-static int rt2870_resume(struct usb_interface *intf);
-#endif // CONFIG_PM //
-
-/**************************************************************************/
-/**************************************************************************/
-//tested for kernel 2.6series
-/**************************************************************************/
-/**************************************************************************/
-static int rtusb_probe (struct usb_interface *intf,
-						const struct usb_device_id *id);
-static void rtusb_disconnect(struct usb_interface *intf);
-
-struct usb_driver rtusb_driver = {
-	.name="rt2870",
-	.probe=rtusb_probe,
-	.disconnect=rtusb_disconnect,
-	.id_table=rtusb_usb_id,
-
-#ifdef CONFIG_PM
-	suspend:	rt2870_suspend,
-	resume:		rt2870_resume,
-#endif
-	};
-
-#ifdef CONFIG_PM
-
-VOID RT2860RejectPendingPackets(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	// clear PS packets
-	// clear TxSw packets
-}
-
-static int rt2870_suspend(
-	struct usb_interface *intf,
-	pm_message_t state)
-{
-	struct net_device *net_dev;
-	PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
-	net_dev = pAd->net_dev;
-	netif_device_detach (net_dev);
-
-	pAd->PM_FlgSuspend = 1;
-	if (netif_running(net_dev)) {
-		RTUSBCancelPendingBulkInIRP(pAd);
-		RTUSBCancelPendingBulkOutIRP(pAd);
-	}
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
-	return 0;
-}
-
-static int rt2870_resume(
-	struct usb_interface *intf)
-{
-	struct net_device *net_dev;
-	PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
-
-	pAd->PM_FlgSuspend = 0;
-	net_dev = pAd->net_dev;
-	netif_device_attach (net_dev);
-	netif_start_queue(net_dev);
-	netif_carrier_on(net_dev);
-	netif_wake_queue(net_dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
-	return 0;
-}
-#endif // CONFIG_PM //
-
-
-// Init driver module
-INT __init rtusb_init(void)
-{
-	printk("rtusb init --->\n");
-	return usb_register(&rtusb_driver);
-}
-
-// Deinit driver module
-VOID __exit rtusb_exit(void)
-{
-	usb_deregister(&rtusb_driver);
-	printk("<--- rtusb exit\n");
-}
-
-module_init(rtusb_init);
-module_exit(rtusb_exit);
-
-
-
-
-/*---------------------------------------------------------------------	*/
-/* function declarations												*/
-/*---------------------------------------------------------------------	*/
-
-/*
-========================================================================
-Routine Description:
-    MLME kernel thread.
-
-Arguments:
-	*Context			the pAd, driver control block pointer
-
-Return Value:
-    0					close the thread
-
-Note:
-========================================================================
-*/
-INT MlmeThread(
-	IN void *Context)
-{
-	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;
-	POS_COOKIE	pObj;
-	int status;
-
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
-
-	while (pAd->mlme_kill == 0)
-	{
-		/* lock the device pointers */
-		//down(&(pAd->mlme_semaphore));
-		status = down_interruptible(&(pAd->mlme_semaphore));
-
-		/* lock the device pointers , need to check if required*/
-		//down(&(pAd->usbdev_semaphore));
-
-		if (!pAd->PM_FlgSuspend)
-		MlmeHandler(pAd);
-
-		/* unlock the device pointers */
-		//up(&(pAd->usbdev_semaphore));
-		if (status != 0)
-		{
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-	}
-
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
-
-	pObj->MLMEThr_pid = NULL;
-
-	complete_and_exit (&pAd->mlmeComplete, 0);
-	return 0;
-
-}
-
-
-/*
-========================================================================
-Routine Description:
-    USB command kernel thread.
-
-Arguments:
-	*Context			the pAd, driver control block pointer
-
-Return Value:
-    0					close the thread
-
-Note:
-========================================================================
-*/
-INT RTUSBCmdThread(
-	IN void * Context)
-{
-	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;
-	POS_COOKIE		pObj;
-	int status;
-
-	pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-	rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
-
-	NdisAcquireSpinLock(&pAd->CmdQLock);
-	pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
-	NdisReleaseSpinLock(&pAd->CmdQLock);
-
-	while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
-	{
-		/* lock the device pointers */
-		//down(&(pAd->RTUSBCmd_semaphore));
-		status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
-
-		if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
-			break;
-
-		if (status != 0)
-		{
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-		/* lock the device pointers , need to check if required*/
-		//down(&(pAd->usbdev_semaphore));
-
-		if (!pAd->PM_FlgSuspend)
-		CMDHandler(pAd);
-
-		/* unlock the device pointers */
-		//up(&(pAd->usbdev_semaphore));
-	}
-
-	if (!pAd->PM_FlgSuspend)
-	{	// Clear the CmdQElements.
-		CmdQElmt	*pCmdQElmt = NULL;
-
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
-		while(pAd->CmdQ.size)
-		{
-			RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
-			if (pCmdQElmt)
-			{
-				if (pCmdQElmt->CmdFromNdis == TRUE)
-				{
-					if (pCmdQElmt->buffer != NULL)
-						NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
-
-					NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
-				}
-				else
-				{
-					if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
-						NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
-		            {
-						NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
-					}
-				}
-			}
-		}
-
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-	}
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
-
-	pObj->RTUSBCmdThr_pid = NULL;
-
-	complete_and_exit (&pAd->CmdQComplete, 0);
-	return 0;
-
-}
-
-
-static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
-{
-	int status;
-	RALINK_TIMER_STRUCT	*pTimer;
-	RT2870_TIMER_ENTRY	*pEntry;
-	unsigned long	irqFlag;
-
-	while(!pAd->TimerFunc_kill)
-	{
-//		printk("waiting for event!\n");
-		pTimer = NULL;
-
-		status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
-
-		if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
-			break;
-
-		// event happened.
-		while(pAd->TimerQ.pQHead)
-		{
-			RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
-			pEntry = pAd->TimerQ.pQHead;
-			if (pEntry)
-			{
-				pTimer = pEntry->pRaTimer;
-
-				// update pQHead
-				pAd->TimerQ.pQHead = pEntry->pNext;
-				if (pEntry == pAd->TimerQ.pQTail)
-					pAd->TimerQ.pQTail = NULL;
-
-				// return this queue entry to timerQFreeList.
-				pEntry->pNext = pAd->TimerQ.pQPollFreeList;
-				pAd->TimerQ.pQPollFreeList = pEntry;
-			}
-			RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
-
-			if (pTimer)
-			{
-				if (pTimer->handle != NULL)
-				if (!pAd->PM_FlgSuspend)
-					pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
-				if ((pTimer->Repeat) && (pTimer->State == FALSE))
-					RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
-			}
-		}
-
-		if (status != 0)
-		{
-			pAd->TimerQ.status = RT2870_THREAD_STOPED;
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-	}
-}
-
-
-INT TimerQThread(
-	IN OUT PVOID Context)
-{
-	PRTMP_ADAPTER	pAd;
-	POS_COOKIE	pObj;
-
-	pAd = (PRTMP_ADAPTER)Context;
-	pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-	rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
-
-	RT2870_TimerQ_Handle(pAd);
-
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
-
-	pObj->TimerQThr_pid = NULL;
-
-	complete_and_exit(&pAd->TimerQComplete, 0);
-	return 0;
-
-}
-
-
-RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer)
-{
-	RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
-	unsigned long irqFlags;
-
-
-	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
-	if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
-	{
-		if(pAd->TimerQ.pQPollFreeList)
-		{
-			pQNode = pAd->TimerQ.pQPollFreeList;
-			pAd->TimerQ.pQPollFreeList = pQNode->pNext;
-
-			pQNode->pRaTimer = pTimer;
-			pQNode->pNext = NULL;
-
-			pQTail = pAd->TimerQ.pQTail;
-			if (pAd->TimerQ.pQTail != NULL)
-				pQTail->pNext = pQNode;
-			pAd->TimerQ.pQTail = pQNode;
-			if (pAd->TimerQ.pQHead == NULL)
-				pAd->TimerQ.pQHead = pQNode;
-		}
-		RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-		if (pQNode)
-			up(&pAd->RTUSBTimer_semaphore);
-			//wake_up(&timerWaitQ);
-	}
-	else
-	{
-		RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-	}
-	return pQNode;
-}
-
-
-BOOLEAN RT2870_TimerQ_Remove(
-	IN RTMP_ADAPTER *pAd,
-	IN RALINK_TIMER_STRUCT *pTimer)
-{
-	RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
-	unsigned long irqFlags;
-
-	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
-	if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
-	{
-		pNode = pAd->TimerQ.pQHead;
-		while (pNode)
-		{
-			if (pNode->pRaTimer == pTimer)
-				break;
-			pPrev = pNode;
-			pNode = pNode->pNext;
-		}
-
-		// Now move it to freeList queue.
-		if (pNode)
-		{
-			if (pNode == pAd->TimerQ.pQHead)
-				pAd->TimerQ.pQHead = pNode->pNext;
-			if (pNode == pAd->TimerQ.pQTail)
-				pAd->TimerQ.pQTail = pPrev;
-			if (pPrev != NULL)
-				pPrev->pNext = pNode->pNext;
-
-			// return this queue entry to timerQFreeList.
-			pNode->pNext = pAd->TimerQ.pQPollFreeList;
-			pAd->TimerQ.pQPollFreeList = pNode;
-		}
-	}
-	RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-	return TRUE;
-}
-
-
-void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
-{
-	RT2870_TIMER_ENTRY *pTimerQ;
-	unsigned long irqFlags;
-
-	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
-	while (pAd->TimerQ.pQHead)
-	{
-		pTimerQ = pAd->TimerQ.pQHead;
-		pAd->TimerQ.pQHead = pTimerQ->pNext;
-		// remove the timeQ
-	}
-	pAd->TimerQ.pQPollFreeList = NULL;
-	os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
-	pAd->TimerQ.pQTail = NULL;
-	pAd->TimerQ.pQHead = NULL;
-	pAd->TimerQ.status = RT2870_THREAD_STOPED;
-	RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-}
-
-
-void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
-{
-	int 	i;
-	RT2870_TIMER_ENTRY *pQNode, *pEntry;
-	unsigned long irqFlags;
-
-	NdisAllocateSpinLock(&pAd->TimerQLock);
-
-	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
-	NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
-	//InterlockedExchange(&pAd->TimerQ.count, 0);
-
-	/* Initialise the wait q head */
-	//init_waitqueue_head(&timerWaitQ);
-
-	os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
-	if (pAd->TimerQ.pTimerQPoll)
-	{
-		pEntry = NULL;
-		pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
-		for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
-		{
-			pQNode->pNext = pEntry;
-			pEntry = pQNode;
-			pQNode++;
-		}
-		pAd->TimerQ.pQPollFreeList = pEntry;
-		pAd->TimerQ.pQHead = NULL;
-		pAd->TimerQ.pQTail = NULL;
-		pAd->TimerQ.status = RT2870_THREAD_INITED;
-	}
-	RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
-}
-
-
-VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
-{
-	PHT_TX_CONTEXT		pHTTXContext;
-	int 					idx;
-	ULONG				irqFlags;
-	PURB		   		pUrb;
-	BOOLEAN				needDumpSeq = FALSE;
-	UINT32          	MACValue;
-
-
-	idx = 0;
-	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
-	if ((MACValue & 0xff) !=0 )
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
-		while((MACValue &0xff) != 0 && (idx++ < 10))
-		{
-		        RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
-		        NdisMSleep(1);
-		}
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
-	}
-
-//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
-	idx = 0;
-	if ((MACValue & 0xff00) !=0 )
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
-		while((MACValue &0xff00) != 0 && (idx++ < 10))
-		{
-			RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
-			NdisMSleep(1);
-		}
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
-	}
-
-	if (pAd->watchDogRxOverFlowCnt >= 2)
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
-		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-									fRTMP_ADAPTER_BULKIN_RESET |
-									fRTMP_ADAPTER_HALT_IN_PROGRESS |
-									fRTMP_ADAPTER_NIC_NOT_EXIST))))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
-			needDumpSeq = TRUE;
-		}
-		pAd->watchDogRxOverFlowCnt = 0;
-	}
-
-
-	for (idx = 0; idx < NUM_OF_TX_RING; idx++)
-	{
-		pUrb = NULL;
-
-		RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
-		if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
-		{
-			pAd->watchDogTxPendingCnt[idx]++;
-
-			if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
-				 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
-				)
-			{
-				// FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
-				pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
-				if (pHTTXContext->IRPPending)
-				{	// Check TxContext.
-					pUrb = pHTTXContext->pUrb;
-				}
-				else if (idx == MGMTPIPEIDX)
-				{
-					PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
-
-					//Check MgmtContext.
-					pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
-					pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
-					pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
-
-					if (pMLMEContext->IRPPending)
-					{
-						ASSERT(pMLMEContext->IRPPending);
-						pUrb = pMLMEContext->pUrb;
-					}
-					else if (pNULLContext->IRPPending)
-					{
-						ASSERT(pNULLContext->IRPPending);
-						pUrb = pNULLContext->pUrb;
-					}
-					else if (pPsPollContext->IRPPending)
-					{
-						ASSERT(pPsPollContext->IRPPending);
-						pUrb = pPsPollContext->pUrb;
-					}
-				}
-
-				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
-
-				DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
-				if (pUrb)
-				{
-					DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
-					// unlink it now
-					RTUSB_UNLINK_URB(pUrb);
-					// Sleep 200 microseconds to give cancellation time to work
-					RTMPusecDelay(200);
-					needDumpSeq = TRUE;
-				}
-				else
-				{
-					DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
-				}
-			}
-			else
-			{
-				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
-			}
-		}
-		else
-		{
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
-		}
-	}
-
-	// For Sigma debug, dump the ba_reordering sequence.
-	if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
-	{
-		USHORT				Idx;
-		PBA_REC_ENTRY		pBAEntry = NULL;
-		UCHAR				count = 0;
-		struct reordering_mpdu *mpdu_blk;
-
-		Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
-
-		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-		if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
-			NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-			mpdu_blk = pBAEntry->list.next;
-			while (mpdu_blk)
-			{
-				DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
-				mpdu_blk = mpdu_blk->next;
-				count++;
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
-			NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-		}
-	}
-}
-
-/*
-========================================================================
-Routine Description:
-    Release allocated resources.
-
-Arguments:
-    *dev				Point to the PCI or USB device
-	pAd					driver control block pointer
-
-Return Value:
-    None
-
-Note:
-========================================================================
-*/
-static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
-{
-	struct net_device	*net_dev = NULL;
-
-
-	DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
-				dev->bus->bus_name, dev->devpath));
-	if (!pAd)
-	{
-		usb_put_dev(dev);
-
-		printk("rtusb_disconnect: pAd == NULL!\n");
-		return;
-	}
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
-
-
-
-	// for debug, wait to show some messages to /proc system
-	udelay(1);
-
-
-
-
-	net_dev = pAd->net_dev;
-	if (pAd->net_dev != NULL)
-	{
-		printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
-		unregister_netdev (pAd->net_dev);
-	}
-	udelay(1);
-	flush_scheduled_work();
-	udelay(1);
-
-	// free net_device memory
-	free_netdev(net_dev);
-
-	// free adapter memory
-	RTMPFreeAdapter(pAd);
-
-	// release a use of the usb device structure
-	usb_put_dev(dev);
-	udelay(1);
-
-	DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Probe RT28XX chipset.
-
-Arguments:
-    *dev				Point to the PCI or USB device
-	interface
-	*id_table			Point to the PCI or USB device ID
-
-Return Value:
-    None
-
-Note:
-========================================================================
-*/
-static int rtusb_probe (struct usb_interface *intf,
-						const struct usb_device_id *id)
-{
-	PRTMP_ADAPTER pAd;
-	return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
-}
-
-
-static void rtusb_disconnect(struct usb_interface *intf)
-{
-	struct usb_device   *dev = interface_to_usbdev(intf);
-	PRTMP_ADAPTER       pAd;
-
-
-	pAd = usb_get_intfdata(intf);
-	usb_set_intfdata(intf, NULL);
-
-	_rtusb_disconnect(dev, pAd);
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Close kernel threads.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    NONE
-
-Note:
-========================================================================
-*/
-VOID RT28xxThreadTerminate(
-	IN RTMP_ADAPTER *pAd)
-{
-	POS_COOKIE	pObj = (POS_COOKIE) pAd->OS_Cookie;
-	INT			ret;
-
-
-	// Sleep 50 milliseconds so pending io might finish normally
-	RTMPusecDelay(50000);
-
-	// We want to wait until all pending receives and sends to the
-	// device object. We cancel any
-	// irps. Wait until sends and receives have stopped.
-	RTUSBCancelPendingIRPs(pAd);
-
-	// Terminate Threads
-
-	if (pid_nr(pObj->TimerQThr_pid) > 0)
-	{
-		POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
-
-		printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
-		mb();
-		pAd->TimerFunc_kill = 1;
-		mb();
-		ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
-		if (ret)
-		{
-			printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
-					pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
-		}
-		else
-		{
-			wait_for_completion(&pAd->TimerQComplete);
-			pObj->TimerQThr_pid = NULL;
-		}
-	}
-
-	if (pid_nr(pObj->MLMEThr_pid) > 0)
-	{
-		printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
-		mb();
-		pAd->mlme_kill = 1;
-		//RT28XX_MLME_HANDLER(pAd);
-		mb();
-		ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
-		if (ret)
-		{
-			printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
-					pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
-		}
-		else
-		{
-			//wait_for_completion (&pAd->notify);
-			wait_for_completion (&pAd->mlmeComplete);
-			pObj->MLMEThr_pid = NULL;
-		}
-	}
-
-	if (pid_nr(pObj->RTUSBCmdThr_pid) > 0)
-	{
-		printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
-		mb();
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-		mb();
-		//RTUSBCMDUp(pAd);
-		ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
-		if (ret)
-		{
-			printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
-					pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
-		}
-		else
-		{
-			//wait_for_completion (&pAd->notify);
-			wait_for_completion (&pAd->CmdQComplete);
-			pObj->RTUSBCmdThr_pid = NULL;
-		}
-	}
-
-	// Kill tasklets
-	pAd->mlme_kill = 0;
-	pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
-	pAd->TimerFunc_kill = 0;
-}
-
-
-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);
-
-}
-
-
-/*
-========================================================================
-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)
-{
-	struct usb_interface *intf = (struct usb_interface *)_dev_p;
-	struct usb_device *dev_p = interface_to_usbdev(intf);
-	UINT32 i;
-
-
-	for(i=0; i<rtusb_usb_id_len; i++)
-	{
-		if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
-			dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
-		{
-			printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
-					dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
-			break;
-		}
-	}
-
-	if (i == rtusb_usb_id_len)
-	{
-		printk("rt2870: Error! Device Descriptor not matching!\n");
-		return FALSE;
-	}
-
-	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 usb_interface *intf = (struct usb_interface *)_dev_p;
-	struct usb_device *dev_p = interface_to_usbdev(intf);
-
-
-	pAd->config = &dev_p->config->desc;
-	return TRUE;
-}
-
-
-/*
-========================================================================
-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				interface)
-{
-	struct usb_interface *intf = (struct usb_interface *)_dev_p;
-	struct usb_host_interface *iface_desc;
-	ULONG BulkOutIdx;
-	UINT32 i;
-
-
-	/* get the active interface descriptor */
-	iface_desc = intf->cur_altsetting;
-
-	/* get # of enpoints  */
-	pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
-	DBGPRINT(RT_DEBUG_TRACE,
-			("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
-
-	/* Configure Pipes */
-	BulkOutIdx = 0;
-
-	for(i=0; i<pAd->NumberOfPipes; i++)
-	{
-		if ((iface_desc->endpoint[i].desc.bmAttributes ==
-				USB_ENDPOINT_XFER_BULK) &&
-			((iface_desc->endpoint[i].desc.bEndpointAddress &
-				USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
-		{
-			pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
-			pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
-		}
-		else if ((iface_desc->endpoint[i].desc.bmAttributes ==
-					USB_ENDPOINT_XFER_BULK) &&
-				((iface_desc->endpoint[i].desc.bEndpointAddress &
-					USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
-		{
-			// there are 6 bulk out EP. EP6 highest priority.
-			// EP1-4 is EDCA.  EP5 is HCCA.
-			pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
-			pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				("EP address = 0x%2x  \n", iface_desc->endpoint[i].desc.bEndpointAddress));
-		}
-	}
-
-	if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
-	{
-		printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __func__);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Disable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID RT28XXDMADisable(
-	IN RTMP_ADAPTER 		*pAd)
-{
-	// no use
-}
-
-
-
-/*
-========================================================================
-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;
-	USB_DMA_CFG_STRUC	UsbCfg;
-	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.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);
-
-	UsbCfg.word = 0;
-	UsbCfg.field.phyclear = 0;
-	/* usb version is 1.1,do not use bulk in aggregation */
-	if (pAd->BulkInMaxPacketSize == 512)
-			UsbCfg.field.RxBulkAggEn = 1;
-	/* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
-	UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
-	UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
-	UsbCfg.field.RxBulkEn = 1;
-	UsbCfg.field.TxBulkEn = 1;
-
-	RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.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)
-{
-	PUCHAR        	pBeaconFrame = NULL;
-	UCHAR  			*ptr;
-	UINT  			i, padding;
-	BEACON_SYNC_STRUCT	*pBeaconSync = pAd->CommonCfg.pBeaconSync;
-	UINT32			longValue;
-	BOOLEAN			bBcnReq = FALSE;
-	UCHAR			bcn_idx = 0;
-
-
-	if (pBeaconFrame == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
-		return;
-	}
-
-	if (pBeaconSync == NULL)
-	{
-		DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
-		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);
-		}
-		pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
-		NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
-	}
-	else
-	{
-		ptr = (PUCHAR)&pAd->BeaconTxWI;
-
-		if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
-		{	// If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
-			pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
-			NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
-		}
-
-		if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
-		{
-			for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
-			{
-				longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
-				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
-				ptr += 4;
-			}
-		}
-
-		ptr = pBeaconSync->BeaconBuf[bcn_idx];
-		padding = (FrameLen & 0x01);
-		NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
-		FrameLen += padding;
-		for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
-		{
-			if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
-			{
-				NdisMoveMemory(ptr, pBeaconFrame, 2);
-				//shortValue = *ptr + (*(ptr+1)<<8);
-				//RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
-				RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
-			}
-			ptr +=2;
-			pBeaconFrame += 2;
-		}
-
-		pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
-
-		// For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
-	}
-
-}
-
-
-VOID RT2870_BssBeaconStop(
-	IN RTMP_ADAPTER *pAd)
-{
-	BEACON_SYNC_STRUCT	*pBeaconSync;
-	int i, offset;
-	BOOLEAN	Cancelled = TRUE;
-
-	pBeaconSync = pAd->CommonCfg.pBeaconSync;
-	if (pBeaconSync && pBeaconSync->EnableBeacon)
-	{
-		INT NumOfBcn;
-
-		NumOfBcn = MAX_MESH_NUM;
-
-		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
-
-		for(i=0; i<NumOfBcn; i++)
-		{
-			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
-
-			for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
-				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
-
-			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
-			pBeaconSync->TimIELocationInBeacon[i] = 0;
-		}
-		pBeaconSync->BeaconBitMap = 0;
-		pBeaconSync->DtimBitOn = 0;
-	}
-}
-
-
-VOID RT2870_BssBeaconStart(
-	IN RTMP_ADAPTER *pAd)
-{
-	int apidx;
-	BEACON_SYNC_STRUCT	*pBeaconSync;
-//	LARGE_INTEGER 	tsfTime, deltaTime;
-
-	pBeaconSync = pAd->CommonCfg.pBeaconSync;
-	if (pBeaconSync && pBeaconSync->EnableBeacon)
-	{
-		INT NumOfBcn;
-
-		NumOfBcn = MAX_MESH_NUM;
-
-		for(apidx=0; apidx<NumOfBcn; apidx++)
-		{
-			UCHAR CapabilityInfoLocationInBeacon = 0;
-			UCHAR TimIELocationInBeacon = 0;
-
-			NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
-			pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
-			pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
-		}
-		pBeaconSync->BeaconBitMap = 0;
-		pBeaconSync->DtimBitOn = 0;
-		pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
-
-		pAd->CommonCfg.BeaconAdjust = 0;
-		pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
-		pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
-		printk(RT28xx_CHIP_NAME "_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
-		RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
-
-	}
-}
-
-
-VOID RT2870_BssBeaconInit(
-	IN RTMP_ADAPTER *pAd)
-{
-	BEACON_SYNC_STRUCT	*pBeaconSync;
-	int i;
-
-	NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
-	if (pAd->CommonCfg.pBeaconSync)
-	{
-		pBeaconSync = pAd->CommonCfg.pBeaconSync;
-		NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
-		for(i=0; i < HW_BEACON_MAX_COUNT; i++)
-		{
-			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
-			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
-			pBeaconSync->TimIELocationInBeacon[i] = 0;
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
-		}
-		pBeaconSync->BeaconBitMap = 0;
-
-		//RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
-		pBeaconSync->EnableBeacon = TRUE;
-	}
-}
-
-
-VOID RT2870_BssBeaconExit(
-	IN RTMP_ADAPTER *pAd)
-{
-	BEACON_SYNC_STRUCT	*pBeaconSync;
-	BOOLEAN	Cancelled = TRUE;
-	int i;
-
-	if (pAd->CommonCfg.pBeaconSync)
-	{
-		pBeaconSync = pAd->CommonCfg.pBeaconSync;
-		pBeaconSync->EnableBeacon = FALSE;
-		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
-		pBeaconSync->BeaconBitMap = 0;
-
-		for(i=0; i<HW_BEACON_MAX_COUNT; i++)
-		{
-			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
-			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
-			pBeaconSync->TimIELocationInBeacon[i] = 0;
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
-		}
-
-		NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
-		pAd->CommonCfg.pBeaconSync = NULL;
-	}
-}
-
-VOID BeaconUpdateExec(
-    IN PVOID SystemSpecific1,
-    IN PVOID FunctionContext,
-    IN PVOID SystemSpecific2,
-    IN PVOID SystemSpecific3)
-{
-	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)FunctionContext;
-	LARGE_INTEGER	tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
-	UINT32			delta, remain, remain_low, remain_high;
-//	BOOLEAN			positive;
-
-	ReSyncBeaconTime(pAd);
-
-
-
-	RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
-	RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
-
-
-	//positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
-	remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
-	remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
-	remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
-	delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
-
-	pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
-
-}
-

+ 23 - 9
drivers/staging/rt2870/Makefile

@@ -1,27 +1,36 @@
+#
 obj-$(CONFIG_RT2870)	+= rt2870sta.o
 
 # TODO: all of these should be removed
 EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-EXTRA_CFLAGS += -DRT2870 -DRT3070
+EXTRA_CFLAGS += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRTMP_TIMER_TASK_SUPPORT
+EXTRA_CFLAGS += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3070
 EXTRA_CFLAGS += -DDBG
 
 rt2870sta-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,10 +43,15 @@ rt2870sta-objs :=		\
 	rt_main_dev.o		\
 	sta_ioctl.o		\
 	common/ba_action.o	\
-	2870_main_dev.o		\
-	common/2870_rtmp_init.o	\
+	usb_main_dev.o		\
+	rt_usb.o		\
+	common/cmm_mac_usb.o	\
 	common/rtusb_io.o	\
 	common/rtusb_bulk.o	\
 	common/rtusb_data.o	\
-	common/cmm_data_2870.o
-
+	common/cmm_data_usb.o	\
+	common/rtmp_mcu.o	\
+	common/ee_efuse.o	\
+	chips/rt30xx.o		\
+	common/rt_rf.o		\
+	chips/rt3070.o

+ 1 - 0
drivers/staging/rt2870/chips/rt3070.c

@@ -0,0 +1 @@
+#include "../../rt2860/chips/rt3070.c"

+ 1 - 0
drivers/staging/rt2870/chips/rt30xx.c

@@ -0,0 +1 @@
+#include "../../rt2860/chips/rt30xx.c"

+ 0 - 1730
drivers/staging/rt2870/common/2870_rtmp_init.c

@@ -1,1730 +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_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.
-	Sample Lin	2007-05-31    Merge RT2860 and RT2870 drivers.
-*/
-
-#include "../rt_config.h"
-
-
-static void rx_done_tasklet(unsigned long data);
-static void rt2870_hcca_dma_done_tasklet(unsigned long data);
-static void rt2870_ac3_dma_done_tasklet(unsigned long data);
-static void rt2870_ac2_dma_done_tasklet(unsigned long data);
-static void rt2870_ac1_dma_done_tasklet(unsigned long data);
-static void rt2870_ac0_dma_done_tasklet(unsigned long data);
-static void rt2870_mgmt_dma_done_tasklet(unsigned long data);
-static void rt2870_null_frame_complete_tasklet(unsigned long data);
-static void rt2870_rts_frame_complete_tasklet(unsigned long data);
-static void rt2870_pspoll_frame_complete_tasklet(unsigned long data);
-static void rt2870_dataout_complete_tasklet(unsigned long data);
-
-
-/*
-========================================================================
-Routine Description:
-    Initialize receive data structures.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_RESOURCES
-
-Note:
-	Initialize all receive releated private buffer, include those define
-	in RTMP_ADAPTER structure and all private data structures. The mahor
-	work is to allocate buffer for each packet and chain buffer to
-	NDIS packet descriptor.
-========================================================================
-*/
-NDIS_STATUS	NICInitRecv(
-	IN	PRTMP_ADAPTER	pAd)
-{
-	UCHAR				i;
-	NDIS_STATUS			Status = NDIS_STATUS_SUCCESS;
-	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
-	pObj = pObj;
-
-	//InterlockedExchange(&pAd->PendingRx, 0);
-	pAd->PendingRx = 0;
-	pAd->NextRxBulkInReadIndex 	= 0;	// Next Rx Read index
-	pAd->NextRxBulkInIndex		= 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
-	pAd->NextRxBulkInPosition 	= 0;
-
-	for (i = 0; i < (RX_RING_SIZE); i++)
-	{
-		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
-
-		//Allocate URB
-		pRxContext->pUrb = RTUSB_ALLOC_URB(0);
-		if (pRxContext->pUrb == NULL)
-		{
-			Status = NDIS_STATUS_RESOURCES;
-			goto out1;
-		}
-
-		// Allocate transfer buffer
-		pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
-		if (pRxContext->TransferBuffer == NULL)
-		{
-			Status = NDIS_STATUS_RESOURCES;
-			goto out1;
-		}
-
-		NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
-
-		pRxContext->pAd	= pAd;
-		pRxContext->pIrp = NULL;
-		pRxContext->InUse		= FALSE;
-		pRxContext->IRPPending	= FALSE;
-		pRxContext->Readable	= FALSE;
-		//pRxContext->ReorderInUse = FALSE;
-		pRxContext->bRxHandling = FALSE;
-		pRxContext->BulkInOffset = 0;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n"));
-	return Status;
-
-out1:
-	for (i = 0; i < (RX_RING_SIZE); i++)
-	{
-		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
-
-		if (NULL != pRxContext->TransferBuffer)
-		{
-			RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
-								pRxContext->TransferBuffer, pRxContext->data_dma);
-			pRxContext->TransferBuffer = NULL;
-		}
-
-		if (NULL != pRxContext->pUrb)
-		{
-			RTUSB_UNLINK_URB(pRxContext->pUrb);
-			RTUSB_FREE_URB(pRxContext->pUrb);
-			pRxContext->pUrb = NULL;
-		}
-	}
-
-	return Status;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Initialize transmit data structures.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-NDIS_STATUS	NICInitTransmit(
-	IN	PRTMP_ADAPTER	pAd)
-{
-#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2)	\
-	Context->pUrb = RTUSB_ALLOC_URB(0);		\
-	if (Context->pUrb == NULL) {			\
-		DBGPRINT(RT_DEBUG_ERROR, msg1);		\
-		Status = NDIS_STATUS_RESOURCES;		\
-		goto err1; }						\
-											\
-	Context->TransferBuffer = 				\
-		(TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma);	\
-	if (Context->TransferBuffer == NULL) {	\
-		DBGPRINT(RT_DEBUG_ERROR, msg2);		\
-		Status = NDIS_STATUS_RESOURCES;		\
-		goto err2; }
-
-#define LM_URB_FREE(pObj, Context, BufferSize)				\
-	if (NULL != Context->pUrb) {							\
-		RTUSB_UNLINK_URB(Context->pUrb);					\
-		RTUSB_FREE_URB(Context->pUrb);						\
-		Context->pUrb = NULL; }								\
-	if (NULL != Context->TransferBuffer) {				\
-		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
-								Context->TransferBuffer,	\
-								Context->data_dma);			\
-		Context->TransferBuffer = NULL; }
-
-	UCHAR			i, acidx;
-	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
-	PTX_CONTEXT		pNullContext   = &(pAd->NullContext);
-	PTX_CONTEXT		pPsPollContext = &(pAd->PsPollContext);
-	PTX_CONTEXT		pRTSContext    = &(pAd->RTSContext);
-	PTX_CONTEXT		pMLMEContext = NULL;
-//	PHT_TX_CONTEXT	pHTTXContext = NULL;
-	POS_COOKIE		pObj = (POS_COOKIE) pAd->OS_Cookie;
-	PVOID			RingBaseVa;
-//	RTMP_TX_RING	*pTxRing;
-	RTMP_MGMT_RING  *pMgmtRing;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
-	pObj = pObj;
-
-	// Init 4 set of Tx parameters
-	for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
-	{
-		// Initialize all Transmit releated queues
-		InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
-
-		// Next Local tx ring pointer waiting for buck out
-		pAd->NextBulkOutIndex[acidx] = acidx;
-		pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
-		//pAd->DataBulkDoneIdx[acidx] = 0;
-	}
-
-	//pAd->NextMLMEIndex	= 0;
-	//pAd->PushMgmtIndex	= 0;
-	//pAd->PopMgmtIndex	= 0;
-	//InterlockedExchange(&pAd->MgmtQueueSize, 0);
-	//InterlockedExchange(&pAd->TxCount, 0);
-
-	//pAd->PrioRingFirstIndex	= 0;
-	//pAd->PrioRingTxCnt		= 0;
-
-	do
-	{
-		//
-		// TX_RING_SIZE, 4 ACs
-		//
-		for(acidx=0; acidx<4; acidx++)
-		{
-			PHT_TX_CONTEXT	pHTTXContext = &(pAd->TxContext[acidx]);
-
-			NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
-			//Allocate URB
-			LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
-							("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
-							done,
-							("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
-							out1);
-
-			NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
-			pHTTXContext->pAd = pAd;
-			pHTTXContext->pIrp = NULL;
-			pHTTXContext->IRPPending = FALSE;
-			pHTTXContext->NextBulkOutPosition = 0;
-			pHTTXContext->ENextBulkOutPosition = 0;
-			pHTTXContext->CurWritePosition = 0;
-			pHTTXContext->CurWriteRealPos = 0;
-			pHTTXContext->BulkOutSize = 0;
-			pHTTXContext->BulkOutPipeId = acidx;
-			pHTTXContext->bRingEmpty = TRUE;
-			pHTTXContext->bCopySavePad = FALSE;
-
-			pAd->BulkOutPending[acidx] = FALSE;
-		}
-
-
-		//
-		// MGMT_RING_SIZE
-		//
-		// Allocate MGMT ring descriptor's memory
-		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
-		RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
-		if (pAd->MgmtDescRing.AllocVa == NULL)
-		{
-			DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
-			Status = NDIS_STATUS_RESOURCES;
-			goto out1;
-		}
-		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
-		RingBaseVa     = pAd->MgmtDescRing.AllocVa;
-
-		// Initialize MGMT Ring and associated buffer memory
-		pMgmtRing = &pAd->MgmtRing;
-		for (i = 0; i < MGMT_RING_SIZE; i++)
-		{
-			// link the pre-allocated Mgmt buffer to MgmtRing.Cell
-			pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
-			pMgmtRing->Cell[i].AllocVa = RingBaseVa;
-			pMgmtRing->Cell[i].pNdisPacket = NULL;
-			pMgmtRing->Cell[i].pNextNdisPacket = NULL;
-
-			//Allocate URB for MLMEContext
-			pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
-			pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
-			if (pMLMEContext->pUrb == NULL)
-			{
-				DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
-				Status = NDIS_STATUS_RESOURCES;
-				goto out2;
-			}
-			pMLMEContext->pAd = pAd;
-			pMLMEContext->pIrp = NULL;
-			pMLMEContext->TransferBuffer = NULL;
-			pMLMEContext->InUse = FALSE;
-			pMLMEContext->IRPPending = FALSE;
-			pMLMEContext->bWaitingBulkOut = FALSE;
-			pMLMEContext->BulkOutSize = 0;
-			pMLMEContext->SelfIdx = i;
-
-			// Offset to next ring descriptor address
-			RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
-		}
-		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
-
-		//pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
-		pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
-		pAd->MgmtRing.TxCpuIdx = 0;
-		pAd->MgmtRing.TxDmaIdx = 0;
-
-		//
-		// BEACON_RING_SIZE
-		//
-		for(i=0; i<BEACON_RING_SIZE; i++) // 2
-		{
-			PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
-
-
-			NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
-
-			//Allocate URB
-			LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
-							("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
-							out2,
-							("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
-							out3);
-
-			pBeaconContext->pAd = pAd;
-			pBeaconContext->pIrp = NULL;
-			pBeaconContext->InUse = FALSE;
-			pBeaconContext->IRPPending = FALSE;
-		}
-
-		//
-		// NullContext
-		//
-		NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
-
-		//Allocate URB
-		LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
-						("<-- ERROR in Alloc TX NullContext urb!! \n"),
-						out3,
-						("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
-						out4);
-
-		pNullContext->pAd = pAd;
-		pNullContext->pIrp = NULL;
-		pNullContext->InUse = FALSE;
-		pNullContext->IRPPending = FALSE;
-
-		//
-		// RTSContext
-		//
-		NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
-
-		//Allocate URB
-		LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
-						("<-- ERROR in Alloc TX RTSContext urb!! \n"),
-						out4,
-						("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
-						out5);
-
-		pRTSContext->pAd = pAd;
-		pRTSContext->pIrp = NULL;
-		pRTSContext->InUse = FALSE;
-		pRTSContext->IRPPending = FALSE;
-
-		//
-		// PsPollContext
-		//
-		//NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
-		//Allocate URB
-		LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
-						("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
-						out5,
-						("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
-						out6);
-
-		pPsPollContext->pAd = pAd;
-		pPsPollContext->pIrp = NULL;
-		pPsPollContext->InUse = FALSE;
-		pPsPollContext->IRPPending = FALSE;
-		pPsPollContext->bAggregatible = FALSE;
-		pPsPollContext->LastOne = TRUE;
-
-	}   while (FALSE);
-
-
-done:
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
-
-	return Status;
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-out6:
-	LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
-
-out5:
-	LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
-
-out4:
-	LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
-
-out3:
-	for(i=0; i<BEACON_RING_SIZE; i++)
-	{
-		PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
-		if (pBeaconContext)
-			LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
-	}
-
-out2:
-	if (pAd->MgmtDescRing.AllocVa)
-	{
-		pMgmtRing = &pAd->MgmtRing;
-	for(i=0; i<MGMT_RING_SIZE; i++)
-	{
-		pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
-		if (pMLMEContext)
-			LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
-	}
-		NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
-		pAd->MgmtDescRing.AllocVa = NULL;
-	}
-
-out1:
-	for (acidx = 0; acidx < 4; acidx++)
-	{
-		PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
-		if (pTxContext)
-			LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
-	}
-
-	// Here we didn't have any pre-allocated memory need to free.
-
-	return Status;
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Allocate DMA memory blocks for send, receive.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-NDIS_STATUS	RTMPAllocTxRxRingMemory(
-	IN	PRTMP_ADAPTER	pAd)
-{
-//	COUNTER_802_11	pCounter = &pAd->WlanCounters;
-	NDIS_STATUS		Status;
-	INT				num;
-
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
-
-
-	do
-	{
-		// Init the CmdQ and CmdQLock
-		NdisAllocateSpinLock(&pAd->CmdQLock);
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		RTUSBInitializeCmdQ(&pAd->CmdQ);
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-
-
-		NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
-		//NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
-		NdisAllocateSpinLock(&pAd->BulkInLock);
-
-		for (num = 0; num < NUM_OF_TX_RING; num++)
-		{
-			NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
-		}
-
-//		NdisAllocateSpinLock(&pAd->MemLock);	// Not used in RT28XX
-
-//		NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
-//		NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
-
-//		for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
-//		{
-//			NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
-//		}
-
-		//
-		// Init Mac Table
-		//
-//		MacTableInitialize(pAd);
-
-		//
-		// Init send data structures and related parameters
-		//
-		Status = NICInitTransmit(pAd);
-		if (Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		//
-		// Init receive data structures and related parameters
-		//
-		Status = NICInitRecv(pAd);
-		if (Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		pAd->PendingIoCount = 1;
-
-	} 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;
-	}
-
-	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
-	return Status;
-}
-
-
-/*
-========================================================================
-Routine Description:
-	Calls USB_InterfaceStop and frees memory allocated for the URBs
-    calls NdisMDeregisterDevice and frees the memory
-    allocated in VNetInitialize for the Adapter Object
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-VOID	RTMPFreeTxRxRingMemory(
-	IN	PRTMP_ADAPTER	pAd)
-{
-#define LM_URB_FREE(pObj, Context, BufferSize)				\
-	if (NULL != Context->pUrb) {							\
-		RTUSB_UNLINK_URB(Context->pUrb);					\
-		RTUSB_FREE_URB(Context->pUrb);						\
-		Context->pUrb = NULL; }								\
-	if (NULL != Context->TransferBuffer) {					\
-		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
-								Context->TransferBuffer,	\
-								Context->data_dma);			\
-		Context->TransferBuffer = NULL; }
-
-
-	UINT                i, acidx;
-	PTX_CONTEXT			pNullContext   = &pAd->NullContext;
-	PTX_CONTEXT			pPsPollContext = &pAd->PsPollContext;
-	PTX_CONTEXT			pRTSContext    = &pAd->RTSContext;
-//	PHT_TX_CONTEXT 		pHTTXContext;
-	//PRTMP_REORDERBUF	pReorderBuf;
-	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
-//	RTMP_TX_RING		*pTxRing;
-
-	DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
-	pObj = pObj;
-
-	// Free all resources for the RECEIVE buffer queue.
-	for(i=0; i<(RX_RING_SIZE); i++)
-	{
-		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
-		if (pRxContext)
-			LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
-	}
-
-	// Free PsPoll frame resource
-	LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
-
-	// Free NULL frame resource
-	LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
-
-	// Free RTS frame resource
-	LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
-
-
-	// Free beacon frame resource
-	for(i=0; i<BEACON_RING_SIZE; i++)
-	{
-		PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
-		if (pBeaconContext)
-			LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
-	}
-
-
-	// Free mgmt frame resource
-	for(i = 0; i < MGMT_RING_SIZE; i++)
-	{
-		PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
-		//LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
-		if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
-		{
-			RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
-			pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
-			pMLMEContext->TransferBuffer = NULL;
-		}
-
-		if (pMLMEContext)
-		{
-			if (NULL != pMLMEContext->pUrb)
-			{
-				RTUSB_UNLINK_URB(pMLMEContext->pUrb);
-				RTUSB_FREE_URB(pMLMEContext->pUrb);
-				pMLMEContext->pUrb = NULL;
-			}
-		}
-	}
-	if (pAd->MgmtDescRing.AllocVa)
-		NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
-
-
-	// Free Tx frame resource
-		for(acidx=0; acidx<4; acidx++)
-		{
-		PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
-			if (pHTTXContext)
-				LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
-		}
-
-	if (pAd->FragFrame.pFragPacket)
-		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
-
-	for(i=0; i<6; i++)
-	{
-		NdisFreeSpinLock(&pAd->BulkOutLock[i]);
-	}
-
-	NdisFreeSpinLock(&pAd->BulkInLock);
-	NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
-
-	NdisFreeSpinLock(&pAd->CmdQLock);
-
-	// Clear all pending bulk-out request flags.
-	RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
-
-//	NdisFreeSpinLock(&pAd->MacTabLock);
-
-//	for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
-//	{
-//		NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
-//	}
-
-	DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Allocate memory for adapter control block.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-NDIS_STATUS AdapterBlockAllocateMemory(
-	IN PVOID	handle,
-	OUT	PVOID	*ppAd)
-{
-	PUSB_DEV	usb_dev;
-	POS_COOKIE	pObj = (POS_COOKIE) handle;
-
-
-	usb_dev = pObj->pUsb_Dev;
-
-	pObj->MLMEThr_pid	= NULL;
-	pObj->RTUSBCmdThr_pid	= NULL;
-
-	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
-
-	if (*ppAd)
-	{
-		NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
-		((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
-		return (NDIS_STATUS_SUCCESS);
-	}
-	else
-	{
-		return (NDIS_STATUS_FAILURE);
-	}
-}
-
-
-/*
-========================================================================
-Routine Description:
-    Create kernel threads & tasklets.
-
-Arguments:
-    *net_dev			Pointer to wireless net device interface
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-
-Note:
-========================================================================
-*/
-NDIS_STATUS	 CreateThreads(
-	IN	struct net_device *net_dev)
-{
-	PRTMP_ADAPTER pAd = net_dev->ml_priv;
-	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
-	pid_t pid_number;
-
-	//init_MUTEX(&(pAd->usbdev_semaphore));
-
-	init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
-	init_completion (&pAd->mlmeComplete);
-
-	init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
-	init_completion (&pAd->CmdQComplete);
-
-	init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
-	init_completion (&pAd->TimerQComplete);
-
-	// Creat MLME Thread
-	pObj->MLMEThr_pid = NULL;
-	pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-	{
-		printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	pObj->MLMEThr_pid = find_get_pid(pid_number);
-
-	// Wait for the thread to start
-	wait_for_completion(&(pAd->mlmeComplete));
-
-	// Creat Command Thread
-	pObj->RTUSBCmdThr_pid = NULL;
-	pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-	{
-		printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	pObj->RTUSBCmdThr_pid = find_get_pid(pid_number);
-
-	wait_for_completion(&(pAd->CmdQComplete));
-
-	pObj->TimerQThr_pid = NULL;
-	pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-	{
-		printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	pObj->TimerQThr_pid = find_get_pid(pid_number);
-
-	// Wait for the thread to start
-	wait_for_completion(&(pAd->TimerQComplete));
-
-	// Create receive tasklet
-	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
-	tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-========================================================================
-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
-
-Note:
-========================================================================
-*/
-VOID	RTMPAddBSSIDCipher(
-	IN	PRTMP_ADAPTER		pAd,
-	IN	UCHAR				Aid,
-	IN	PNDIS_802_11_KEY	pKey,
-	IN  UCHAR   			CipherAlg)
-{
-	PUCHAR		pTxMic, pRxMic;
-	BOOLEAN 	bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
-//	UCHAR		CipherAlg;
-	UCHAR		i;
-	ULONG		WCIDAttri;
-	USHORT	 	offset;
-	UCHAR		KeyIdx, IVEIV[8];
-	UINT32		Value;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
-
-	// Bit 29 of Add-key KeyRSC
-	bKeyRSC 	   = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
-
-	// Bit 28 of Add-key Authenticator
-	bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
-	KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
-
-	if (KeyIdx > 4)
-		return;
-
-
-	if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
-	{	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-		{
-			// for WPA-None Tx, Rx MIC is the same
-			pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
-			pRxMic = pTxMic;
-		}
-		else if (bAuthenticator == TRUE)
-		{
-			pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
-			pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
-		}
-		else
-		{
-			pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
-			pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
-		}
-
-		offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
-		for (i=0; i<8; )
-		{
-			Value = *(pTxMic+i);
-			Value += (*(pTxMic+i+1)<<8);
-			Value += (*(pTxMic+i+2)<<16);
-			Value += (*(pTxMic+i+3)<<24);
-			RTUSBWriteMACRegister(pAd, offset+i, Value);
-			i+=4;
-		}
-
-		offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
-		for (i=0; i<8; )
-		{
-			Value = *(pRxMic+i);
-			Value += (*(pRxMic+i+1)<<8);
-			Value += (*(pRxMic+i+2)<<16);
-			Value += (*(pRxMic+i+3)<<24);
-			RTUSBWriteMACRegister(pAd, offset+i, Value);
-			i+=4;
-		}
-
-		// Only Key lenth equal to TKIP key have these
-		NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
-		NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-				("	TxMIC  = %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]));
-		DBGPRINT(RT_DEBUG_TRACE,
-				("	RxMIC  = %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]));
-	}
-
-	// 2. Record Security Key.
-	pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
-	NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
-
-	// 3. Check RxTsc. And used to init to ASIC IV.
-	if (bKeyRSC == TRUE)
-		NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
-	else
-		NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
-
-	// 4. Init TxTsc to one based on WiFi WPA specs
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
-	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
-
-	CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
-
-	offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
-	RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
-				((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
-
-	offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
-	RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
-
-	offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
-	NdisZeroMemory(IVEIV, 8);
-
-	// IV/EIV
-	if ((CipherAlg == CIPHER_TKIP) ||
-		(CipherAlg == CIPHER_TKIP_NO_MIC) ||
-		(CipherAlg == CIPHER_AES))
-	{
-		IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
-	}
-	// default key idx needs to set.
-	// in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
-	else
-	{
-		IVEIV[3] |= (KeyIdx<< 6);
-	}
-	RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
-
-	// WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
-	if ((CipherAlg == CIPHER_TKIP) ||
-		(CipherAlg == CIPHER_TKIP_NO_MIC) ||
-		(CipherAlg == CIPHER_AES))
-	{
-		WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
-	}
-	else
-		WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
-
-	offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
-	RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
-	RTUSBReadMACRegister(pAd, offset, &Value);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
-			offset, WCIDAttri));
-
-	// pAddr
-	// Add Bssid mac address at linkup. not here.  check!
-	/*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
-	*for (i=0; i<MAC_ADDR_LEN; i++)
-	{
-		RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
-	}
-	*/
-
-	DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
-			CipherName[CipherAlg], pKey->KeyLength));
-	DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
-			pKey->KeyIndex, pKey->KeyLength));
-	for(i=0; i<pKey->KeyLength; i++)
-		DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
-	DBGPRINT(RT_DEBUG_TRACE,("	 \n"));
-}
-
-/*
-========================================================================
-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:
-========================================================================
-*/
-#define RT2870_RXDMALEN_FIELD_SIZE			4
-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",
-									__func__, 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", __func__));
-		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:
-    Handle received packets.
-
-Arguments:
-	data				- URB information pointer
-
-Return Value:
-    None
-
-Note:
-========================================================================
-*/
-static void rx_done_tasklet(unsigned long data)
-{
-	purbb_t 			pUrb;
-	PRX_CONTEXT			pRxContext;
-	PRTMP_ADAPTER		pAd;
-	NTSTATUS			Status;
-	unsigned int		IrqFlags;
-
-	pUrb		= (purbb_t)data;
-	pRxContext	= (PRX_CONTEXT)pUrb->context;
-	pAd 		= pRxContext->pAd;
-	Status = pUrb->status;
-
-
-	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-	pRxContext->InUse = FALSE;
-	pRxContext->IRPPending = FALSE;
-	pRxContext->BulkInOffset += pUrb->actual_length;
-	//NdisInterlockedDecrement(&pAd->PendingRx);
-	pAd->PendingRx--;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		pAd->BulkInComplete++;
-		pAd->NextRxBulkInPosition = 0;
-		if (pRxContext->BulkInOffset)	// As jan's comment, it may bulk-in success but size is zero.
-		{
-			pRxContext->Readable = TRUE;
-			INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
-		}
-		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-	}
-	else	 // STATUS_OTHER
-	{
-		pAd->BulkInCompleteFail++;
-		// Still read this packet although it may comtain wrong bytes.
-		pRxContext->Readable = FALSE;
-		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-
-		// Parsing all packets. because after reset, the index will reset to all zero.
-		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-									fRTMP_ADAPTER_BULKIN_RESET |
-									fRTMP_ADAPTER_HALT_IN_PROGRESS |
-									fRTMP_ADAPTER_NIC_NOT_EXIST))))
-		{
-
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
-							Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
-
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
-		}
-	}
-
-	ASSERT((pRxContext->InUse == pRxContext->IRPPending));
-
-	RTUSBBulkReceive(pAd);
-
-	return;
-
-}
-
-
-static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER 	pAd;
-	PTX_CONTEXT		pMLMEContext;
-	int				index;
-	PNDIS_PACKET	pPacket;
-	purbb_t			pUrb;
-	NTSTATUS		Status;
-	unsigned long	IrqFlags;
-
-
-	pUrb			= (purbb_t)data;
-	pMLMEContext	= (PTX_CONTEXT)pUrb->context;
-	pAd 			= pMLMEContext->pAd;
-	Status			= pUrb->status;
-	index 			= pMLMEContext->SelfIdx;
-
-	ASSERT((pAd->MgmtRing.TxDmaIdx == index));
-
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-
-
-	if (Status != USB_ST_NOERROR)
-	{
-		//Bulk-Out fail status handle
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
-			// TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-		}
-	}
-
-	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
-	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-
-	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-	// Reset MLME context flags
-	pMLMEContext->IRPPending = FALSE;
-	pMLMEContext->InUse = FALSE;
-	pMLMEContext->bWaitingBulkOut = FALSE;
-	pMLMEContext->BulkOutSize = 0;
-
-	pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
-	pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
-
-	// Increase MgmtRing Index
-	INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
-	pAd->MgmtRing.TxSwFreeIdx++;
-	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-
-	// No-matter success or fail, we free the mgmt packet.
-	if (pPacket)
-		RTMPFreeNdisPacket(pAd, pPacket);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
-			((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
-		{	// For Mgmt Bulk-Out failed, ignore it now.
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{
-
-			// Always call Bulk routine, even reset bulk.
-			// The protectioon of rest bulk should be in BulkOut routine
-			if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
-			{
-				RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
-			}
-				RTUSBKickBulkOut(pAd);
-			}
-		}
-
-}
-
-
-static void rt2870_hcca_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 4;
-	purbb_t				pUrb;
-
-	DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n"));
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<4);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-	DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n"));
-}
-
-
-static void rt2870_ac3_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 3;
-	purbb_t				pUrb;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-
-		return;
-}
-
-
-static void rt2870_ac2_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 2;
-	purbb_t				pUrb;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-		return;
-}
-
-
-static void rt2870_ac1_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 1;
-	purbb_t				pUrb;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-
-	return;
-}
-
-
-static void rt2870_ac0_dma_done_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId = 0;
-	purbb_t				pUrb;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-
-	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-								fRTMP_ADAPTER_HALT_IN_PROGRESS |
-								fRTMP_ADAPTER_NIC_NOT_EXIST))))
-	{
-		// do nothing and return directly.
-	}
-	else
-	{
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
-		{
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-				/*  ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-				(pHTTXContext->bCurWriting == FALSE))
-			{
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-
-	return;
-
-}
-
-
-static void rt2870_null_frame_complete_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER	pAd;
-	PTX_CONTEXT		pNullContext;
-	purbb_t			pUrb;
-	NTSTATUS		Status;
-	unsigned long	irqFlag;
-
-
-	pUrb			= (purbb_t)data;
-	pNullContext	= (PTX_CONTEXT)pUrb->context;
-	pAd 			= pNullContext->pAd;
-	Status 			= pUrb->status;
-
-	// Reset Null frame context flags
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
-	pNullContext->IRPPending 	= FALSE;
-	pNullContext->InUse 		= FALSE;
-	pAd->BulkOutPending[0] = FALSE;
-	pAd->watchDogTxPendingCnt[0] = 0;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	}
-	else	// STATUS_OTHER
-	{
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-		}
-	}
-
-	// Always call Bulk routine, even reset bulk.
-	// The protectioon of rest bulk should be in BulkOut routine
-	RTUSBKickBulkOut(pAd);
-
-}
-
-
-static void rt2870_rts_frame_complete_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER	pAd;
-	PTX_CONTEXT		pRTSContext;
-	purbb_t			pUrb;
-	NTSTATUS		Status;
-	unsigned long	irqFlag;
-
-
-	pUrb		= (purbb_t)data;
-	pRTSContext	= (PTX_CONTEXT)pUrb->context;
-	pAd			= pRTSContext->pAd;
-	Status		= pUrb->status;
-
-	// Reset RTS frame context flags
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
-	pRTSContext->IRPPending = FALSE;
-	pRTSContext->InUse		= FALSE;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	}
-	else	// STATUS_OTHER
-	{
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-		else
-		{
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-		}
-	}
-
-	RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
-	pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
-	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
-
-	// Always call Bulk routine, even reset bulk.
-	// The protectioon of rest bulk should be in BulkOut routine
-	RTUSBKickBulkOut(pAd);
-
-}
-
-
-static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER	pAd;
-	PTX_CONTEXT		pPsPollContext;
-	purbb_t			pUrb;
-	NTSTATUS		Status;
-
-
-	pUrb			= (purbb_t)data;
-	pPsPollContext	= (PTX_CONTEXT)pUrb->context;
-	pAd				= pPsPollContext->pAd;
-	Status			= pUrb->status;
-
-	// Reset PsPoll context flags
-	pPsPollContext->IRPPending	= FALSE;
-	pPsPollContext->InUse		= FALSE;
-	pAd->watchDogTxPendingCnt[0] = 0;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	}
-	else // STATUS_OTHER
-	{
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
-		}
-	}
-
-	RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
-	pAd->BulkOutPending[0] = FALSE;
-	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
-
-	// Always call Bulk routine, even reset bulk.
-	// The protectioon of rest bulk should be in BulkOut routine
-	RTUSBKickBulkOut(pAd);
-
-}
-
-
-static void rt2870_dataout_complete_tasklet(unsigned long data)
-{
-	PRTMP_ADAPTER		pAd;
-	purbb_t				pUrb;
-	POS_COOKIE			pObj;
-	PHT_TX_CONTEXT		pHTTXContext;
-	UCHAR				BulkOutPipeId;
-	NTSTATUS			Status;
-	unsigned long		IrqFlags;
-
-
-	pUrb			= (purbb_t)data;
-	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
-	pAd				= pHTTXContext->pAd;
-	pObj 			= (POS_COOKIE) pAd->OS_Cookie;
-	Status			= pUrb->status;
-
-	// Store BulkOut PipeId
-	BulkOutPipeId = pHTTXContext->BulkOutPipeId;
-	pAd->BulkOutDataOneSecCount++;
-
-	//DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
-	//		pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
-
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
-	pHTTXContext->IRPPending = FALSE;
-	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
-
-	if (Status == USB_ST_NOERROR)
-	{
-		pAd->BulkOutComplete++;
-
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-
-		pAd->Counters8023.GoodTransmits++;
-		//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-		FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
-		//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-
-
-	}
-	else	// STATUS_OTHER
-	{
-		PUCHAR	pBuf;
-
-		pAd->BulkOutCompleteOther++;
-
-		pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
-
-		if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-									fRTMP_ADAPTER_HALT_IN_PROGRESS |
-									fRTMP_ADAPTER_NIC_NOT_EXIST |
-									fRTMP_ADAPTER_BULKOUT_RESET)))
-		{
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = BulkOutPipeId;
-			pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
-		}
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
-		//DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
-
-	}
-
-	//
-	// bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
-	// bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
-	//
-	//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-	if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
-		(pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
-		!RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
-	{
-		// Indicate There is data avaliable
-		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
-	}
-	//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-
-	// Always call Bulk routine, even reset bulk.
-	// The protection of rest bulk should be in BulkOut routine
-	RTUSBKickBulkOut(pAd);
-}
-
-/* End of 2870_rtmp_init.c */

+ 1 - 0
drivers/staging/rt2870/common/acction.c

@@ -0,0 +1 @@
+#include "../../rt2860/common/action.c"

+ 1 - 0
drivers/staging/rt2870/common/cmm_aes.c

@@ -0,0 +1 @@
+#include "../../rt2860/common/cmm_aes.c"

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov