Merge branch 'tc1100-wmi' into release
[deliverable/linux.git] / drivers / staging / rt2860 / common / mlme.c
index 61a2a4eb7140db39d2fa8d01f8735e27f75bb8fc..9fc34a8f218022dc651a984d1c323bc1836e484c 100644 (file)
 #include "../rt_config.h"
 #include <stdarg.h>
 
-UCHAR  CISCO_OUI[] = {0x00, 0x40, 0x96};
-
-UCHAR  WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
-UCHAR  RSN_OUI[] = {0x00, 0x0f, 0xac};
-UCHAR   WME_INFO_ELEM[]  = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
-UCHAR   WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
-UCHAR  Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
-UCHAR   RALINK_OUI[]  = {0x00, 0x0c, 0x43};
-UCHAR   BROADCOM_OUI[]  = {0x00, 0x90, 0x4c};
-UCHAR   WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
-UCHAR  PRE_N_HT_OUI[]  = {0x00, 0x90, 0x4c};
-
-UCHAR RateSwitchTable[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x11, 0x00,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
-    0x04, 0x21,  0, 30, 50,
-    0x05, 0x21,  1, 20, 50,
-    0x06, 0x21,  2, 20, 50,
-    0x07, 0x21,  3, 15, 50,
-    0x08, 0x21,  4, 15, 30,
-    0x09, 0x21,  5, 10, 25,
-    0x0a, 0x21,  6,  8, 25,
-    0x0b, 0x21,  7,  8, 25,
-    0x0c, 0x20, 12,  15, 30,
-    0x0d, 0x20, 13,  8, 20,
-    0x0e, 0x20, 14,  8, 20,
-    0x0f, 0x20, 15,  8, 25,
-    0x10, 0x22, 15,  8, 25,
-    0x11, 0x00,  0,  0,  0,
-    0x12, 0x00,  0,  0,  0,
-    0x13, 0x00,  0,  0,  0,
-    0x14, 0x00,  0,  0,  0,
-    0x15, 0x00,  0,  0,  0,
-    0x16, 0x00,  0,  0,  0,
-    0x17, 0x00,  0,  0,  0,
-    0x18, 0x00,  0,  0,  0,
-    0x19, 0x00,  0,  0,  0,
-    0x1a, 0x00,  0,  0,  0,
-    0x1b, 0x00,  0,  0,  0,
-    0x1c, 0x00,  0,  0,  0,
-    0x1d, 0x00,  0,  0,  0,
-    0x1e, 0x00,  0,  0,  0,
-    0x1f, 0x00,  0,  0,  0,
+u8 CISCO_OUI[] = { 0x00, 0x40, 0x96 };
+
+u8 WPA_OUI[] = { 0x00, 0x50, 0xf2, 0x01 };
+u8 RSN_OUI[] = { 0x00, 0x0f, 0xac };
+u8 WME_INFO_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01 };
+u8 WME_PARM_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01 };
+u8 Ccx2QosInfo[] = { 0x00, 0x40, 0x96, 0x04 };
+u8 RALINK_OUI[] = { 0x00, 0x0c, 0x43 };
+u8 BROADCOM_OUI[] = { 0x00, 0x90, 0x4c };
+u8 WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
+u8 PRE_N_HT_OUI[] = { 0x00, 0x90, 0x4c };
+
+u8 RateSwitchTable[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x11, 0x00, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x00, 0, 40, 101,
+       0x01, 0x00, 1, 40, 50,
+       0x02, 0x00, 2, 35, 45,
+       0x03, 0x00, 3, 20, 45,
+       0x04, 0x21, 0, 30, 50,
+       0x05, 0x21, 1, 20, 50,
+       0x06, 0x21, 2, 20, 50,
+       0x07, 0x21, 3, 15, 50,
+       0x08, 0x21, 4, 15, 30,
+       0x09, 0x21, 5, 10, 25,
+       0x0a, 0x21, 6, 8, 25,
+       0x0b, 0x21, 7, 8, 25,
+       0x0c, 0x20, 12, 15, 30,
+       0x0d, 0x20, 13, 8, 20,
+       0x0e, 0x20, 14, 8, 20,
+       0x0f, 0x20, 15, 8, 25,
+       0x10, 0x22, 15, 8, 25,
+       0x11, 0x00, 0, 0, 0,
+       0x12, 0x00, 0, 0, 0,
+       0x13, 0x00, 0, 0, 0,
+       0x14, 0x00, 0, 0, 0,
+       0x15, 0x00, 0, 0, 0,
+       0x16, 0x00, 0, 0, 0,
+       0x17, 0x00, 0, 0, 0,
+       0x18, 0x00, 0, 0, 0,
+       0x19, 0x00, 0, 0, 0,
+       0x1a, 0x00, 0, 0, 0,
+       0x1b, 0x00, 0, 0, 0,
+       0x1c, 0x00, 0, 0, 0,
+       0x1d, 0x00, 0, 0, 0,
+       0x1e, 0x00, 0, 0, 0,
+       0x1f, 0x00, 0, 0, 0,
 };
 
-UCHAR RateSwitchTable11B[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x04, 0x03,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
+u8 RateSwitchTable11B[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x04, 0x03, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x00, 0, 40, 101,
+       0x01, 0x00, 1, 40, 50,
+       0x02, 0x00, 2, 35, 45,
+       0x03, 0x00, 3, 20, 45,
 };
 
-UCHAR RateSwitchTable11BG[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
-    0x04, 0x10,  2, 20, 35,
-    0x05, 0x10,  3, 16, 35,
-    0x06, 0x10,  4, 10, 25,
-    0x07, 0x10,  5, 16, 25,
-    0x08, 0x10,  6, 10, 25,
-    0x09, 0x10,  7, 10, 13,
+u8 RateSwitchTable11BG[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0a, 0x00, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x00, 0, 40, 101,
+       0x01, 0x00, 1, 40, 50,
+       0x02, 0x00, 2, 35, 45,
+       0x03, 0x00, 3, 20, 45,
+       0x04, 0x10, 2, 20, 35,
+       0x05, 0x10, 3, 16, 35,
+       0x06, 0x10, 4, 10, 25,
+       0x07, 0x10, 5, 16, 25,
+       0x08, 0x10, 6, 10, 25,
+       0x09, 0x10, 7, 10, 13,
 };
 
-UCHAR RateSwitchTable11G[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x08, 0x00,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x10,  0, 20, 101,
-    0x01, 0x10,  1, 20, 35,
-    0x02, 0x10,  2, 20, 35,
-    0x03, 0x10,  3, 16, 35,
-    0x04, 0x10,  4, 10, 25,
-    0x05, 0x10,  5, 16, 25,
-    0x06, 0x10,  6, 10, 25,
-    0x07, 0x10,  7, 10, 13,
+u8 RateSwitchTable11G[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x08, 0x00, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x10, 0, 20, 101,
+       0x01, 0x10, 1, 20, 35,
+       0x02, 0x10, 2, 20, 35,
+       0x03, 0x10, 3, 16, 35,
+       0x04, 0x10, 4, 10, 25,
+       0x05, 0x10, 5, 16, 25,
+       0x06, 0x10, 6, 10, 25,
+       0x07, 0x10, 7, 10, 13,
 };
 
-UCHAR RateSwitchTable11N1S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x09, 0x00,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 10, 25,
-    0x06, 0x21,  6,  8, 14,
-    0x07, 0x21,  7,  8, 14,
-    0x08, 0x23,  7,  8, 14,
+u8 RateSwitchTable11N1S[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0c, 0x0a, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x00, 0, 40, 101,
+       0x01, 0x00, 1, 40, 50,
+       0x02, 0x00, 2, 25, 45,
+       0x03, 0x21, 0, 20, 35,
+       0x04, 0x21, 1, 20, 35,
+       0x05, 0x21, 2, 20, 35,
+       0x06, 0x21, 3, 15, 35,
+       0x07, 0x21, 4, 15, 30,
+       0x08, 0x21, 5, 10, 25,
+       0x09, 0x21, 6, 8, 14,
+       0x0a, 0x21, 7, 8, 14,
+       0x0b, 0x23, 7, 8, 14,
 };
 
-UCHAR RateSwitchTable11N2S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,      // Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x20, 12,  15, 30,
-    0x06, 0x20, 13,  8, 20,
-    0x07, 0x20, 14,  8, 20,
-    0x08, 0x20, 15,  8, 25,
-    0x09, 0x22, 15,  8, 25,
+u8 RateSwitchTable11N2S[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0e, 0x0c, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x00, 0, 40, 101,
+       0x01, 0x00, 1, 40, 50,
+       0x02, 0x00, 2, 25, 45,
+       0x03, 0x21, 0, 20, 35,
+       0x04, 0x21, 1, 20, 35,
+       0x05, 0x21, 2, 20, 35,
+       0x06, 0x21, 3, 15, 35,
+       0x07, 0x21, 4, 15, 30,
+       0x08, 0x20, 11, 15, 30,
+       0x09, 0x20, 12, 15, 30,
+       0x0a, 0x20, 13, 8, 20,
+       0x0b, 0x20, 14, 8, 20,
+       0x0c, 0x20, 15, 8, 25,
+       0x0d, 0x22, 15, 8, 15,
 };
 
-UCHAR RateSwitchTable11N3S[] = {
-// Item No.    Mode    Curr-MCS        TrainUp TrainDown       // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,      // Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x20, 12,  15, 30,
-    0x06, 0x20, 13,  8, 20,
-    0x07, 0x20, 14,  8, 20,
-    0x08, 0x20, 15,  8, 25,
-    0x09, 0x22, 15,  8, 25,
+u8 RateSwitchTable11N3S[] = {
+/* Item No.     Mode    Curr-MCS        TrainUp TrainDown       // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0b, 0x00, 0, 0, 0,    /* 0x0a, 0x00,  0,  0,  0,      // Initial used item after association */
+       0x00, 0x21, 0, 30, 101,
+       0x01, 0x21, 1, 20, 50,
+       0x02, 0x21, 2, 20, 50,
+       0x03, 0x21, 3, 15, 50,
+       0x04, 0x21, 4, 15, 30,
+       0x05, 0x20, 11, 15, 30, /* Required by System-Alan @ 20080812 */
+       0x06, 0x20, 12, 15, 30, /* 0x05, 0x20, 12, 15, 30, */
+       0x07, 0x20, 13, 8, 20,  /* 0x06, 0x20, 13,  8, 20, */
+       0x08, 0x20, 14, 8, 20,  /* 0x07, 0x20, 14,  8, 20, */
+       0x09, 0x20, 15, 8, 25,  /* 0x08, 0x20, 15,  8, 25, */
+       0x0a, 0x22, 15, 8, 25,  /* 0x09, 0x22, 15,  8, 25, */
 };
 
-UCHAR RateSwitchTable11N2SForABand[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x09,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x20, 12,  15, 30,
-    0x07, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,
+u8 RateSwitchTable11N2SForABand[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0b, 0x09, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x21, 0, 30, 101,
+       0x01, 0x21, 1, 20, 50,
+       0x02, 0x21, 2, 20, 50,
+       0x03, 0x21, 3, 15, 50,
+       0x04, 0x21, 4, 15, 30,
+       0x05, 0x21, 5, 15, 30,
+       0x06, 0x20, 12, 15, 30,
+       0x07, 0x20, 13, 8, 20,
+       0x08, 0x20, 14, 8, 20,
+       0x09, 0x20, 15, 8, 25,
+       0x0a, 0x22, 15, 8, 25,
 };
 
-UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x09,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x21,  0, 30, 101,
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x20, 12,  15, 30,
-    0x07, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,
+u8 RateSwitchTable11N3SForABand[] = {  /* 3*3 */
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0b, 0x09, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x21, 0, 30, 101,
+       0x01, 0x21, 1, 20, 50,
+       0x02, 0x21, 2, 20, 50,
+       0x03, 0x21, 3, 15, 50,
+       0x04, 0x21, 4, 15, 30,
+       0x05, 0x21, 5, 15, 30,
+       0x06, 0x20, 12, 15, 30,
+       0x07, 0x20, 13, 8, 20,
+       0x08, 0x20, 14, 8, 20,
+       0x09, 0x20, 15, 8, 25,
+       0x0a, 0x22, 15, 8, 25,
 };
 
-UCHAR RateSwitchTable11BGN1S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0d, 0x00,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x00,  0, 40, 101,
-    0x01, 0x00,  1, 40, 50,
-    0x02, 0x00,  2, 35, 45,
-    0x03, 0x00,  3, 20, 45,
-    0x04, 0x21,  0, 30,101,    //50
-    0x05, 0x21,  1, 20, 50,
-    0x06, 0x21,  2, 20, 50,
-    0x07, 0x21,  3, 15, 50,
-    0x08, 0x21,  4, 15, 30,
-    0x09, 0x21,  5, 10, 25,
-    0x0a, 0x21,  6,  8, 14,
-    0x0b, 0x21,  7,  8, 14,
-       0x0c, 0x23,  7,  8, 14,
+u8 RateSwitchTable11BGN1S[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0c, 0x0a, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x00, 0, 40, 101,
+       0x01, 0x00, 1, 40, 50,
+       0x02, 0x00, 2, 25, 45,
+       0x03, 0x21, 0, 20, 35,
+       0x04, 0x21, 1, 20, 35,
+       0x05, 0x21, 2, 20, 35,
+       0x06, 0x21, 3, 15, 35,
+       0x07, 0x21, 4, 15, 30,
+       0x08, 0x21, 5, 10, 25,
+       0x09, 0x21, 6, 8, 14,
+       0x0a, 0x21, 7, 8, 14,
+       0x0b, 0x23, 7, 8, 14,
 };
 
-UCHAR RateSwitchTable11BGN2S[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x21,  0, 30,101,    //50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x20, 12, 15, 30,
-    0x06, 0x20, 13,  8, 20,
-    0x07, 0x20, 14,  8, 20,
-    0x08, 0x20, 15,  8, 25,
-    0x09, 0x22, 15,  8, 25,
+u8 RateSwitchTable11BGN2S[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0e, 0x0c, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x00, 0, 40, 101,
+       0x01, 0x00, 1, 40, 50,
+       0x02, 0x00, 2, 25, 45,
+       0x03, 0x21, 0, 20, 35,
+       0x04, 0x21, 1, 20, 35,
+       0x05, 0x21, 2, 20, 35,
+       0x06, 0x21, 3, 15, 35,
+       0x07, 0x21, 4, 15, 30,
+       0x08, 0x20, 11, 15, 30,
+       0x09, 0x20, 12, 15, 30,
+       0x0a, 0x20, 13, 8, 20,
+       0x0b, 0x20, 14, 8, 20,
+       0x0c, 0x20, 15, 8, 25,
+       0x0d, 0x22, 15, 8, 15,
 };
 
-UCHAR RateSwitchTable11BGN3S[] = { // 3*3
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0a, 0x00,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x21,  0, 30,101,    //50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 20, 50,
-    0x04, 0x21,  4, 15, 50,
-    0x05, 0x20, 20, 15, 30,
-    0x06, 0x20, 21,  8, 20,
-    0x07, 0x20, 22,  8, 20,
-    0x08, 0x20, 23,  8, 25,
-    0x09, 0x22, 23,  8, 25,
+u8 RateSwitchTable11BGN3S[] = {        /* 3*3 */
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0a, 0x00, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x21, 0, 30, 101, /*50 */
+       0x01, 0x21, 1, 20, 50,
+       0x02, 0x21, 2, 20, 50,
+       0x03, 0x21, 3, 20, 50,
+       0x04, 0x21, 4, 15, 50,
+       0x05, 0x20, 20, 15, 30,
+       0x06, 0x20, 21, 8, 20,
+       0x07, 0x20, 22, 8, 20,
+       0x08, 0x20, 23, 8, 25,
+       0x09, 0x22, 23, 8, 25,
 };
 
-UCHAR RateSwitchTable11BGN2SForABand[] = {
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0b, 0x09,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x21,  0, 30,101,    //50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x20, 12, 15, 30,
-    0x07, 0x20, 13,  8, 20,
-    0x08, 0x20, 14,  8, 20,
-    0x09, 0x20, 15,  8, 25,
-    0x0a, 0x22, 15,  8, 25,
+u8 RateSwitchTable11BGN2SForABand[] = {
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0b, 0x09, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x21, 0, 30, 101, /*50 */
+       0x01, 0x21, 1, 20, 50,
+       0x02, 0x21, 2, 20, 50,
+       0x03, 0x21, 3, 15, 50,
+       0x04, 0x21, 4, 15, 30,
+       0x05, 0x21, 5, 15, 30,
+       0x06, 0x20, 12, 15, 30,
+       0x07, 0x20, 13, 8, 20,
+       0x08, 0x20, 14, 8, 20,
+       0x09, 0x20, 15, 8, 25,
+       0x0a, 0x22, 15, 8, 25,
 };
 
-UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
-// Item No.   Mode   Curr-MCS   TrainUp   TrainDown            // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
-    0x0c, 0x09,  0,  0,  0,                                            // Initial used item after association
-    0x00, 0x21,  0, 30,101,    //50
-    0x01, 0x21,  1, 20, 50,
-    0x02, 0x21,  2, 20, 50,
-    0x03, 0x21,  3, 15, 50,
-    0x04, 0x21,  4, 15, 30,
-    0x05, 0x21,  5, 15, 30,
-    0x06, 0x21, 12, 15, 30,
-    0x07, 0x20, 20, 15, 30,
-    0x08, 0x20, 21,  8, 20,
-    0x09, 0x20, 22,  8, 20,
-    0x0a, 0x20, 23,  8, 25,
-    0x0b, 0x22, 23,  8, 25,
+u8 RateSwitchTable11BGN3SForABand[] = {        /* 3*3 */
+/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
+       0x0c, 0x09, 0, 0, 0,    /* Initial used item after association */
+       0x00, 0x21, 0, 30, 101, /*50 */
+       0x01, 0x21, 1, 20, 50,
+       0x02, 0x21, 2, 20, 50,
+       0x03, 0x21, 3, 15, 50,
+       0x04, 0x21, 4, 15, 30,
+       0x05, 0x21, 5, 15, 30,
+       0x06, 0x21, 12, 15, 30,
+       0x07, 0x20, 20, 15, 30,
+       0x08, 0x20, 21, 8, 20,
+       0x09, 0x20, 22, 8, 20,
+       0x0a, 0x20, 23, 8, 25,
+       0x0b, 0x22, 23, 8, 25,
 };
 
-PUCHAR ReasonString[] = {
-       /* 0  */         "Reserved",
-       /* 1  */         "Unspecified Reason",
-       /* 2  */         "Previous Auth no longer valid",
-       /* 3  */         "STA is leaving / has left",
-       /* 4  */         "DIS-ASSOC due to inactivity",
-       /* 5  */         "AP unable to hanle all associations",
-       /* 6  */         "class 2 error",
-       /* 7  */         "class 3 error",
-       /* 8  */         "STA is leaving / has left",
-       /* 9  */         "require auth before assoc/re-assoc",
-       /* 10 */         "Reserved",
-       /* 11 */         "Reserved",
-       /* 12 */         "Reserved",
-       /* 13 */         "invalid IE",
-       /* 14 */         "MIC error",
-       /* 15 */         "4-way handshake timeout",
-       /* 16 */         "2-way (group key) handshake timeout",
-       /* 17 */         "4-way handshake IE diff among AssosReq/Rsp/Beacon",
-       /* 18 */
+extern u8 OfdmRateToRxwiMCS[];
+/* since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate. */
+/* otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate */
+unsigned long BasicRateMask[12] =
+    { 0xfffff001 /* 1-Mbps */ , 0xfffff003 /* 2 Mbps */ , 0xfffff007 /* 5.5 */ ,
+0xfffff00f /* 11 */ ,
+       0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ ,
+           0xfffff0ff /* 18 */ ,
+       0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ ,
+           0xffffffff /* 54 */
 };
 
-extern UCHAR    OfdmRateToRxwiMCS[];
-// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
-// otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
-ULONG BasicRateMask[12]                                = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
-                                                                         0xfffff01f /* 6 */     , 0xfffff03f /* 9 */     , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
-                                                                         0xfffff1ff /* 24 */    , 0xfffff3ff /* 36 */    , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
-
-UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1,  0x00, 0x00, 0x00, 0x00, 0x00};
-UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN]  = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-// e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
-//             this value, then it's quaranteed capable of operating in 36 mbps TX rate in
-//             clean environment.
-//                                                               TxRate: 1   2   5.5   11       6        9    12       18       24   36   48   54       72  100
-CHAR RssiSafeLevelForTxRate[] ={  -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
-
-UCHAR  RateIdToMbps[]   = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
-USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
-
-UCHAR  SsidIe   = IE_SSID;
-UCHAR  SupRateIe = IE_SUPP_RATES;
-UCHAR  ExtRateIe = IE_EXT_SUPP_RATES;
-UCHAR  HtCapIe = IE_HT_CAP;
-UCHAR  AddHtInfoIe = IE_ADD_HT;
-UCHAR  NewExtChanIe = IE_SECONDARY_CH_OFFSET;
-UCHAR  ErpIe    = IE_ERP;
-UCHAR  DsIe     = IE_DS_PARM;
-UCHAR  TimIe    = IE_TIM;
-UCHAR  WpaIe    = IE_WPA;
-UCHAR  Wpa2Ie   = IE_WPA2;
-UCHAR  IbssIe   = IE_IBSS_PARM;
-UCHAR  Ccx2Ie   = IE_CCX_V2;
-
-extern UCHAR   WPA_OUI[];
-
-UCHAR  SES_OUI[] = {0x00, 0x90, 0x4c};
-
-UCHAR  ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-
-// 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},
-
-               // 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
+u8 BROADCAST_ADDR[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+u8 ZERO_MAC_ADDR[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+/* e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than */
+/*              this value, then it's quaranteed capable of operating in 36 mbps TX rate in */
+/*              clean environment. */
+/*                                                                TxRate: 1   2   5.5   11       6        9    12       18       24   36   48   54       72  100 */
+char RssiSafeLevelForTxRate[] =
+    { -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
+
+u8 RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100 };
+u16 RateIdTo500Kbps[] =
+    { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200 };
+
+u8 SsidIe = IE_SSID;
+u8 SupRateIe = IE_SUPP_RATES;
+u8 ExtRateIe = IE_EXT_SUPP_RATES;
+u8 HtCapIe = IE_HT_CAP;
+u8 AddHtInfoIe = IE_ADD_HT;
+u8 NewExtChanIe = IE_SECONDARY_CH_OFFSET;
+u8 ErpIe = IE_ERP;
+u8 DsIe = IE_DS_PARM;
+u8 TimIe = IE_TIM;
+u8 WpaIe = IE_WPA;
+u8 Wpa2Ie = IE_WPA2;
+u8 IbssIe = IE_IBSS_PARM;
+
+extern u8 WPA_OUI[];
+
+u8 SES_OUI[] = { 0x00, 0x90, 0x4c };
+
+u8 ZeroSsid[32] =
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+           0x00, 0x00, 0x00, 0x00
 };
-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));
 
 /*
        ==========================================================================
@@ -460,17 +356,15 @@ UCHAR     NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
 
        ==========================================================================
 */
-NDIS_STATUS MlmeInit(
-       IN PRTMP_ADAPTER pAd)
+int MlmeInit(struct rt_rtmp_adapter *pAd)
 {
-       NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+       int Status = NDIS_STATUS_SUCCESS;
 
        DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
 
-       do
-       {
+       do {
                Status = MlmeQueueInit(&pAd->Mlme.Queue);
-               if(Status != NDIS_STATUS_SUCCESS)
+               if (Status != NDIS_STATUS_SUCCESS)
                        break;
 
                pAd->Mlme.bRunning = FALSE;
@@ -479,40 +373,65 @@ NDIS_STATUS MlmeInit(
                {
                        BssTableInit(&pAd->ScanTab);
 
-                       // init STA state machines
-                       AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
-                       AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
-                       AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
-                       SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
-                       WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
-                       AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
-
-                       // Since we are using switch/case to implement it, the init is different from the above
-                       // state machine init
+                       /* init STA state machines */
+                       AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine,
+                                             pAd->Mlme.AssocFunc);
+                       AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine,
+                                            pAd->Mlme.AuthFunc);
+                       AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine,
+                                               pAd->Mlme.AuthRspFunc);
+                       SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine,
+                                            pAd->Mlme.SyncFunc);
+
+                       /* Since we are using switch/case to implement it, the init is different from the above */
+                       /* state machine init */
                        MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
                }
 
-               ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
+               WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine,
+                                   pAd->Mlme.WpaFunc);
+
+               ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine,
+                                      pAd->Mlme.ActFunc);
 
-               // Init mlme periodic timer
-               RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
+               /* Init mlme periodic timer */
+               RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer,
+                             GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
 
-               // Set mlme periodic timer
+               /* Set mlme periodic timer */
                RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
 
-               // software-based RX Antenna diversity
-               RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
+               /* software-based RX Antenna diversity */
+               RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer,
+                             GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd,
+                             FALSE);
+
+               {
+#ifdef RTMP_PCI_SUPPORT
+                       if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
+                               /* only PCIe cards need these two timers */
+                               RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer,
+                                             GET_TIMER_FUNCTION
+                                             (PsPollWakeExec), pAd, FALSE);
+                               RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer,
+                                             GET_TIMER_FUNCTION(RadioOnExec),
+                                             pAd, FALSE);
+                       }
+#endif /* RTMP_PCI_SUPPORT // */
 
-#ifdef RT2860
-               {
-               if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-               {
-                   // only PCIe cards need these two timers
-                       RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE);
-                       RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
-               }
+                       RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer,
+                                     GET_TIMER_FUNCTION(LinkDownExec), pAd,
+                                     FALSE);
+
+#ifdef RTMP_MAC_USB
+                       RTMPInitTimer(pAd, &pAd->Mlme.AutoWakeupTimer,
+                                     GET_TIMER_FUNCTION
+                                     (RtmpUsbStaAsicForceWakeupTimeout), pAd,
+                                     FALSE);
+                       pAd->Mlme.AutoWakeupTimerRunning = FALSE;
+#endif /* RTMP_MAC_USB // */
                }
-#endif
+
        } while (FALSE);
 
        DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
@@ -534,93 +453,102 @@ NDIS_STATUS MlmeInit(
 
        ==========================================================================
  */
-VOID MlmeHandler(
-       IN PRTMP_ADAPTER pAd)
+void MlmeHandler(struct rt_rtmp_adapter *pAd)
 {
-       MLME_QUEUE_ELEM            *Elem = NULL;
+       struct rt_mlme_queue_elem *Elem = NULL;
 
-       // Only accept MLME and Frame from peer side, no other (control/data) frame should
-       // get into this state machine
+       /* Only accept MLME and Frame from peer side, no other (control/data) frame should */
+       /* get into this state machine */
 
        NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-       if(pAd->Mlme.bRunning)
-       {
+       if (pAd->Mlme.bRunning) {
                NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
                return;
-       }
-       else
-       {
+       } else {
                pAd->Mlme.bRunning = TRUE;
        }
        NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
 
-       while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
-       {
+       while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) {
                if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
-                       RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
-                       RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-               {
-                       DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
+                   RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
+                   RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n",
+                                 pAd->Mlme.Queue.Num));
                        break;
                }
-
-               //From message type, determine which state machine I should drive
-               if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
-               {
-#ifdef RT2870
-                       if (Elem->MsgType == MT2_RESET_CONF)
-                       {
-                               DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
+               /*From message type, determine which state machine I should drive */
+               if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
+#ifdef RTMP_MAC_USB
+                       if (Elem->MsgType == MT2_RESET_CONF) {
+                               DBGPRINT_RAW(RT_DEBUG_TRACE,
+                                            ("reset MLME state machine!\n"));
                                MlmeRestartStateMachine(pAd);
                                Elem->Occupied = FALSE;
                                Elem->MsgLen = 0;
                                continue;
                        }
-#endif // RT2870 //
-
-                       // if dequeue success
-                       switch (Elem->Machine)
-                       {
-                               // STA state machines
-                               case ASSOC_STATE_MACHINE:
-                                       StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
-                                       break;
-                               case AUTH_STATE_MACHINE:
-                                       StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
-                                       break;
-                               case AUTH_RSP_STATE_MACHINE:
-                                       StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
-                                       break;
-                               case SYNC_STATE_MACHINE:
-                                       StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
-                                       break;
-                               case MLME_CNTL_STATE_MACHINE:
-                                       MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
-                                       break;
-                               case WPA_PSK_STATE_MACHINE:
-                                       StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
-                                       break;
-                               case AIRONET_STATE_MACHINE:
-                                       StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
-                                       break;
-                               case ACTION_STATE_MACHINE:
-                                       StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
-                                       break;
-
+#endif /* RTMP_MAC_USB // */
+
+                       /* if dequeue success */
+                       switch (Elem->Machine) {
+                               /* STA state machines */
+                       case ASSOC_STATE_MACHINE:
+                               StateMachinePerformAction(pAd,
+                                                         &pAd->Mlme.
+                                                         AssocMachine, Elem);
+                               break;
+                       case AUTH_STATE_MACHINE:
+                               StateMachinePerformAction(pAd,
+                                                         &pAd->Mlme.
+                                                         AuthMachine, Elem);
+                               break;
+                       case AUTH_RSP_STATE_MACHINE:
+                               StateMachinePerformAction(pAd,
+                                                         &pAd->Mlme.
+                                                         AuthRspMachine, Elem);
+                               break;
+                       case SYNC_STATE_MACHINE:
+                               StateMachinePerformAction(pAd,
+                                                         &pAd->Mlme.
+                                                         SyncMachine, Elem);
+                               break;
+                       case MLME_CNTL_STATE_MACHINE:
+                               MlmeCntlMachinePerformAction(pAd,
+                                                            &pAd->Mlme.
+                                                            CntlMachine, Elem);
+                               break;
+                       case WPA_PSK_STATE_MACHINE:
+                               StateMachinePerformAction(pAd,
+                                                         &pAd->Mlme.
+                                                         WpaPskMachine, Elem);
+                               break;
 
+                       case ACTION_STATE_MACHINE:
+                               StateMachinePerformAction(pAd,
+                                                         &pAd->Mlme.ActMachine,
+                                                         Elem);
+                               break;
 
+                       case WPA_STATE_MACHINE:
+                               StateMachinePerformAction(pAd,
+                                                         &pAd->Mlme.WpaMachine,
+                                                         Elem);
+                               break;
 
-                               default:
-                                       DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
-                                       break;
-                       } // end of switch
+                       default:
+                               DBGPRINT(RT_DEBUG_TRACE,
+                                        ("ERROR: Illegal machine %ld in MlmeHandler()\n",
+                                         Elem->Machine));
+                               break;
+                       }       /* end of switch */
 
-                       // free MLME element
+                       /* free MLME element */
                        Elem->Occupied = FALSE;
                        Elem->MsgLen = 0;
 
-               }
-               else {
+               } else {
                        DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
                }
        }
@@ -643,73 +571,67 @@ VOID MlmeHandler(
 
        ==========================================================================
  */
-VOID MlmeHalt(
-       IN PRTMP_ADAPTER pAd)
+void MlmeHalt(struct rt_rtmp_adapter *pAd)
 {
-       BOOLEAN           Cancelled;
-#ifdef RT3070
-       UINT32          TxPinCfg = 0x00050F0F;
-#endif // RT3070 //
+       BOOLEAN Cancelled;
 
        DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
 
-       if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-       {
-               // disable BEACON generation and other BEACON related hardware timers
+       if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
+               /* disable BEACON generation and other BEACON related hardware timers */
                AsicDisableSync(pAd);
        }
 
        {
-               // Cancel pending timers
-               RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,               &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,             &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,    &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,                &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,              &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,                &Cancelled);
-#ifdef RT2860
-           if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-           {
-                   RTMPCancelTimer(&pAd->Mlme.PsPollTimer,             &Cancelled);
-                   RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,         &Cancelled);
+               /* Cancel pending timers */
+               RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+
+#ifdef RTMP_MAC_PCI
+               if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+                   && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
+                       RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
+                       RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
                }
-#endif
-       }
+#endif /* RTMP_MAC_PCI // */
+
+               RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled);
 
-       RTMPCancelTimer(&pAd->Mlme.PeriodicTimer,               &Cancelled);
-       RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer,              &Cancelled);
+#ifdef RTMP_MAC_USB
+               RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Cancelled);
+#endif /* RTMP_MAC_USB // */
+       }
 
+       RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+       RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
 
+       if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
+               struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
 
-       if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-       {
-               // Set LED
+               /* Set LED */
                RTMPSetLED(pAd, LED_HALT);
-        RTMPSetSignalLED(pAd, -100);   // Force signal strength Led to be turned off, firmware is not done it.
-#ifdef RT2870
-        {
-            LED_CFG_STRUC LedCfg;
-            RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
-            LedCfg.field.LedPolar = 0;
-            LedCfg.field.RLedMode = 0;
-            LedCfg.field.GLedMode = 0;
-            LedCfg.field.YLedMode = 0;
-            RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
-        }
-#endif // RT2870 //
-#ifdef RT3070
-               //
-               // Turn off LNA_PE
-               //
-               if (IS_RT3070(pAd) || IS_RT3071(pAd))
+               RTMPSetSignalLED(pAd, -100);    /* Force signal strength Led to be turned off, firmware is not done it. */
+#ifdef RTMP_MAC_USB
                {
-                       TxPinCfg &= 0xFFFFF0F0;
-                       RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
+                       LED_CFG_STRUC LedCfg;
+                       RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
+                       LedCfg.field.LedPolar = 0;
+                       LedCfg.field.RLedMode = 0;
+                       LedCfg.field.GLedMode = 0;
+                       LedCfg.field.YLedMode = 0;
+                       RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
                }
-#endif // RT3070 //
+#endif /* RTMP_MAC_USB // */
+
+               if (pChipOps->AsicHaltAction)
+                       pChipOps->AsicHaltAction(pAd);
        }
 
-       RTMPusecDelay(5000);    //  5 msec to gurantee Ant Diversity timer canceled
+       RTMPusecDelay(5000);    /*  5 msec to gurantee Ant Diversity timer canceled */
 
        MlmeQueueDestroy(&pAd->Mlme.Queue);
        NdisFreeSpinLock(&pAd->Mlme.TaskLock);
@@ -717,11 +639,11 @@ VOID MlmeHalt(
        DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
 }
 
-VOID MlmeResetRalinkCounters(
-       IN  PRTMP_ADAPTER   pAd)
+void MlmeResetRalinkCounters(struct rt_rtmp_adapter *pAd)
 {
-       pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
-       // clear all OneSecxxx counters.
+       pAd->RalinkCounters.LastOneSecRxOkDataCnt =
+           pAd->RalinkCounters.OneSecRxOkDataCnt;
+       /* clear all OneSecxxx counters. */
        pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
        pAd->RalinkCounters.OneSecFalseCCACnt = 0;
        pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
@@ -730,8 +652,10 @@ VOID MlmeResetRalinkCounters(
        pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
        pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
        pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
+       pAd->RalinkCounters.OneSecReceivedByteCount = 0;
+       pAd->RalinkCounters.OneSecTransmittedByteCount = 0;
 
-       // TODO: for debug only. to be removed
+       /* TODO: for debug only. to be removed */
        pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
        pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
        pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
@@ -748,9 +672,6 @@ VOID MlmeResetRalinkCounters(
        return;
 }
 
-unsigned long rx_AMSDU;
-unsigned long rx_Total;
-
 /*
        ==========================================================================
        Description:
@@ -767,229 +688,188 @@ unsigned long rx_Total;
 
        ==========================================================================
  */
-#define ADHOC_BEACON_LOST_TIME         (8*OS_HZ)  // 8 sec
-VOID MlmePeriodicExec(
-       IN PVOID SystemSpecific1,
-       IN PVOID FunctionContext,
-       IN PVOID SystemSpecific2,
-       IN PVOID SystemSpecific3)
+#define ADHOC_BEACON_LOST_TIME         (8*OS_HZ)       /* 8 sec */
+void MlmePeriodicExec(void *SystemSpecific1,
+                     void *FunctionContext,
+                     void *SystemSpecific2, void *SystemSpecific3)
 {
-       ULONG                   TxTotalCnt;
-       PRTMP_ADAPTER   pAd = (RTMP_ADAPTER *)FunctionContext;
-
-#ifdef RT2860
-       //Baron 2008/07/10
-       //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
-       //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
-       //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
-       if(pAd->StaCfg.WepStatus<2)
-       {
-               pAd->StaCfg.WpaSupplicantUP = 0;
-       }
-       else
-       {
-               pAd->StaCfg.WpaSupplicantUP = 1;
-       }
-
-       {
-           // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
-               // Move code to here, because following code will return when radio is off
-               if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) &&
-                       (pAd->StaCfg.bHardwareRadio == TRUE) &&
-                       (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
-                       (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-                       (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
-               {
-                       UINT32                          data = 0;
-
-                       // Read GPIO pin2 as Hardware controlled radio state
-                       RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
-                       if (data & 0x04)
-                       {
+       unsigned long TxTotalCnt;
+       struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+
+#ifdef RTMP_MAC_PCI
+       {
+               /* If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second. */
+               /* Move code to here, because following code will return when radio is off */
+               if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) ==
+                    0) && (pAd->StaCfg.bHardwareRadio == TRUE)
+                   && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+                   && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+                   /*&&(pAd->bPCIclkOff == FALSE) */
+                   ) {
+                       u32 data = 0;
+
+                       /* Read GPIO pin2 as Hardware controlled radio state */
+#ifndef RT3090
+                       RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
+#endif /* RT3090 // */
+/*KH(PCIE PS):Added based on Jane<-- */
+#ifdef RT3090
+/* Read GPIO pin2 as Hardware controlled radio state */
+/* We need to Read GPIO if HW said so no mater what advance power saving */
+                       if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
+                           &&
+                           (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
+                           && (pAd->StaCfg.PSControl.field.EnablePSinIdle ==
+                               TRUE)) {
+                               /* Want to make sure device goes to L0 state before reading register. */
+                               RTMPPCIeLinkCtrlValueRestore(pAd, 0);
+                               RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
+                               RTMPPCIeLinkCtrlSetting(pAd, 3);
+                       } else
+                               RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
+#endif /* RT3090 // */
+/*KH(PCIE PS):Added based on Jane--> */
+
+                       if (data & 0x04) {
                                pAd->StaCfg.bHwRadio = TRUE;
-                       }
-                       else
-                       {
+                       } else {
                                pAd->StaCfg.bHwRadio = FALSE;
                        }
-                       if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
-                       {
-                               pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
-                               if (pAd->StaCfg.bRadio == TRUE)
-                               {
+                       if (pAd->StaCfg.bRadio !=
+                           (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) {
+                               pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio
+                                                     && pAd->StaCfg.bSwRadio);
+                               if (pAd->StaCfg.bRadio == TRUE) {
                                        MlmeRadioOn(pAd);
-                                       // Update extra information
+                                       /* Update extra information */
                                        pAd->ExtraInfo = EXTRA_INFO_CLEAR;
-                               }
-                               else
-                               {
+                               } else {
                                        MlmeRadioOff(pAd);
-                                       // Update extra information
+                                       /* Update extra information */
                                        pAd->ExtraInfo = HW_RADIO_OFF;
                                }
                        }
                }
        }
-#endif /* RT2860 */
+#endif /* RTMP_MAC_PCI // */
 
-       // Do nothing if the driver is starting halt state.
-       // This might happen when timer already been fired before cancel timer with mlmehalt
+       /* 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_RADIO_OFF |
-                                                               fRTMP_ADAPTER_RADIO_MEASUREMENT |
-                                                               fRTMP_ADAPTER_RESET_IN_PROGRESS))))
+                                 fRTMP_ADAPTER_RADIO_OFF |
+                                 fRTMP_ADAPTER_RADIO_MEASUREMENT |
+                                 fRTMP_ADAPTER_RESET_IN_PROGRESS))))
                return;
 
-#ifdef RT2860
-       {
-               if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
-               {
-                       // If ReceiveByteCount doesn't change,  increase SameRxByteCount by 1.
-                       pAd->SameRxByteCount++;
-               }
-               else
-                       pAd->SameRxByteCount = 0;
-
-               // If after BBP, still not work...need to check to reset PBF&MAC.
-               if (pAd->SameRxByteCount == 702)
-               {
-                       pAd->SameRxByteCount = 0;
-                       AsicResetPBF(pAd);
-                       AsicResetMAC(pAd);
-               }
-
-               // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
-               if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600)))
-               {
-                       if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700))
-                       {
-                               DBGPRINT(RT_DEBUG_TRACE, ("--->  SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount));
-                               pAd->SameRxByteCount = 700;
-                               AsicResetBBP(pAd);
-                       }
-               }
-
-               // Update lastReceiveByteCount.
-               pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount;
-
-               if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd)))
-               {
-                       pAd->CheckDmaBusyCount = 0;
-                       AsicResetFromDMABusy(pAd);
-               }
-       }
-#endif /* RT2860 */
-       RT28XX_MLME_PRE_SANITY_CHECK(pAd);
+       RTMP_MLME_PRE_SANITY_CHECK(pAd);
 
        {
-               // Do nothing if monitor mode is on
+               /* Do nothing if monitor mode is on */
                if (MONITOR_ON(pAd))
                        return;
 
-               if (pAd->Mlme.PeriodicRound & 0x1)
-               {
-                       // This is the fix for wifi 11n extension channel overlapping test case.  for 2860D
+               if (pAd->Mlme.PeriodicRound & 0x1) {
+                       /* This is the fix for wifi 11n extension channel overlapping test case.  for 2860D */
                        if (((pAd->MACVersion & 0xffff) == 0x0101) &&
-                               (STA_TGN_WIFI_ON(pAd)) &&
-                               (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
-
-                               {
-                                       RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
-                                       pAd->CommonCfg.IOTestParm.bToggle = TRUE;
-                               }
-                               else if ((STA_TGN_WIFI_ON(pAd)) &&
-                                               ((pAd->MACVersion & 0xffff) == 0x0101))
-                               {
-                                       RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
-                                       pAd->CommonCfg.IOTestParm.bToggle = FALSE;
-                               }
+                           (STA_TGN_WIFI_ON(pAd)) &&
+                           (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
+                       {
+                               RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
+                               pAd->CommonCfg.IOTestParm.bToggle = TRUE;
+                       } else if ((STA_TGN_WIFI_ON(pAd)) &&
+                                  ((pAd->MACVersion & 0xffff) == 0x0101)) {
+                               RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
+                               pAd->CommonCfg.IOTestParm.bToggle = FALSE;
+                       }
                }
        }
 
        pAd->bUpdateBcnCntDone = FALSE;
 
-//     RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
-       pAd->Mlme.PeriodicRound ++;
+/*      RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3); */
+       pAd->Mlme.PeriodicRound++;
 
-#ifdef RT3070
-       // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
+#ifdef RTMP_MAC_USB
+       /* execute every 100ms, update the Tx FIFO Cnt for update Tx Rate. */
        NICUpdateFifoStaCounters(pAd);
-#endif // RT3070 //
-       // execute every 500ms
-       if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
+#endif /* RTMP_MAC_USB // */
+
+       /* execute every 500ms */
+       if ((pAd->Mlme.PeriodicRound % 5 == 0)
+           && RTMPAutoRateSwitchCheck(pAd)
+           /*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ )
        {
-               // perform dynamic tx rate switching based on past TX history
+               /* perform dynamic tx rate switching based on past TX history */
                {
-                       if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-                                       )
-                               && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
+                       if ((OPSTATUS_TEST_FLAG
+                            (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+                           )
+                           && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
                                MlmeDynamicTxRateSwitching(pAd);
                }
        }
+       /* Normal 1 second Mlme PeriodicExec. */
+       if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE == 0) {
+               pAd->Mlme.OneSecPeriodicRound++;
 
-       // Normal 1 second Mlme PeriodicExec.
-       if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
-       {
-                pAd->Mlme.OneSecPeriodicRound ++;
-
-               if (rx_Total)
-               {
-
-                       // reset counters
-                       rx_AMSDU = 0;
-                       rx_Total = 0;
-               }
+               /*ORIBATimerTimeout(pAd); */
 
-               // Media status changed, report to NDIS
-               if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
-               {
+               /* Media status changed, report to NDIS */
+               if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE)) {
                        RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
-                       if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-                       {
-                               pAd->IndicateMediaState = NdisMediaStateConnected;
+                       if (OPSTATUS_TEST_FLAG
+                           (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+                               pAd->IndicateMediaState =
+                                   NdisMediaStateConnected;
                                RTMP_IndicateMediaState(pAd);
 
-                       }
-                       else
-                       {
-                               pAd->IndicateMediaState = NdisMediaStateDisconnected;
+                       } else {
+                               pAd->IndicateMediaState =
+                                   NdisMediaStateDisconnected;
                                RTMP_IndicateMediaState(pAd);
                        }
                }
 
                NdisGetSystemUpTime(&pAd->Mlme.Now32);
 
-               // add the most up-to-date h/w raw counters into software variable, so that
-               // the dynamic tuning mechanism below are based on most up-to-date information
+               /* add the most up-to-date h/w raw counters into software variable, so that */
+               /* the dynamic tuning mechanism below are based on most up-to-date information */
                NICUpdateRawCounters(pAd);
 
-#ifdef RT2870
-               RT2870_WatchDog(pAd);
-#endif // RT2870 //
+#ifdef RTMP_MAC_USB
+               RTUSBWatchDog(pAd);
+#endif /* RTMP_MAC_USB // */
 
-               // Need statistics after read counter. So put after NICUpdateRawCounters
+               /* Need statistics after read counter. So put after NICUpdateRawCounters */
                ORIBATimerTimeout(pAd);
 
-               // The time period for checking antenna is according to traffic
-               if (pAd->Mlme.bEnableAutoAntennaCheck)
-               {
-                       TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-                                                        pAd->RalinkCounters.OneSecTxRetryOkCount +
-                                                        pAd->RalinkCounters.OneSecTxFailCount;
-
-                       // dynamic adjust antenna evaluation period according to the traffic
-                       if (TxTotalCnt > 50)
-                       {
-                               if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
-                               {
-                                       AsicEvaluateRxAnt(pAd);
-                               }
-                       }
-                       else
-                       {
-                               if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
-                               {
-                                       AsicEvaluateRxAnt(pAd);
+               /* if MGMT RING is full more than twice within 1 second, we consider there's */
+               /* a hardware problem stucking the TX path. In this case, try a hardware reset */
+               /* to recover the system */
+               /*      if (pAd->RalinkCounters.MgmtRingFullCount >= 2) */
+               /*              RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR); */
+               /*      else */
+               /*              pAd->RalinkCounters.MgmtRingFullCount = 0; */
+
+               /* The time period for checking antenna is according to traffic */
+               {
+                       if (pAd->Mlme.bEnableAutoAntennaCheck) {
+                               TxTotalCnt =
+                                   pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+                                   pAd->RalinkCounters.OneSecTxRetryOkCount +
+                                   pAd->RalinkCounters.OneSecTxFailCount;
+
+                               /* dynamic adjust antenna evaluation period according to the traffic */
+                               if (TxTotalCnt > 50) {
+                                       if (pAd->Mlme.OneSecPeriodicRound %
+                                           10 == 0) {
+                                               AsicEvaluateRxAnt(pAd);
+                                       }
+                               } else {
+                                       if (pAd->Mlme.OneSecPeriodicRound % 3 ==
+                                           0) {
+                                               AsicEvaluateRxAnt(pAd);
+                                       }
                                }
                        }
                }
@@ -999,305 +879,590 @@ VOID MlmePeriodicExec(
                MlmeResetRalinkCounters(pAd);
 
                {
-#ifdef RT2860
-                       if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
-#endif
+#ifdef RTMP_MAC_PCI
+                       if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
+                           && (pAd->bPCIclkOff == FALSE))
+#endif /* RTMP_MAC_PCI // */
                        {
-                               // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
-                               // and sending CTS-to-self over and over.
-                               // Software Patch Solution:
-                               // 1. Polling debug state register 0x10F4 every one second.
-                               // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
-                               // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
+                               /* When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock */
+                               /* and sending CTS-to-self over and over. */
+                               /* Software Patch Solution: */
+                               /* 1. Polling debug state register 0x10F4 every one second. */
+                               /* 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred. */
+                               /* 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again. */
 
-                               UINT32  MacReg = 0;
+                               u32 MacReg = 0;
 
                                RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
-                               if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
-                               {
+                               if (((MacReg & 0x20000000) && (MacReg & 0x80))
+                                   || ((MacReg & 0x20000000)
+                                       && (MacReg & 0x20))) {
                                        RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
                                        RTMPusecDelay(1);
                                        RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
 
-                                       DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
+                                       DBGPRINT(RT_DEBUG_WARN,
+                                                ("Warning, MAC specific condition occurs \n"));
                                }
                        }
                }
 
-               RT28XX_MLME_HANDLER(pAd);
+               RTMP_MLME_HANDLER(pAd);
        }
 
        pAd->bUpdateBcnCntDone = FALSE;
 }
 
-VOID STAMlmePeriodicExec(
-       PRTMP_ADAPTER pAd)
+/*
+       ==========================================================================
+       Validate SSID for connection try and rescan purpose
+       Valid SSID will have visible chars only.
+       The valid length is from 0 to 32.
+       IRQL = DISPATCH_LEVEL
+       ==========================================================================
+ */
+BOOLEAN MlmeValidateSSID(u8 *pSsid, u8 SsidLen)
 {
-#ifdef RT2860
-       ULONG                       TxTotalCnt;
-#endif
-#ifdef RT2870
-       ULONG   TxTotalCnt;
-       int     i;
-#endif
-
-    if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
-    {
-       // WPA MIC error should block association attempt for 60 seconds
-       if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
-               pAd->StaCfg.bBlockAssoc = FALSE;
-    }
-
-#ifdef RT2860
-       //Baron 2008/07/10
-       //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
-       //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
-       //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
-       if(pAd->StaCfg.WepStatus<2)
-       {
-               pAd->StaCfg.WpaSupplicantUP = 0;
-       }
-       else
-       {
-               pAd->StaCfg.WpaSupplicantUP = 1;
-       }
-#endif
+       int index;
 
-    if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
-       {
-               if (pAd->IndicateMediaState == NdisMediaStateConnected)
-               {
-                       RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
-               }
-               pAd->PreMediaState = pAd->IndicateMediaState;
-       }
+       if (SsidLen > MAX_LEN_OF_SSID)
+               return (FALSE);
 
-#ifdef RT2860
-       if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
-        (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
-               (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
-               (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
-               (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
-               (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-       {
-               RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
+       /* Check each character value */
+       for (index = 0; index < SsidLen; index++) {
+               if (pSsid[index] < 0x20)
+                       return (FALSE);
        }
-#endif
 
+       /* All checked */
+       return (TRUE);
+}
 
+void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd,
+                          struct rt_mac_table_entry *pEntry,
+                          u8 ** ppTable,
+                          u8 *pTableSize, u8 *pInitTxRateIdx)
+{
+       do {
+               /* decide the rate table for tuning */
+               if (pAd->CommonCfg.TxRateTableSize > 0) {
+                       *ppTable = RateSwitchTable;
+                       *pTableSize = RateSwitchTable[0];
+                       *pInitTxRateIdx = RateSwitchTable[1];
 
-       AsicStaBbpTuning(pAd);
+                       break;
+               }
 
-       TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-                                        pAd->RalinkCounters.OneSecTxRetryOkCount +
-                                        pAd->RalinkCounters.OneSecTxFailCount;
+               if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd)) {
+                       if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) {       /* 11N 1S Adhoc */
+                               *ppTable = RateSwitchTable11N1S;
+                               *pTableSize = RateSwitchTable11N1S[0];
+                               *pInitTxRateIdx = RateSwitchTable11N1S[1];
 
-       if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-       {
-               // update channel quality for Roaming and UI LinkQuality display
-               MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
-       }
+                       } else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) {  /* 11N 2S Adhoc */
+                               if (pAd->LatchRfRegs.Channel <= 14) {
+                                       *ppTable = RateSwitchTable11N2S;
+                                       *pTableSize = RateSwitchTable11N2S[0];
+                                       *pInitTxRateIdx =
+                                           RateSwitchTable11N2S[1];
+                               } else {
+                                       *ppTable = RateSwitchTable11N2SForABand;
+                                       *pTableSize =
+                                           RateSwitchTable11N2SForABand[0];
+                                       *pInitTxRateIdx =
+                                           RateSwitchTable11N2SForABand[1];
+                               }
 
-       // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
-       // Radio is currently in noisy environment
-       if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-               AsicAdjustTxPower(pAd);
+                       } else if ((pEntry->RateLen == 4)
+                                  && (pEntry->HTCapability.MCSSet[0] == 0)
+                                  && (pEntry->HTCapability.MCSSet[1] == 0)
+                           ) {
+                               *ppTable = RateSwitchTable11B;
+                               *pTableSize = RateSwitchTable11B[0];
+                               *pInitTxRateIdx = RateSwitchTable11B[1];
 
-       if (INFRA_ON(pAd))
-       {
-               // Is PSM bit consistent with user power management policy?
-               // This is the only place that will set PSM bit ON.
-               if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-               MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
+                       } else if (pAd->LatchRfRegs.Channel <= 14) {
+                               *ppTable = RateSwitchTable11BG;
+                               *pTableSize = RateSwitchTable11BG[0];
+                               *pInitTxRateIdx = RateSwitchTable11BG[1];
 
-               pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
+                       } else {
+                               *ppTable = RateSwitchTable11G;
+                               *pTableSize = RateSwitchTable11G[0];
+                               *pInitTxRateIdx = RateSwitchTable11G[1];
 
-               if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
-                       (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
-                       ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
-               {
-                       RTMPSetAGCInitValue(pAd, BW_20);
-                       DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
+                       }
+                       break;
                }
+               /*if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */
+               /*      ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */
+               if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) {     /* 11BGN 1S AP */
+                       *ppTable = RateSwitchTable11BGN1S;
+                       *pTableSize = RateSwitchTable11BGN1S[0];
+                       *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
 
-        {
-               if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
-               {
-                   // When APSD is enabled, the period changes as 20 sec
-                       if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
-                               RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-               }
-               else
-               {
-                   // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
-                       if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
-                {
-                    if (pAd->CommonCfg.bWmmCapable)
-                                       RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-                    else
-                                               RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
-                }
-               }
-        }
-
-               if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
-                       {
-                       DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
-                       pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
-                       pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
-
-                       // Lost AP, send disconnect & link down event
-                       LinkDown(pAd, FALSE);
-
-            {
-                union iwreq_data    wrqu;
-                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
-                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-            }
-
-                       MlmeAutoReconnectLastSSID(pAd);
-               }
-               else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
-               {
-                       pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
-                       DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
-                       MlmeAutoReconnectLastSSID(pAd);
+                       break;
                }
+               /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */
+               /*      (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */
+               if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) {       /* 11BGN 2S AP */
+                       if (pAd->LatchRfRegs.Channel <= 14) {
+                               *ppTable = RateSwitchTable11BGN2S;
+                               *pTableSize = RateSwitchTable11BGN2S[0];
+                               *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
 
-               // Add auto seamless roaming
-               if (pAd->StaCfg.bFastRoaming)
-               {
-                       SHORT   dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
-
-                       DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), (CHAR)dBmToRoam));
+                       } else {
+                               *ppTable = RateSwitchTable11BGN2SForABand;
+                               *pTableSize = RateSwitchTable11BGN2SForABand[0];
+                               *pInitTxRateIdx =
+                                   RateSwitchTable11BGN2SForABand[1];
 
-                       if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
-                       {
-                               MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
                        }
+                       break;
                }
-       }
-       else if (ADHOC_ON(pAd))
-       {
-#ifdef RT2860
-               // 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
-               // the "TX BEACON competition" for the entire past 1 sec.
-               // So that even when ASIC's BEACONgen engine been blocked
-               // by peer's BEACON due to slower system clock, this STA still can send out
-               // minimum BEACON to tell the peer I'm alive.
-               // drawback is that this BEACON won't be well aligned at TBTT boundary.
-               // EnqueueBeaconFrame(pAd);                       // software send BEACON
-
-               // if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
-               // restore outgoing BEACON to support B/G-mixed mode
-               if ((pAd->CommonCfg.Channel <= 14)                         &&
-                       (pAd->CommonCfg.MaxTxRate <= RATE_11)      &&
-                       (pAd->CommonCfg.MaxDesiredRate > RATE_11)  &&
-                       ((pAd->StaCfg.Last11bBeaconRxTime + 5*OS_HZ) < pAd->Mlme.Now32))
-               {
-                       DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11B peer left, update Tx rates\n"));
-                       NdisMoveMemory(pAd->StaActive.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-                       pAd->StaActive.SupRateLen = pAd->CommonCfg.SupRateLen;
-                       MlmeUpdateTxRates(pAd, FALSE, 0);
-                       MakeIbssBeacon(pAd);            // re-build BEACON frame
-                       AsicEnableIbssSync(pAd);        // copy to on-chip memory
-                       pAd->StaCfg.AdhocBOnlyJoined = FALSE;
-               }
+               /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */
+               if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) { /* 11N 1S AP */
+                       *ppTable = RateSwitchTable11N1S;
+                       *pTableSize = RateSwitchTable11N1S[0];
+                       *pInitTxRateIdx = RateSwitchTable11N1S[1];
 
-               if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-               {
-                       if ((pAd->StaCfg.AdhocBGJoined) &&
-                               ((pAd->StaCfg.Last11gBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
-                       {
-                               DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11G peer left\n"));
-                               pAd->StaCfg.AdhocBGJoined = FALSE;
+                       break;
+               }
+               /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */
+               if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) {   /* 11N 2S AP */
+                       if (pAd->LatchRfRegs.Channel <= 14) {
+                               *ppTable = RateSwitchTable11N2S;
+                               *pTableSize = RateSwitchTable11N2S[0];
+                               *pInitTxRateIdx = RateSwitchTable11N2S[1];
+                       } else {
+                               *ppTable = RateSwitchTable11N2SForABand;
+                               *pTableSize = RateSwitchTable11N2SForABand[0];
+                               *pInitTxRateIdx =
+                                   RateSwitchTable11N2SForABand[1];
                        }
 
-                       if ((pAd->StaCfg.Adhoc20NJoined) &&
-                               ((pAd->StaCfg.Last20NBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
-                       {
-                               DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 20MHz N peer left\n"));
-                               pAd->StaCfg.Adhoc20NJoined = FALSE;
-                       }
+                       break;
                }
-#endif /* RT2860 */
+               /*else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
+               if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode == PHY_11B)
+                   /*Iverson mark for Adhoc b mode,sta will use rate 54  Mbps when connect with sta b/g/n mode */
+                   /* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) */
+                   ) {         /* B only AP */
+                       *ppTable = RateSwitchTable11B;
+                       *pTableSize = RateSwitchTable11B[0];
+                       *pInitTxRateIdx = RateSwitchTable11B[1];
 
-               //radar detect
-               if ((pAd->CommonCfg.Channel > 14)
-                       && (pAd->CommonCfg.bIEEE80211H == 1)
-                       && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
-               {
-                       RadarDetectPeriodic(pAd);
+                       break;
                }
+               /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
+               if ((pEntry->RateLen > 8)
+                   && (pEntry->HTCapability.MCSSet[0] == 0)
+                   && (pEntry->HTCapability.MCSSet[1] == 0)
+                   ) {         /* B/G  mixed AP */
+                       *ppTable = RateSwitchTable11BG;
+                       *pTableSize = RateSwitchTable11BG[0];
+                       *pInitTxRateIdx = RateSwitchTable11BG[1];
 
-               // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
-               // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
-               // join later.
-               if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
-                       OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-               {
-                       MLME_START_REQ_STRUCT     StartReq;
-
-                       DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
-                       LinkDown(pAd, FALSE);
+                       break;
+               }
+               /*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
+               if ((pEntry->RateLen == 8)
+                   && (pEntry->HTCapability.MCSSet[0] == 0)
+                   && (pEntry->HTCapability.MCSSet[1] == 0)
+                   ) {         /* G only AP */
+                       *ppTable = RateSwitchTable11G;
+                       *pTableSize = RateSwitchTable11G[0];
+                       *pInitTxRateIdx = RateSwitchTable11G[1];
 
-                       StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-                       MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
-                       pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+                       break;
                }
 
-#ifdef RT2870
-               for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
                {
-                       MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
-
-                       if (pEntry->ValidAsCLI == FALSE)
-                               continue;
+                       /*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
+                       if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)) {   /* Legacy mode */
+                               if (pAd->CommonCfg.MaxTxRate <= RATE_11) {
+                                       *ppTable = RateSwitchTable11B;
+                                       *pTableSize = RateSwitchTable11B[0];
+                                       *pInitTxRateIdx = RateSwitchTable11B[1];
+                               } else if ((pAd->CommonCfg.MaxTxRate > RATE_11)
+                                          && (pAd->CommonCfg.MinTxRate >
+                                              RATE_11)) {
+                                       *ppTable = RateSwitchTable11G;
+                                       *pTableSize = RateSwitchTable11G[0];
+                                       *pInitTxRateIdx = RateSwitchTable11G[1];
 
-                       if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
-                               MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
-               }
-#endif
+                               } else {
+                                       *ppTable = RateSwitchTable11BG;
+                                       *pTableSize = RateSwitchTable11BG[0];
+                                       *pInitTxRateIdx =
+                                           RateSwitchTable11BG[1];
+                               }
+                               break;
+                       }
+                       if (pAd->LatchRfRegs.Channel <= 14) {
+                               if (pAd->CommonCfg.TxStream == 1) {
+                                       *ppTable = RateSwitchTable11N1S;
+                                       *pTableSize = RateSwitchTable11N1S[0];
+                                       *pInitTxRateIdx =
+                                           RateSwitchTable11N1S[1];
+                                       DBGPRINT_RAW(RT_DEBUG_ERROR,
+                                                    ("DRS: unkown mode,default use 11N 1S AP \n"));
+                               } else {
+                                       *ppTable = RateSwitchTable11N2S;
+                                       *pTableSize = RateSwitchTable11N2S[0];
+                                       *pInitTxRateIdx =
+                                           RateSwitchTable11N2S[1];
+                                       DBGPRINT_RAW(RT_DEBUG_ERROR,
+                                                    ("DRS: unkown mode,default use 11N 2S AP \n"));
+                               }
+                       } else {
+                               if (pAd->CommonCfg.TxStream == 1) {
+                                       *ppTable = RateSwitchTable11N1S;
+                                       *pTableSize = RateSwitchTable11N1S[0];
+                                       *pInitTxRateIdx =
+                                           RateSwitchTable11N1S[1];
+                                       DBGPRINT_RAW(RT_DEBUG_ERROR,
+                                                    ("DRS: unkown mode,default use 11N 1S AP \n"));
+                               } else {
+                                       *ppTable = RateSwitchTable11N2SForABand;
+                                       *pTableSize =
+                                           RateSwitchTable11N2SForABand[0];
+                                       *pInitTxRateIdx =
+                                           RateSwitchTable11N2SForABand[1];
+                                       DBGPRINT_RAW(RT_DEBUG_ERROR,
+                                                    ("DRS: unkown mode,default use 11N 2S AP \n"));
+                               }
+                       }
+                       DBGPRINT_RAW(RT_DEBUG_ERROR,
+                                    ("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
+                                     pAd->StaActive.SupRateLen,
+                                     pAd->StaActive.ExtRateLen,
+                                     pAd->StaActive.SupportedPhyInfo.MCSSet[0],
+                                     pAd->StaActive.SupportedPhyInfo.
+                                     MCSSet[1]));
+               }
+       } while (FALSE);
+}
+
+void STAMlmePeriodicExec(struct rt_rtmp_adapter *pAd)
+{
+       unsigned long TxTotalCnt;
+       int i;
+
+       /*
+          We return here in ATE mode, because the statistics
+          that ATE need are not collected via this routine.
+        */
+#if defined(RT305x)||defined(RT3070)
+       /* request by Gary, if Rssi0 > -42, BBP 82 need to be changed from 0x62 to 0x42, , bbp 67 need to be changed from 0x20 to 0x18 */
+       if (!pAd->CommonCfg.HighPowerPatchDisabled) {
+#ifdef RT3070
+               if ((IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
+#endif /* RT3070 // */
+               {
+                       if ((pAd->StaCfg.RssiSample.AvgRssi0 != 0)
+                           && (pAd->StaCfg.RssiSample.AvgRssi0 >
+                               (pAd->BbpRssiToDbmDelta - 35))) {
+                               RT30xxWriteRFRegister(pAd, RF_R27, 0x20);
+                       } else {
+                               RT30xxWriteRFRegister(pAd, RF_R27, 0x23);
+                       }
+               }
+       }
+#endif
+#ifdef PCIE_PS_SUPPORT
+/* don't perform idle-power-save mechanism within 3 min after driver initialization. */
+/* This can make rebooter test more robust */
+       if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
+               if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
+                   && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
+                   && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+                   && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
+                       if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
+                               if (pAd->StaCfg.PSControl.field.EnableNewPS ==
+                                   TRUE) {
+                                       DBGPRINT(RT_DEBUG_TRACE,
+                                                ("%s\n", __func__));
+                                       RT28xxPciAsicRadioOff(pAd,
+                                                             GUI_IDLE_POWER_SAVE,
+                                                             0);
+                               } else {
+                                       AsicSendCommandToMcu(pAd, 0x30,
+                                                            PowerSafeCID, 0xff,
+                                                            0x2);
+                                       /* Wait command success */
+                                       AsicCheckCommanOk(pAd, PowerSafeCID);
+                                       RTMP_SET_FLAG(pAd,
+                                                     fRTMP_ADAPTER_IDLE_RADIO_OFF);
+                                       DBGPRINT(RT_DEBUG_TRACE,
+                                                ("PSM - rt30xx Issue Sleep command)\n"));
+                               }
+                       } else if (pAd->Mlme.OneSecPeriodicRound > 180) {
+                               if (pAd->StaCfg.PSControl.field.EnableNewPS ==
+                                   TRUE) {
+                                       DBGPRINT(RT_DEBUG_TRACE,
+                                                ("%s\n", __func__));
+                                       RT28xxPciAsicRadioOff(pAd,
+                                                             GUI_IDLE_POWER_SAVE,
+                                                             0);
+                               } else {
+                                       AsicSendCommandToMcu(pAd, 0x30,
+                                                            PowerSafeCID, 0xff,
+                                                            0x02);
+                                       /* Wait command success */
+                                       AsicCheckCommanOk(pAd, PowerSafeCID);
+                                       RTMP_SET_FLAG(pAd,
+                                                     fRTMP_ADAPTER_IDLE_RADIO_OFF);
+                                       DBGPRINT(RT_DEBUG_TRACE,
+                                                ("PSM -  rt28xx Issue Sleep command)\n"));
+                               }
+                       }
+               } else {
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("STAMlmePeriodicExec MMCHK - CommonCfg.Ssid[%d]=%c%c%c%c... MlmeAux.Ssid[%d]=%c%c%c%c...\n",
+                                 pAd->CommonCfg.SsidLen,
+                                 pAd->CommonCfg.Ssid[0],
+                                 pAd->CommonCfg.Ssid[1],
+                                 pAd->CommonCfg.Ssid[2],
+                                 pAd->CommonCfg.Ssid[3], pAd->MlmeAux.SsidLen,
+                                 pAd->MlmeAux.Ssid[0], pAd->MlmeAux.Ssid[1],
+                                 pAd->MlmeAux.Ssid[2], pAd->MlmeAux.Ssid[3]));
+               }
+       }
+#endif /* PCIE_PS_SUPPORT // */
+
+       if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) {
+               /* WPA MIC error should block association attempt for 60 seconds */
+               if (pAd->StaCfg.bBlockAssoc &&
+                   RTMP_TIME_AFTER(pAd->Mlme.Now32,
+                                   pAd->StaCfg.LastMicErrorTime +
+                                   (60 * OS_HZ)))
+                       pAd->StaCfg.bBlockAssoc = FALSE;
+       }
+
+       if ((pAd->PreMediaState != pAd->IndicateMediaState)
+           && (pAd->CommonCfg.bWirelessEvent)) {
+               if (pAd->IndicateMediaState == NdisMediaStateConnected) {
+                       RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
+                                             pAd->MacTab.Content[BSSID_WCID].
+                                             Addr, BSS0, 0);
+               }
+               pAd->PreMediaState = pAd->IndicateMediaState;
        }
-       else // no INFRA nor ADHOC connection
+
+       if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd)) {
+       } else {
+               AsicStaBbpTuning(pAd);
+       }
+
+       TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+           pAd->RalinkCounters.OneSecTxRetryOkCount +
+           pAd->RalinkCounters.OneSecTxFailCount;
+
+       if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+               /* update channel quality for Roaming and UI LinkQuality display */
+               MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32);
+       }
+       /* must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if */
+       /* Radio is currently in noisy environment */
+       if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+               AsicAdjustTxPower(pAd);
+
+       if (INFRA_ON(pAd)) {
+
+               /* Is PSM bit consistent with user power management policy? */
+               /* This is the only place that will set PSM bit ON. */
+               if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+                       MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
+
+               pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
+
+               if ((RTMP_TIME_AFTER
+                    (pAd->Mlme.Now32,
+                     pAd->StaCfg.LastBeaconRxTime + (1 * OS_HZ)))
+                   &&
+                   (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+                   &&
+                   (((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) <
+                     600))) {
+                       RTMPSetAGCInitValue(pAd, BW_20);
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n",
+                                 (0x2E + GET_LNA_GAIN(pAd))));
+               }
+               /*if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && */
+               /*    (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)) */
+               {
+                       if (pAd->CommonCfg.bAPSDCapable
+                           && pAd->CommonCfg.APEdcaParm.bAPSDCapable) {
+                               /* When APSD is enabled, the period changes as 20 sec */
+                               if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
+                                       RTMPSendNullFrame(pAd,
+                                                         pAd->CommonCfg.TxRate,
+                                                         TRUE);
+                       } else {
+                               /* Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out) */
+                               if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8) {
+                                       if (pAd->CommonCfg.bWmmCapable)
+                                               RTMPSendNullFrame(pAd,
+                                                                 pAd->
+                                                                 CommonCfg.
+                                                                 TxRate, TRUE);
+                                       else
+                                               RTMPSendNullFrame(pAd,
+                                                                 pAd->
+                                                                 CommonCfg.
+                                                                 TxRate,
+                                                                 FALSE);
+                               }
+                       }
+               }
+
+               if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality)) {
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n",
+                                 pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+
+                       /* Lost AP, send disconnect & link down event */
+                       LinkDown(pAd, FALSE);
+
+                       RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL,
+                                               0);
+
+                       /* RTMPPatchMacBbpBug(pAd); */
+                       MlmeAutoReconnectLastSSID(pAd);
+               } else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality)) {
+                       pAd->RalinkCounters.BadCQIAutoRecoveryCount++;
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n",
+                                 pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+                       MlmeAutoReconnectLastSSID(pAd);
+               }
+
+               if (pAd->StaCfg.bAutoRoaming) {
+                       BOOLEAN rv = FALSE;
+                       char dBmToRoam = pAd->StaCfg.dBmToRoam;
+                       char MaxRssi = RTMPMaxRssi(pAd,
+                                                  pAd->StaCfg.RssiSample.
+                                                  LastRssi0,
+                                                  pAd->StaCfg.RssiSample.
+                                                  LastRssi1,
+                                                  pAd->StaCfg.RssiSample.
+                                                  LastRssi2);
+
+                       /* Scanning, ignore Roaming */
+                       if (!RTMP_TEST_FLAG
+                           (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)
+                           && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
+                           && (MaxRssi <= dBmToRoam)) {
+                               DBGPRINT(RT_DEBUG_TRACE,
+                                        ("Rssi=%d, dBmToRoam=%d\n", MaxRssi,
+                                         (char)dBmToRoam));
+
+                               /* Add auto seamless roaming */
+                               if (rv == FALSE)
+                                       rv = MlmeCheckForFastRoaming(pAd);
+
+                               if (rv == FALSE) {
+                                       if ((pAd->StaCfg.LastScanTime +
+                                            10 * OS_HZ) < pAd->Mlme.Now32) {
+                                               DBGPRINT(RT_DEBUG_TRACE,
+                                                        ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
+                                               pAd->StaCfg.ScanCnt = 2;
+                                               pAd->StaCfg.LastScanTime =
+                                                   pAd->Mlme.Now32;
+                                               MlmeAutoScan(pAd);
+                                       }
+                               }
+                       }
+               }
+       } else if (ADHOC_ON(pAd)) {
+               /* If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState */
+               /* to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can */
+               /* join later. */
+               if (RTMP_TIME_AFTER
+                   (pAd->Mlme.Now32,
+                    pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME)
+                   && OPSTATUS_TEST_FLAG(pAd,
+                                         fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+                       struct rt_mlme_start_req StartReq;
+
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
+                       LinkDown(pAd, FALSE);
+
+                       StartParmFill(pAd, &StartReq,
+                                     (char *) pAd->MlmeAux.Ssid,
+                                     pAd->MlmeAux.SsidLen);
+                       MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
+                                   sizeof(struct rt_mlme_start_req), &StartReq);
+                       pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+               }
+
+               for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
+                       struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[i];
+
+                       if (pEntry->ValidAsCLI == FALSE)
+                               continue;
+
+                       if (RTMP_TIME_AFTER
+                           (pAd->Mlme.Now32,
+                            pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME))
+                               MacTableDeleteEntry(pAd, pEntry->Aid,
+                                                   pEntry->Addr);
+               }
+       } else                  /* no INFRA nor ADHOC connection */
        {
 
                if (pAd->StaCfg.bScanReqIsFromWebUI &&
-            ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
+                   RTMP_TIME_BEFORE(pAd->Mlme.Now32,
+                                    pAd->StaCfg.LastScanTime + (30 * OS_HZ)))
                        goto SKIP_AUTO_SCAN_CONN;
-        else
-            pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
+               else
+                       pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
 
                if ((pAd->StaCfg.bAutoReconnect == TRUE)
-                       && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
-                       && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
-               {
-                       if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
-                       {
-                               MLME_SCAN_REQ_STRUCT       ScanReq;
-
-                               if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
-                               {
-                                       DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
-                                       ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_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 Missed scan number
-                                       pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
-                               }
-                               else if (pAd->StaCfg.BssType == BSS_ADHOC)      // Quit the forever scan when in a very clean room
+                   && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
+                   &&
+                   (MlmeValidateSSID
+                    (pAd->MlmeAux.AutoReconnectSsid,
+                     pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) {
+                       if ((pAd->ScanTab.BssNr == 0)
+                           && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)) {
+                               struct rt_mlme_scan_req ScanReq;
+
+                               if (RTMP_TIME_AFTER
+                                   (pAd->Mlme.Now32,
+                                    pAd->StaCfg.LastScanTime + (10 * OS_HZ))) {
+                                       DBGPRINT(RT_DEBUG_TRACE,
+                                                ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n",
+                                                 pAd->MlmeAux.
+                                                 AutoReconnectSsid));
+                                       ScanParmFill(pAd, &ScanReq,
+                                                    (char *)pAd->MlmeAux.
+                                                    AutoReconnectSsid,
+                                                    pAd->MlmeAux.
+                                                    AutoReconnectSsidLen,
+                                                    BSS_ANY, SCAN_ACTIVE);
+                                       MlmeEnqueue(pAd, SYNC_STATE_MACHINE,
+                                                   MT2_MLME_SCAN_REQ,
+                                                   sizeof
+                                                   (struct rt_mlme_scan_req),
+                                                   &ScanReq);
+                                       pAd->Mlme.CntlMachine.CurrState =
+                                           CNTL_WAIT_OID_LIST_SCAN;
+                                       /* Reset Missed scan number */
+                                       pAd->StaCfg.LastScanTime =
+                                           pAd->Mlme.Now32;
+                               } else if (pAd->StaCfg.BssType == BSS_ADHOC)    /* Quit the forever scan when in a very clean room */
                                        MlmeAutoReconnectLastSSID(pAd);
-                       }
-                       else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-                       {
-                               if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
-                               {
+                       } else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
+                               if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0) {
                                        MlmeAutoScan(pAd);
-                                       pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
-                               }
-                               else
-                               {
-                                               MlmeAutoReconnectLastSSID(pAd);
+                                       pAd->StaCfg.LastScanTime =
+                                           pAd->Mlme.Now32;
+                               } else {
+                                       MlmeAutoReconnectLastSSID(pAd);
                                }
                        }
                }
@@ -1305,6346 +1470,3763 @@ VOID STAMlmePeriodicExec(
 
 SKIP_AUTO_SCAN_CONN:
 
-    if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
-       {
+       if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap != 0)
+           && (pAd->MacTab.fAnyBASession == FALSE)) {
                pAd->MacTab.fAnyBASession = TRUE;
-               AsicUpdateProtect(pAd, HT_FORCERTSCTS,  ALLN_SETPROTECT, FALSE, FALSE);
-       }
-       else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
-       {
+               AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE,
+                                 FALSE);
+       } else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap == 0)
+                  && (pAd->MacTab.fAnyBASession == TRUE)) {
                pAd->MacTab.fAnyBASession = FALSE;
-               AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
+               AsicUpdateProtect(pAd,
+                                 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
+                                 OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
        }
 
        return;
 }
 
-// Link down report
-VOID LinkDownExec(
-       IN PVOID SystemSpecific1,
-       IN PVOID FunctionContext,
-       IN PVOID SystemSpecific2,
-       IN PVOID SystemSpecific3)
+/* Link down report */
+void LinkDownExec(void *SystemSpecific1,
+                 void *FunctionContext,
+                 void *SystemSpecific2, void *SystemSpecific3)
 {
+       struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
-       RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+       if (pAd != NULL) {
+               struct rt_mlme_disassoc_req DisassocReq;
 
-       pAd->IndicateMediaState = NdisMediaStateDisconnected;
-       RTMP_IndicateMediaState(pAd);
-    pAd->ExtraInfo = GENERAL_LINK_DOWN;
+               if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) &&
+                   (INFRA_ON(pAd))) {
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("LinkDownExec(): disassociate with current AP...\n"));
+                       DisassocParmFill(pAd, &DisassocReq,
+                                        pAd->CommonCfg.Bssid,
+                                        REASON_DISASSOC_STA_LEAVING);
+                       MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
+                                   MT2_MLME_DISASSOC_REQ,
+                                   sizeof(struct rt_mlme_disassoc_req),
+                                   &DisassocReq);
+                       pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+
+                       pAd->IndicateMediaState = NdisMediaStateDisconnected;
+                       RTMP_IndicateMediaState(pAd);
+                       pAd->ExtraInfo = GENERAL_LINK_DOWN;
+               }
+       }
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID MlmeAutoScan(
-       IN PRTMP_ADAPTER pAd)
+/* IRQL = DISPATCH_LEVEL */
+void MlmeAutoScan(struct rt_rtmp_adapter *pAd)
 {
-       // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-       if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-       {
+       /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
+       if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
                DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
                MlmeEnqueue(pAd,
-                                       MLME_CNTL_STATE_MACHINE,
-                                       OID_802_11_BSSID_LIST_SCAN,
-                                       0,
-                                       NULL);
-               RT28XX_MLME_HANDLER(pAd);
+                           MLME_CNTL_STATE_MACHINE,
+                           OID_802_11_BSSID_LIST_SCAN,
+                           pAd->MlmeAux.AutoReconnectSsidLen,
+                           pAd->MlmeAux.AutoReconnectSsid);
+               RTMP_MLME_HANDLER(pAd);
        }
 }
 
-// IRQL = DISPATCH_LEVEL
-VOID MlmeAutoReconnectLastSSID(
-       IN PRTMP_ADAPTER pAd)
+/* IRQL = DISPATCH_LEVEL */
+void MlmeAutoReconnectLastSSID(struct rt_rtmp_adapter *pAd)
 {
+       if (pAd->StaCfg.bAutoConnectByBssid) {
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("Driver auto reconnect to last OID_802_11_BSSID setting - %02X:%02X:%02X:%02X:%02X:%02X\n",
+                         pAd->MlmeAux.Bssid[0], pAd->MlmeAux.Bssid[1],
+                         pAd->MlmeAux.Bssid[2], pAd->MlmeAux.Bssid[3],
+                         pAd->MlmeAux.Bssid[4], pAd->MlmeAux.Bssid[5]));
+
+               pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
+               MlmeEnqueue(pAd,
+                           MLME_CNTL_STATE_MACHINE,
+                           OID_802_11_BSSID, MAC_ADDR_LEN, pAd->MlmeAux.Bssid);
 
+               pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
 
-       // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-       if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
-               (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
-       {
-               NDIS_802_11_SSID OidSsid;
+               RTMP_MLME_HANDLER(pAd);
+       }
+       /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
+       else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+                (MlmeValidateSSID
+                 (pAd->MlmeAux.AutoReconnectSsid,
+                  pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) {
+               struct rt_ndis_802_11_ssid OidSsid;
                OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
-               NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+               NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid,
+                              pAd->MlmeAux.AutoReconnectSsidLen);
 
-               DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
-               MlmeEnqueue(pAd,
-                                       MLME_CNTL_STATE_MACHINE,
-                                       OID_802_11_SSID,
-                                       sizeof(NDIS_802_11_SSID),
-                                       &OidSsid);
-               RT28XX_MLME_HANDLER(pAd);
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n",
+                         pAd->MlmeAux.AutoReconnectSsid,
+                         pAd->MlmeAux.AutoReconnectSsidLen));
+               MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID,
+                           sizeof(struct rt_ndis_802_11_ssid), &OidSsid);
+               RTMP_MLME_HANDLER(pAd);
        }
 }
 
 /*
        ==========================================================================
-       Validate SSID for connection try and rescan purpose
-       Valid SSID will have visible chars only.
-       The valid length is from 0 to 32.
+       Description:
+               This routine checks if there're other APs out there capable for
+               roaming. Caller should call this routine only when Link up in INFRA mode
+               and channel quality is below CQI_GOOD_THRESHOLD.
+
        IRQL = DISPATCH_LEVEL
+
+       Output:
        ==========================================================================
  */
-BOOLEAN MlmeValidateSSID(
-       IN PUCHAR       pSsid,
-       IN UCHAR        SsidLen)
+void MlmeCheckForRoaming(struct rt_rtmp_adapter *pAd, unsigned long Now32)
 {
-       int     index;
+       u16 i;
+       struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab;
+       struct rt_bss_entry *pBss;
 
-       if (SsidLen > MAX_LEN_OF_SSID)
-               return (FALSE);
+       DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
+       /* put all roaming candidates into RoamTab, and sort in RSSI order */
+       BssTableInit(pRoamTab);
+       for (i = 0; i < pAd->ScanTab.BssNr; i++) {
+               pBss = &pAd->ScanTab.BssEntry[i];
 
-       // Check each character value
-       for (index = 0; index < SsidLen; index++)
-       {
-               if (pSsid[index] < 0x20)
-                       return (FALSE);
+               if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) <
+                   Now32)
+                       continue;       /* AP disappear */
+               if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
+                       continue;       /* RSSI too weak. forget it. */
+               if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+                       continue;       /* skip current AP */
+               if (pBss->Rssi <
+                   (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
+                       continue;       /* only AP with stronger RSSI is eligible for roaming */
+
+               /* AP passing all above rules is put into roaming candidate table */
+               NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss,
+                              sizeof(struct rt_bss_entry));
+               pRoamTab->BssNr += 1;
        }
 
-       // All checked
-       return (TRUE);
+       if (pRoamTab->BssNr > 0) {
+               /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
+               if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
+                       pAd->RalinkCounters.PoorCQIRoamingCount++;
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("MMCHK - Roaming attempt #%ld\n",
+                                 pAd->RalinkCounters.PoorCQIRoamingCount));
+                       MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
+                                   MT2_MLME_ROAMING_REQ, 0, NULL);
+                       RTMP_MLME_HANDLER(pAd);
+               }
+       }
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("<== MlmeCheckForRoaming(# of candidate= %d)\n",
+                 pRoamTab->BssNr));
 }
 
-VOID MlmeSelectTxRateTable(
-       IN PRTMP_ADAPTER                pAd,
-       IN PMAC_TABLE_ENTRY             pEntry,
-       IN PUCHAR                               *ppTable,
-       IN PUCHAR                               pTableSize,
-       IN PUCHAR                               pInitTxRateIdx)
+/*
+       ==========================================================================
+       Description:
+               This routine checks if there're other APs out there capable for
+               roaming. Caller should call this routine only when link up in INFRA mode
+               and channel quality is below CQI_GOOD_THRESHOLD.
+
+       IRQL = DISPATCH_LEVEL
+
+       Output:
+       ==========================================================================
+ */
+BOOLEAN MlmeCheckForFastRoaming(struct rt_rtmp_adapter *pAd)
 {
-       do
-       {
-               // decide the rate table for tuning
-               if (pAd->CommonCfg.TxRateTableSize > 0)
-               {
-                       *ppTable = RateSwitchTable;
-                       *pTableSize = RateSwitchTable[0];
-                       *pInitTxRateIdx = RateSwitchTable[1];
+       u16 i;
+       struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab;
+       struct rt_bss_entry *pBss;
 
-                       break;
+       DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
+       /* put all roaming candidates into RoamTab, and sort in RSSI order */
+       BssTableInit(pRoamTab);
+       for (i = 0; i < pAd->ScanTab.BssNr; i++) {
+               pBss = &pAd->ScanTab.BssEntry[i];
+
+               if ((pBss->Rssi <= -50)
+                   && (pBss->Channel == pAd->CommonCfg.Channel))
+                       continue;       /* RSSI too weak. forget it. */
+               if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+                       continue;       /* skip current AP */
+               if (!SSID_EQUAL
+                   (pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid,
+                    pAd->CommonCfg.SsidLen))
+                       continue;       /* skip different SSID */
+               if (pBss->Rssi <
+                   (RTMPMaxRssi
+                    (pAd, pAd->StaCfg.RssiSample.LastRssi0,
+                     pAd->StaCfg.RssiSample.LastRssi1,
+                     pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
+                       continue;       /* skip AP without better RSSI */
+
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("LastRssi0 = %d, pBss->Rssi = %d\n",
+                         RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
+                                     pAd->StaCfg.RssiSample.LastRssi1,
+                                     pAd->StaCfg.RssiSample.LastRssi2),
+                         pBss->Rssi));
+               /* AP passing all above rules is put into roaming candidate table */
+               NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss,
+                              sizeof(struct rt_bss_entry));
+               pRoamTab->BssNr += 1;
+       }
+
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
+       if (pRoamTab->BssNr > 0) {
+               /* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
+               if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
+                       pAd->RalinkCounters.PoorCQIRoamingCount++;
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("MMCHK - Roaming attempt #%ld\n",
+                                 pAd->RalinkCounters.PoorCQIRoamingCount));
+                       MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
+                                   MT2_MLME_ROAMING_REQ, 0, NULL);
+                       RTMP_MLME_HANDLER(pAd);
+                       return TRUE;
                }
+       }
 
-               if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
-               {
-                       if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
-#ifdef RT2860
-                               !pAd->StaCfg.AdhocBOnlyJoined &&
-                               !pAd->StaCfg.AdhocBGJoined &&
-                               (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
-                               ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
-#endif
-#ifdef RT2870
-                               (pEntry->HTCapability.MCSSet[0] == 0xff) &&
-                               ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
-#endif
-                       {// 11N 1S Adhoc
-                               *ppTable = RateSwitchTable11N1S;
-                               *pTableSize = RateSwitchTable11N1S[0];
-                               *pInitTxRateIdx = RateSwitchTable11N1S[1];
+       return FALSE;
+}
 
-                       }
-                       else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
-#ifdef RT2860
-                                       !pAd->StaCfg.AdhocBOnlyJoined &&
-                                       !pAd->StaCfg.AdhocBGJoined &&
-                                       (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
-                                       (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) &&
-#endif
-#ifdef RT2870
-                                       (pEntry->HTCapability.MCSSet[0] == 0xff) &&
-                                       (pEntry->HTCapability.MCSSet[1] == 0xff) &&
-#endif
-                                       (pAd->Antenna.field.TxPath == 2))
-                       {// 11N 2S Adhoc
-                               if (pAd->LatchRfRegs.Channel <= 14)
-                               {
-                                       *ppTable = RateSwitchTable11N2S;
-                                       *pTableSize = RateSwitchTable11N2S[0];
-                                       *pInitTxRateIdx = RateSwitchTable11N2S[1];
-                               }
-                               else
-                               {
-                                       *ppTable = RateSwitchTable11N2SForABand;
-                                       *pTableSize = RateSwitchTable11N2SForABand[0];
-                                       *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
-                               }
+void MlmeSetTxRate(struct rt_rtmp_adapter *pAd,
+                  struct rt_mac_table_entry *pEntry, struct rt_rtmp_tx_rate_switch * pTxRate)
+{
+       u8 MaxMode = MODE_OFDM;
 
-                       }
-                       else
-#ifdef RT2860
-                               if (pAd->CommonCfg.PhyMode == PHY_11B)
-                       {
-                               *ppTable = RateSwitchTable11B;
-                               *pTableSize = RateSwitchTable11B[0];
-                               *pInitTxRateIdx = RateSwitchTable11B[1];
+       MaxMode = MODE_HTGREENFIELD;
 
-                       }
-               else if((pAd->LatchRfRegs.Channel <= 14) && (pAd->StaCfg.AdhocBOnlyJoined == TRUE))
-#endif
-#ifdef RT2870
-                               if ((pEntry->RateLen == 4)
-                                       && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
-                                       )
-#endif
-                       {
-                               // USe B Table when Only b-only Station in my IBSS .
-                               *ppTable = RateSwitchTable11B;
-                               *pTableSize = RateSwitchTable11B[0];
-                               *pInitTxRateIdx = RateSwitchTable11B[1];
+       if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC)
+           && (pAd->Antenna.field.TxPath == 2))
+               pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
+       else
+               pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
 
-                       }
-                       else if (pAd->LatchRfRegs.Channel <= 14)
-                       {
-                               *ppTable = RateSwitchTable11BG;
-                               *pTableSize = RateSwitchTable11BG[0];
-                               *pInitTxRateIdx = RateSwitchTable11BG[1];
+       if (pTxRate->CurrMCS < MCS_AUTO)
+               pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
 
-                       }
-                       else
-                       {
-                               *ppTable = RateSwitchTable11G;
-                               *pTableSize = RateSwitchTable11G[0];
-                               *pInitTxRateIdx = RateSwitchTable11G[1];
+       if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
+               pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
 
-                       }
-                       break;
-               }
+       if (ADHOC_ON(pAd)) {
+               /* If peer adhoc is b-only mode, we can't send 11g rate. */
+               pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+               pEntry->HTPhyMode.field.STBC = STBC_NONE;
 
-               if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
-                       ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
-               {// 11BGN 1S AP
-                       *ppTable = RateSwitchTable11BGN1S;
-                       *pTableSize = RateSwitchTable11BGN1S[0];
-                       *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
+               /* */
+               /* For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary */
+               /* */
+               pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
+               pEntry->HTPhyMode.field.ShortGI =
+                   pAd->StaCfg.HTPhyMode.field.ShortGI;
+               pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
 
-                       break;
-               }
+               /* Patch speed error in status page */
+               pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
+       } else {
+               if (pTxRate->Mode <= MaxMode)
+                       pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
 
-               if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
-                       (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
-               {// 11BGN 2S AP
-                       if (pAd->LatchRfRegs.Channel <= 14)
-                       {
-                               *ppTable = RateSwitchTable11BGN2S;
-                               *pTableSize = RateSwitchTable11BGN2S[0];
-                               *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
+               if (pTxRate->ShortGI
+                   && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
+                       pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
+               else
+                       pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
 
+               /* Reexam each bandwidth's SGI support. */
+               if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400) {
+                       if ((pEntry->HTPhyMode.field.BW == BW_20)
+                           &&
+                           (!CLIENT_STATUS_TEST_FLAG
+                            (pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
+                               pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+                       if ((pEntry->HTPhyMode.field.BW == BW_40)
+                           &&
+                           (!CLIENT_STATUS_TEST_FLAG
+                            (pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
+                               pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+               }
+               /* Turn RTS/CTS rate to 6Mbps. */
+               if ((pEntry->HTPhyMode.field.MCS == 0)
+                   && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) {
+                       pEntry->HTPhyMode.field.MCS =
+                           pAd->StaCfg.HTPhyMode.field.MCS;
+                       if (pAd->MacTab.fAnyBASession) {
+                               AsicUpdateProtect(pAd, HT_FORCERTSCTS,
+                                                 ALLN_SETPROTECT, TRUE,
+                                                 (BOOLEAN) pAd->MlmeAux.
+                                                 AddHtInfo.AddHtInfo2.
+                                                 NonGfPresent);
+                       } else {
+                               AsicUpdateProtect(pAd,
+                                                 pAd->MlmeAux.AddHtInfo.
+                                                 AddHtInfo2.OperaionMode,
+                                                 ALLN_SETPROTECT, TRUE,
+                                                 (BOOLEAN) pAd->MlmeAux.
+                                                 AddHtInfo.AddHtInfo2.
+                                                 NonGfPresent);
                        }
-                       else
-                       {
-                               *ppTable = RateSwitchTable11BGN2SForABand;
-                               *pTableSize = RateSwitchTable11BGN2SForABand[0];
-                               *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
-
+               } else if ((pEntry->HTPhyMode.field.MCS == 8)
+                          && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) {
+                       pEntry->HTPhyMode.field.MCS =
+                           pAd->StaCfg.HTPhyMode.field.MCS;
+                       if (pAd->MacTab.fAnyBASession) {
+                               AsicUpdateProtect(pAd, HT_FORCERTSCTS,
+                                                 ALLN_SETPROTECT, TRUE,
+                                                 (BOOLEAN) pAd->MlmeAux.
+                                                 AddHtInfo.AddHtInfo2.
+                                                 NonGfPresent);
+                       } else {
+                               AsicUpdateProtect(pAd,
+                                                 pAd->MlmeAux.AddHtInfo.
+                                                 AddHtInfo2.OperaionMode,
+                                                 ALLN_SETPROTECT, TRUE,
+                                                 (BOOLEAN) pAd->MlmeAux.
+                                                 AddHtInfo.AddHtInfo2.
+                                                 NonGfPresent);
                        }
-                       break;
-               }
-
-               if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
-               {// 11N 1S AP
-                       *ppTable = RateSwitchTable11N1S;
-                       *pTableSize = RateSwitchTable11N1S[0];
-                       *pInitTxRateIdx = RateSwitchTable11N1S[1];
+               } else if ((pEntry->HTPhyMode.field.MCS != 0)
+                          && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) {
+                       AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT,
+                                         TRUE,
+                                         (BOOLEAN) pAd->MlmeAux.AddHtInfo.
+                                         AddHtInfo2.NonGfPresent);
+
+               } else if ((pEntry->HTPhyMode.field.MCS != 8)
+                          && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) {
+                       AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT,
+                                         TRUE,
+                                         (BOOLEAN) pAd->MlmeAux.AddHtInfo.
+                                         AddHtInfo2.NonGfPresent);
+               }
+
+               pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
+               pEntry->HTPhyMode.field.ShortGI =
+                   pAd->StaCfg.HTPhyMode.field.ShortGI;
+               pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+               pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+               if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD)
+                   && pAd->WIFItestbed.bGreenField)
+                       pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
+       }
+
+       pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word);
+}
 
-                       break;
-               }
+/*
+       ==========================================================================
+       Description:
+               This routine calculates the acumulated TxPER of eaxh TxRate. And
+               according to the calculation result, change CommonCfg.TxRate which
+               is the stable TX Rate we expect the Radio situation could sustained.
 
-               if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
-               {// 11N 2S AP
-                       if (pAd->LatchRfRegs.Channel <= 14)
-                       {
-                       *ppTable = RateSwitchTable11N2S;
-                       *pTableSize = RateSwitchTable11N2S[0];
-                       *pInitTxRateIdx = RateSwitchTable11N2S[1];
-            }
-                       else
-                       {
-                               *ppTable = RateSwitchTable11N2SForABand;
-                               *pTableSize = RateSwitchTable11N2SForABand[0];
-                               *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
-                       }
+               CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
+       Output:
+               CommonCfg.TxRate -
 
-                       break;
-               }
+       IRQL = DISPATCH_LEVEL
 
-               //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-               if (pEntry->RateLen == 4)
-               {// B only AP
-                       *ppTable = RateSwitchTable11B;
-                       *pTableSize = RateSwitchTable11B[0];
-                       *pInitTxRateIdx = RateSwitchTable11B[1];
+       NOTE:
+               call this routine every second
+       ==========================================================================
+ */
+void MlmeDynamicTxRateSwitching(struct rt_rtmp_adapter *pAd)
+{
+       u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
+       unsigned long i, AccuTxTotalCnt = 0, TxTotalCnt;
+       unsigned long TxErrorRatio = 0;
+       BOOLEAN bTxRateChanged = FALSE, bUpgradeQuality = FALSE;
+       struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL;
+       u8 *pTable;
+       u8 TableSize = 0;
+       u8 InitTxRateIdx = 0, TrainUp, TrainDown;
+       char Rssi, RssiOffset = 0;
+       TX_STA_CNT1_STRUC StaTx1;
+       TX_STA_CNT0_STRUC TxStaCnt0;
+       unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+       struct rt_mac_table_entry *pEntry;
+       struct rt_rssi_sample *pRssi = &pAd->StaCfg.RssiSample;
+
+       /* */
+       /* walk through MAC table, see if need to change AP's TX rate toward each entry */
+       /* */
+       for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
+               pEntry = &pAd->MacTab.Content[i];
 
-                       break;
-               }
+               /* check if this entry need to switch rate automatically */
+               if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+                       continue;
 
-               //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-               if ((pEntry->RateLen > 8)
-                       && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
-                       )
-               {// B/G  mixed AP
-                       *ppTable = RateSwitchTable11BG;
-                       *pTableSize = RateSwitchTable11BG[0];
-                       *pInitTxRateIdx = RateSwitchTable11BG[1];
+               if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls)) {
+                       Rssi = RTMPMaxRssi(pAd,
+                                          pRssi->AvgRssi0,
+                                          pRssi->AvgRssi1, pRssi->AvgRssi2);
 
-                       break;
+                       /* Update statistic counter */
+                       RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+                       RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+                       pAd->bUpdateBcnCntDone = TRUE;
+                       TxRetransmit = StaTx1.field.TxRetransmit;
+                       TxSuccess = StaTx1.field.TxSuccess;
+                       TxFailCount = TxStaCnt0.field.TxFailCount;
+                       TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+                       pAd->RalinkCounters.OneSecTxRetryOkCount +=
+                           StaTx1.field.TxRetransmit;
+                       pAd->RalinkCounters.OneSecTxNoRetryOkCount +=
+                           StaTx1.field.TxSuccess;
+                       pAd->RalinkCounters.OneSecTxFailCount +=
+                           TxStaCnt0.field.TxFailCount;
+                       pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
+                           StaTx1.field.TxSuccess;
+                       pAd->WlanCounters.RetryCount.u.LowPart +=
+                           StaTx1.field.TxRetransmit;
+                       pAd->WlanCounters.FailedCount.u.LowPart +=
+                           TxStaCnt0.field.TxFailCount;
+
+                       /* if no traffic in the past 1-sec period, don't change TX rate, */
+                       /* but clear all bad history. because the bad history may affect the next */
+                       /* Chariot throughput test */
+                       AccuTxTotalCnt =
+                           pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+                           pAd->RalinkCounters.OneSecTxRetryOkCount +
+                           pAd->RalinkCounters.OneSecTxFailCount;
+
+                       if (TxTotalCnt)
+                               TxErrorRatio =
+                                   ((TxRetransmit +
+                                     TxFailCount) * 100) / TxTotalCnt;
+               } else {
+                       if (INFRA_ON(pAd) && (i == 1))
+                               Rssi = RTMPMaxRssi(pAd,
+                                                  pRssi->AvgRssi0,
+                                                  pRssi->AvgRssi1,
+                                                  pRssi->AvgRssi2);
+                       else
+                               Rssi = RTMPMaxRssi(pAd,
+                                                  pEntry->RssiSample.AvgRssi0,
+                                                  pEntry->RssiSample.AvgRssi1,
+                                                  pEntry->RssiSample.AvgRssi2);
+
+                       TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+                           pEntry->OneSecTxRetryOkCount +
+                           pEntry->OneSecTxFailCount;
+
+                       if (TxTotalCnt)
+                               TxErrorRatio =
+                                   ((pEntry->OneSecTxRetryOkCount +
+                                     pEntry->OneSecTxFailCount) * 100) /
+                                   TxTotalCnt;
+               }
+
+               if (TxTotalCnt) {
+                       /*
+                          Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool
+                          We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings
+                        */
+                       if (TxErrorRatio == 100) {
+                               TX_RTY_CFG_STRUC TxRtyCfg, TxRtyCfgtmp;
+                               unsigned long Index;
+                               unsigned long MACValue;
+
+                               RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
+                               TxRtyCfgtmp.word = TxRtyCfg.word;
+                               TxRtyCfg.field.LongRtyLimit = 0x0;
+                               TxRtyCfg.field.ShortRtyLimit = 0x0;
+                               RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
+
+                               RTMPusecDelay(1);
+
+                               Index = 0;
+                               MACValue = 0;
+                               do {
+                                       RTMP_IO_READ32(pAd, TXRXQ_PCNT,
+                                                      &MACValue);
+                                       if ((MACValue & 0xffffff) == 0)
+                                               break;
+                                       Index++;
+                                       RTMPusecDelay(1000);
+                               } while ((Index < 330)
+                                        &&
+                                        (!RTMP_TEST_FLAG
+                                         (pAd,
+                                          fRTMP_ADAPTER_HALT_IN_PROGRESS)));
+
+                               RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
+                               TxRtyCfg.field.LongRtyLimit =
+                                   TxRtyCfgtmp.field.LongRtyLimit;
+                               TxRtyCfg.field.ShortRtyLimit =
+                                   TxRtyCfgtmp.field.ShortRtyLimit;
+                               RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
+                       }
                }
 
-               //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-               if ((pEntry->RateLen == 8)
-                       && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
-                       )
-               {// G only AP
-                       *ppTable = RateSwitchTable11G;
-                       *pTableSize = RateSwitchTable11G[0];
-                       *pInitTxRateIdx = RateSwitchTable11G[1];
+               CurrRateIdx = pEntry->CurrTxRateIndex;
 
-                       break;
+               MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
+                                     &InitTxRateIdx);
+
+               if (CurrRateIdx >= TableSize) {
+                       CurrRateIdx = TableSize - 1;
                }
+               /* When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex. */
+               /* So need to sync here. */
+               pCurrTxRate =
+                   (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
+               if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
+                   /*&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE) */
+                   ) {
+
+                       /* Need to sync Real Tx rate and our record. */
+                       /* Then return for next DRS. */
+                       pCurrTxRate =
+                           (struct rt_rtmp_tx_rate_switch *) & pTable[(InitTxRateIdx + 1)
+                                                           * 5];
+                       pEntry->CurrTxRateIndex = InitTxRateIdx;
+                       MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
 
-               {
-                       //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
-                       if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
-                       {       // Legacy mode
-                               if (pAd->CommonCfg.MaxTxRate <= RATE_11)
-                               {
-                                       *ppTable = RateSwitchTable11B;
-                                       *pTableSize = RateSwitchTable11B[0];
-                                       *pInitTxRateIdx = RateSwitchTable11B[1];
-                               }
-                               else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
-                               {
-                                       *ppTable = RateSwitchTable11G;
-                                       *pTableSize = RateSwitchTable11G[0];
-                                       *pInitTxRateIdx = RateSwitchTable11G[1];
+                       /* reset all OneSecTx counters */
+                       RESET_ONE_SEC_TX_CNT(pEntry);
+                       continue;
+               }
+               /* decide the next upgrade rate and downgrade rate, if any */
+               if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) {
+                       UpRateIdx = CurrRateIdx + 1;
+                       DownRateIdx = CurrRateIdx - 1;
+               } else if (CurrRateIdx == 0) {
+                       UpRateIdx = CurrRateIdx + 1;
+                       DownRateIdx = CurrRateIdx;
+               } else if (CurrRateIdx == (TableSize - 1)) {
+                       UpRateIdx = CurrRateIdx;
+                       DownRateIdx = CurrRateIdx - 1;
+               }
 
+               pCurrTxRate =
+                   (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
+
+               if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) {
+                       TrainUp =
+                           (pCurrTxRate->TrainUp +
+                            (pCurrTxRate->TrainUp >> 1));
+                       TrainDown =
+                           (pCurrTxRate->TrainDown +
+                            (pCurrTxRate->TrainDown >> 1));
+               } else {
+                       TrainUp = pCurrTxRate->TrainUp;
+                       TrainDown = pCurrTxRate->TrainDown;
+               }
+
+               /*pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction; */
+
+               /* */
+               /* Keep the last time TxRateChangeAction status. */
+               /* */
+               pEntry->LastTimeTxRateChangeAction =
+                   pEntry->LastSecTxRateChangeAction;
+
+               /* */
+               /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */
+               /*         (criteria copied from RT2500 for Netopia case) */
+               /* */
+               if (TxTotalCnt <= 15) {
+                       char idx = 0;
+                       u8 TxRateIdx;
+                       u8 MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 =
+                           0, MCS5 = 0, MCS6 = 0, MCS7 = 0;
+                       u8 MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
+                       u8 MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0;  /* 3*3 */
+
+                       /* check the existence and index of each needed MCS */
+                       while (idx < pTable[0]) {
+                               pCurrTxRate =
+                                   (struct rt_rtmp_tx_rate_switch *) & pTable[(idx + 1) *
+                                                                   5];
+
+                               if (pCurrTxRate->CurrMCS == MCS_0) {
+                                       MCS0 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_1) {
+                                       MCS1 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_2) {
+                                       MCS2 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_3) {
+                                       MCS3 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_4) {
+                                       MCS4 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_5) {
+                                       MCS5 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_6) {
+                                       MCS6 = idx;
                                }
-                               else
+                               /*else if (pCurrTxRate->CurrMCS == MCS_7) */
+                               else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))   /* prevent the highest MCS using short GI when 1T and low throughput */
                                {
-                                       *ppTable = RateSwitchTable11BG;
-                                       *pTableSize = RateSwitchTable11BG[0];
-                                       *pInitTxRateIdx = RateSwitchTable11BG[1];
+                                       MCS7 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_12) {
+                                       MCS12 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_13) {
+                                       MCS13 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_14) {
+                                       MCS14 = idx;
                                }
-                               break;
-                       }
-
-                       if (pAd->LatchRfRegs.Channel <= 14)
-                       {
-                               if (pAd->CommonCfg.TxStream == 1)
+                               else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))  /*we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI */
                                {
-                                       *ppTable = RateSwitchTable11N1S;
-                                       *pTableSize = RateSwitchTable11N1S[0];
-                                       *pInitTxRateIdx = RateSwitchTable11N1S[1];
-                                       DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
-                               }
-                               else
+                                       MCS15 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_20)      /* 3*3 */
                                {
-                                       *ppTable = RateSwitchTable11N2S;
-                                       *pTableSize = RateSwitchTable11N2S[0];
-                                       *pInitTxRateIdx = RateSwitchTable11N2S[1];
-                                       DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+                                       MCS20 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_21) {
+                                       MCS21 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_22) {
+                                       MCS22 = idx;
+                               } else if (pCurrTxRate->CurrMCS == MCS_23) {
+                                       MCS23 = idx;
                                }
+                               idx++;
                        }
-                       else
-                       {
-                               if (pAd->CommonCfg.TxStream == 1)
-                               {
-                                       *ppTable = RateSwitchTable11N1S;
-                                       *pTableSize = RateSwitchTable11N1S[0];
-                                       *pInitTxRateIdx = RateSwitchTable11N1S[1];
-                                       DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
+
+                       if (pAd->LatchRfRegs.Channel <= 14) {
+                               if (pAd->NicConfig2.field.ExternalLNAForG) {
+                                       RssiOffset = 2;
+                               } else {
+                                       RssiOffset = 5;
                                }
-                               else
-                               {
-                                       *ppTable = RateSwitchTable11N2SForABand;
-                                       *pTableSize = RateSwitchTable11N2SForABand[0];
-                                       *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
-                                       DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+                       } else {
+                               if (pAd->NicConfig2.field.ExternalLNAForA) {
+                                       RssiOffset = 5;
+                               } else {
+                                       RssiOffset = 8;
                                }
                        }
 
-                       DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
-                               pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
-               }
-       } while(FALSE);
-}
-
-/*
-       ==========================================================================
-       Description:
-               This routine checks if there're other APs out there capable for
-               roaming. Caller should call this routine only when Link up in INFRA mode
-               and channel quality is below CQI_GOOD_THRESHOLD.
-
-       IRQL = DISPATCH_LEVEL
-
-       Output:
-       ==========================================================================
- */
-VOID MlmeCheckForRoaming(
-       IN PRTMP_ADAPTER pAd,
-       IN ULONG        Now32)
-{
-       USHORT     i;
-       BSS_TABLE  *pRoamTab = &pAd->MlmeAux.RoamTab;
-       BSS_ENTRY  *pBss;
-
-       DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
-       // put all roaming candidates into RoamTab, and sort in RSSI order
-       BssTableInit(pRoamTab);
-       for (i = 0; i < pAd->ScanTab.BssNr; i++)
-       {
-               pBss = &pAd->ScanTab.BssEntry[i];
+                       /*if (MCS15) */
+                       if ((pTable == RateSwitchTable11BGN3S) || (pTable == RateSwitchTable11N3S) || (pTable == RateSwitchTable)) {    /* N mode with 3 stream // 3*3 */
+                               if (MCS23 && (Rssi >= -70))
+                                       TxRateIdx = MCS23;
+                               else if (MCS22 && (Rssi >= -72))
+                                       TxRateIdx = MCS22;
+                               else if (MCS21 && (Rssi >= -76))
+                                       TxRateIdx = MCS21;
+                               else if (MCS20 && (Rssi >= -78))
+                                       TxRateIdx = MCS20;
+                               else if (MCS4 && (Rssi >= -82))
+                                       TxRateIdx = MCS4;
+                               else if (MCS3 && (Rssi >= -84))
+                                       TxRateIdx = MCS3;
+                               else if (MCS2 && (Rssi >= -86))
+                                       TxRateIdx = MCS2;
+                               else if (MCS1 && (Rssi >= -88))
+                                       TxRateIdx = MCS1;
+                               else
+                                       TxRateIdx = MCS0;
+                       }
+/*              else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable)) */
+                       else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) || (pTable == RateSwitchTable11N2S) || (pTable == RateSwitchTable11N2SForABand))      /* 3*3 */
+                       {       /* N mode with 2 stream */
+                               if (MCS15 && (Rssi >= (-70 + RssiOffset)))
+                                       TxRateIdx = MCS15;
+                               else if (MCS14 && (Rssi >= (-72 + RssiOffset)))
+                                       TxRateIdx = MCS14;
+                               else if (MCS13 && (Rssi >= (-76 + RssiOffset)))
+                                       TxRateIdx = MCS13;
+                               else if (MCS12 && (Rssi >= (-78 + RssiOffset)))
+                                       TxRateIdx = MCS12;
+                               else if (MCS4 && (Rssi >= (-82 + RssiOffset)))
+                                       TxRateIdx = MCS4;
+                               else if (MCS3 && (Rssi >= (-84 + RssiOffset)))
+                                       TxRateIdx = MCS3;
+                               else if (MCS2 && (Rssi >= (-86 + RssiOffset)))
+                                       TxRateIdx = MCS2;
+                               else if (MCS1 && (Rssi >= (-88 + RssiOffset)))
+                                       TxRateIdx = MCS1;
+                               else
+                                       TxRateIdx = MCS0;
+                       } else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) {    /* N mode with 1 stream */
+                               if (MCS7 && (Rssi > (-72 + RssiOffset)))
+                                       TxRateIdx = MCS7;
+                               else if (MCS6 && (Rssi > (-74 + RssiOffset)))
+                                       TxRateIdx = MCS6;
+                               else if (MCS5 && (Rssi > (-77 + RssiOffset)))
+                                       TxRateIdx = MCS5;
+                               else if (MCS4 && (Rssi > (-79 + RssiOffset)))
+                                       TxRateIdx = MCS4;
+                               else if (MCS3 && (Rssi > (-81 + RssiOffset)))
+                                       TxRateIdx = MCS3;
+                               else if (MCS2 && (Rssi > (-83 + RssiOffset)))
+                                       TxRateIdx = MCS2;
+                               else if (MCS1 && (Rssi > (-86 + RssiOffset)))
+                                       TxRateIdx = MCS1;
+                               else
+                                       TxRateIdx = MCS0;
+                       } else {        /* Legacy mode */
+                               if (MCS7 && (Rssi > -70))
+                                       TxRateIdx = MCS7;
+                               else if (MCS6 && (Rssi > -74))
+                                       TxRateIdx = MCS6;
+                               else if (MCS5 && (Rssi > -78))
+                                       TxRateIdx = MCS5;
+                               else if (MCS4 && (Rssi > -82))
+                                       TxRateIdx = MCS4;
+                               else if (MCS4 == 0)     /* for B-only mode */
+                                       TxRateIdx = MCS3;
+                               else if (MCS3 && (Rssi > -85))
+                                       TxRateIdx = MCS3;
+                               else if (MCS2 && (Rssi > -87))
+                                       TxRateIdx = MCS2;
+                               else if (MCS1 && (Rssi > -90))
+                                       TxRateIdx = MCS1;
+                               else
+                                       TxRateIdx = MCS0;
+                       }
 
-               if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
-                       continue;        // AP disappear
-               if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
-                       continue;        // RSSI too weak. forget it.
-               if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
-                       continue;        // skip current AP
-               if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
-                       continue;        // only AP with stronger RSSI is eligible for roaming
+                       /*              if (TxRateIdx != pAd->CommonCfg.TxRateIndex) */
+                       {
+                               pEntry->CurrTxRateIndex = TxRateIdx;
+                               pNextTxRate =
+                                   (struct rt_rtmp_tx_rate_switch *) &
+                                   pTable[(pEntry->CurrTxRateIndex + 1) * 5];
+                               MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+                       }
 
-               // AP passing all above rules is put into roaming candidate table
-               NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
-               pRoamTab->BssNr += 1;
-       }
+                       NdisZeroMemory(pEntry->TxQuality,
+                                      sizeof(u16)*
+                                      MAX_STEP_OF_TX_RATE_SWITCH);
+                       NdisZeroMemory(pEntry->PER,
+                                      sizeof(u8)*
+                                      MAX_STEP_OF_TX_RATE_SWITCH);
+                       pEntry->fLastSecAccordingRSSI = TRUE;
+                       /* reset all OneSecTx counters */
+                       RESET_ONE_SEC_TX_CNT(pEntry);
 
-       if (pRoamTab->BssNr > 0)
-       {
-               // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-               if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-               {
-                       pAd->RalinkCounters.PoorCQIRoamingCount ++;
-                       DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
-                       MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
-                       RT28XX_MLME_HANDLER(pAd);
+                       continue;
                }
-       }
-       DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
-}
-
-/*
-       ==========================================================================
-       Description:
-               This routine checks if there're other APs out there capable for
-               roaming. Caller should call this routine only when link up in INFRA mode
-               and channel quality is below CQI_GOOD_THRESHOLD.
-
-       IRQL = DISPATCH_LEVEL
-
-       Output:
-       ==========================================================================
- */
-VOID MlmeCheckForFastRoaming(
-       IN      PRTMP_ADAPTER   pAd,
-       IN      ULONG                   Now)
-{
-       USHORT          i;
-       BSS_TABLE       *pRoamTab = &pAd->MlmeAux.RoamTab;
-       BSS_ENTRY       *pBss;
-
-       DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
-       // put all roaming candidates into RoamTab, and sort in RSSI order
-       BssTableInit(pRoamTab);
-       for (i = 0; i < pAd->ScanTab.BssNr; i++)
-       {
-               pBss = &pAd->ScanTab.BssEntry[i];
 
-        if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
-                       continue;        // RSSI too weak. forget it.
-               if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
-                       continue;        // skip current AP
-               if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
-                       continue;        // skip different SSID
-        if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
-                       continue;        // skip AP without better RSSI
-
-        DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));
-               // AP passing all above rules is put into roaming candidate table
-               NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
-               pRoamTab->BssNr += 1;
-       }
+               if (pEntry->fLastSecAccordingRSSI == TRUE) {
+                       pEntry->fLastSecAccordingRSSI = FALSE;
+                       pEntry->LastSecTxRateChangeAction = 0;
+                       /* reset all OneSecTx counters */
+                       RESET_ONE_SEC_TX_CNT(pEntry);
 
-       if (pRoamTab->BssNr > 0)
-       {
-               // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-               if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-               {
-                       pAd->RalinkCounters.PoorCQIRoamingCount ++;
-                       DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
-                       MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
-                       RT28XX_MLME_HANDLER(pAd);
-               }
-       }
-       // Maybe site survey required
-       else
-       {
-               if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
-               {
-                       // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
-                       DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
-                       pAd->StaCfg.ScanCnt = 2;
-                       pAd->StaCfg.LastScanTime = Now;
-                       MlmeAutoScan(pAd);
+                       continue;
                }
-       }
-
-    DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
-}
 
-/*
-       ==========================================================================
-       Description:
-               This routine calculates TxPER, RxPER of the past N-sec period. And
-               according to the calculation result, ChannelQuality is calculated here
-               to decide if current AP is still doing the job.
+               do {
+                       BOOLEAN bTrainUpDown = FALSE;
 
-               If ChannelQuality is not good, a ROAMing attempt may be tried later.
-       Output:
-               StaCfg.ChannelQuality - 0..100
+                       pEntry->CurrTxRateStableTime++;
 
-       IRQL = DISPATCH_LEVEL
+                       /* downgrade TX quality if PER >= Rate-Down threshold */
+                       if (TxErrorRatio >= TrainDown) {
+                               bTrainUpDown = TRUE;
+                               pEntry->TxQuality[CurrRateIdx] =
+                                   DRS_TX_QUALITY_WORST_BOUND;
+                       }
+                       /* upgrade TX quality if PER <= Rate-Up threshold */
+                       else if (TxErrorRatio <= TrainUp) {
+                               bTrainUpDown = TRUE;
+                               bUpgradeQuality = TRUE;
+                               if (pEntry->TxQuality[CurrRateIdx])
+                                       pEntry->TxQuality[CurrRateIdx]--;       /* quality very good in CurrRate */
 
-       NOTE: This routine decide channle quality based on RX CRC error ratio.
-               Caller should make sure a function call to NICUpdateRawCounters(pAd)
-               is performed right before this routine, so that this routine can decide
-               channel quality based on the most up-to-date information
-       ==========================================================================
- */
-VOID MlmeCalculateChannelQuality(
-       IN PRTMP_ADAPTER pAd,
-       IN ULONG Now32)
-{
-       ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
-       ULONG RxCnt, RxPER;
-       UCHAR NorRssi;
-       CHAR  MaxRssi;
-       ULONG BeaconLostTime = BEACON_LOST_TIME;
-
-       MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
-
-       //
-       // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
-       //
-       TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
-       TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
-       if (TxCnt < 5)
-       {
-               TxPER = 0;
-               TxPRR = 0;
-       }
-       else
-       {
-               TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
-               TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
-       }
-
-       //
-       // calculate RX PER - don't take RxPER into consideration if too few sample
-       //
-       RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
-       if (RxCnt < 5)
-               RxPER = 0;
-       else
-               RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
-
-       //
-       // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
-       //
-       if (INFRA_ON(pAd) &&
-               (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
-               (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
-       {
-               DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
-               pAd->Mlme.ChannelQuality = 0;
-       }
-       else
-       {
-               // Normalize Rssi
-               if (MaxRssi > -40)
-                       NorRssi = 100;
-               else if (MaxRssi < -90)
-                       NorRssi = 0;
-               else
-                       NorRssi = (MaxRssi + 90) * 2;
-
-               // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER        (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
-               pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
-                                                                  TX_WEIGHTING * (100 - TxPRR) +
-                                                                  RX_WEIGHTING* (100 - RxPER)) / 100;
-               if (pAd->Mlme.ChannelQuality >= 100)
-                       pAd->Mlme.ChannelQuality = 100;
-       }
-
-}
-
-VOID MlmeSetTxRate(
-       IN PRTMP_ADAPTER                pAd,
-       IN PMAC_TABLE_ENTRY             pEntry,
-       IN PRTMP_TX_RATE_SWITCH pTxRate)
-{
-       UCHAR   MaxMode = MODE_OFDM;
-
-       MaxMode = MODE_HTGREENFIELD;
-
-       if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
-               pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
-       else
-               pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
-
-       if (pTxRate->CurrMCS < MCS_AUTO)
-               pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
-
-       if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
-               pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
-
-       if (ADHOC_ON(pAd))
-       {
-               // If peer adhoc is b-only mode, we can't send 11g rate.
-               pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-               pEntry->HTPhyMode.field.STBC    = STBC_NONE;
-
-               //
-               // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
-               //
-               pEntry->HTPhyMode.field.MODE    = pTxRate->Mode;
-               pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
-               pEntry->HTPhyMode.field.MCS             = pAd->StaCfg.HTPhyMode.field.MCS;
-
-               // Patch speed error in status page
-               pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
-       }
-       else
-       {
-               if (pTxRate->Mode <= MaxMode)
-                       pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
-
-               if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
-                       pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
-               else
-                       pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-
-               // Reexam each bandwidth's SGI support.
-               if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
-               {
-                       if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
-                               pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-                       if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
-                               pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-               }
-
-               // Turn RTS/CTS rate to 6Mbps.
-               if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
-               {
-                       pEntry->HTPhyMode.field.MCS             = pAd->StaCfg.HTPhyMode.field.MCS;
-                       if (pAd->MacTab.fAnyBASession)
-                       {
-                               AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-                       }
-                       else
-                       {
-                               AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-                       }
-               }
-               else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
-               {
-                       pEntry->HTPhyMode.field.MCS             = pAd->StaCfg.HTPhyMode.field.MCS;
-                       if (pAd->MacTab.fAnyBASession)
-                       {
-                               AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-                       }
-                       else
-                       {
-                               AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-                       }
-               }
-               else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
-               {
-                       AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-
-               }
-               else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
-               {
-                       AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
-               }
-
-               pEntry->HTPhyMode.field.STBC    = pAd->StaCfg.HTPhyMode.field.STBC;
-               pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
-               pEntry->HTPhyMode.field.MCS             = pAd->StaCfg.HTPhyMode.field.MCS;
-               pEntry->HTPhyMode.field.MODE    = pAd->StaCfg.HTPhyMode.field.MODE;
-
-               if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
-                   pAd->WIFItestbed.bGreenField)
-                   pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
-       }
-
-       pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
-}
-
-/*
-       ==========================================================================
-       Description:
-               This routine calculates the acumulated TxPER of eaxh TxRate. And
-               according to the calculation result, change CommonCfg.TxRate which
-               is the stable TX Rate we expect the Radio situation could sustained.
-
-               CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
-       Output:
-               CommonCfg.TxRate -
-
-       IRQL = DISPATCH_LEVEL
-
-       NOTE:
-               call this routine every second
-       ==========================================================================
- */
-VOID MlmeDynamicTxRateSwitching(
-       IN PRTMP_ADAPTER pAd)
-{
-       UCHAR                                   UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
-       ULONG                                   i, AccuTxTotalCnt = 0, TxTotalCnt;
-       ULONG                                   TxErrorRatio = 0;
-       BOOLEAN                                 bTxRateChanged, bUpgradeQuality = FALSE;
-       PRTMP_TX_RATE_SWITCH    pCurrTxRate, pNextTxRate = NULL;
-       PUCHAR                                  pTable;
-       UCHAR                                   TableSize = 0;
-       UCHAR                                   InitTxRateIdx = 0, TrainUp, TrainDown;
-       CHAR                                    Rssi, RssiOffset = 0;
-       TX_STA_CNT1_STRUC               StaTx1;
-       TX_STA_CNT0_STRUC               TxStaCnt0;
-       ULONG                                   TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
-       MAC_TABLE_ENTRY                 *pEntry;
-
-       //
-       // walk through MAC table, see if need to change AP's TX rate toward each entry
-       //
-       for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
-       {
-               pEntry = &pAd->MacTab.Content[i];
-
-               // check if this entry need to switch rate automatically
-               if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
-                       continue;
-
-               if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
-               {
-#ifdef RT2860
-                       Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2);
-#endif
-#ifdef RT2870
-                       Rssi = RTMPMaxRssi(pAd,
-                                                          pAd->StaCfg.RssiSample.AvgRssi0,
-                                                          pAd->StaCfg.RssiSample.AvgRssi1,
-                                                          pAd->StaCfg.RssiSample.AvgRssi2);
-#endif
-
-                       // Update statistic counter
-                       RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
-                       RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-                       pAd->bUpdateBcnCntDone = TRUE;
-                       TxRetransmit = StaTx1.field.TxRetransmit;
-                       TxSuccess = StaTx1.field.TxSuccess;
-                       TxFailCount = TxStaCnt0.field.TxFailCount;
-                       TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
-
-                       pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
-                       pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
-                       pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
-                       pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
-                       pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
-                       pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
-
-                       // if no traffic in the past 1-sec period, don't change TX rate,
-                       // but clear all bad history. because the bad history may affect the next
-                       // Chariot throughput test
-                       AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-                                                pAd->RalinkCounters.OneSecTxRetryOkCount +
-                                                pAd->RalinkCounters.OneSecTxFailCount;
-
-                       if (TxTotalCnt)
-                               TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
-               }
-               else
-               {
-#ifdef RT2860
-                       Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2);
-#endif
-#ifdef RT2870
-                       if (INFRA_ON(pAd) && (i == 1))
-                               Rssi = RTMPMaxRssi(pAd,
-                                                                  pAd->StaCfg.RssiSample.AvgRssi0,
-                                                                  pAd->StaCfg.RssiSample.AvgRssi1,
-                                                                  pAd->StaCfg.RssiSample.AvgRssi2);
-                       else
-                               Rssi = RTMPMaxRssi(pAd,
-                                                                  pEntry->RssiSample.AvgRssi0,
-                                                                  pEntry->RssiSample.AvgRssi1,
-                                                                  pEntry->RssiSample.AvgRssi2);
-#endif
-
-                       TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
-                                pEntry->OneSecTxRetryOkCount +
-                                pEntry->OneSecTxFailCount;
-
-                       if (TxTotalCnt)
-                               TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
-               }
-
-               CurrRateIdx = pEntry->CurrTxRateIndex;
-
-               MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
-
-               if (CurrRateIdx >= TableSize)
-               {
-                       CurrRateIdx = TableSize - 1;
-               }
-
-               // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
-               // So need to sync here.
-               pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
-               if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
-                       //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
-                       )
-               {
-
-                       // Need to sync Real Tx rate and our record.
-                       // Then return for next DRS.
-                       pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
-                       pEntry->CurrTxRateIndex = InitTxRateIdx;
-                       MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
-
-                       // reset all OneSecTx counters
-                       RESET_ONE_SEC_TX_CNT(pEntry);
-                       continue;
-               }
-
-               // decide the next upgrade rate and downgrade rate, if any
-               if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
-               {
-                       UpRateIdx = CurrRateIdx + 1;
-                       DownRateIdx = CurrRateIdx -1;
-               }
-               else if (CurrRateIdx == 0)
-               {
-                       UpRateIdx = CurrRateIdx + 1;
-                       DownRateIdx = CurrRateIdx;
-               }
-               else if (CurrRateIdx == (TableSize - 1))
-               {
-                       UpRateIdx = CurrRateIdx;
-                       DownRateIdx = CurrRateIdx - 1;
-               }
-
-               pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
-
-               if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
-               {
-                       TrainUp         = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
-                       TrainDown       = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
-               }
-               else
-               {
-                       TrainUp         = pCurrTxRate->TrainUp;
-                       TrainDown       = pCurrTxRate->TrainDown;
-               }
-
-               //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
-
-               //
-               // Keep the last time TxRateChangeAction status.
-               //
-               pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
-
-
-
-               //
-               // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
-               //         (criteria copied from RT2500 for Netopia case)
-               //
-               if (TxTotalCnt <= 15)
-               {
-                       CHAR    idx = 0;
-                       UCHAR   TxRateIdx;
-                       //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
-                       UCHAR   MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0,  MCS5 =0, MCS6 = 0, MCS7 = 0;
-               UCHAR   MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
-                       UCHAR   MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
-
-                       // check the existence and index of each needed MCS
-                       while (idx < pTable[0])
-                       {
-                               pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
-
-                               if (pCurrTxRate->CurrMCS == MCS_0)
-                               {
-                                       MCS0 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_1)
-                               {
-                                       MCS1 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_2)
-                               {
-                                       MCS2 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_3)
-                               {
-                                       MCS3 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_4)
-                               {
-                                       MCS4 = idx;
-                               }
-                   else if (pCurrTxRate->CurrMCS == MCS_5)
-                   {
-                       MCS5 = idx;
-                   }
-                   else if (pCurrTxRate->CurrMCS == MCS_6)
-                   {
-                       MCS6 = idx;
-                   }
-                               //else if (pCurrTxRate->CurrMCS == MCS_7)
-                               else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))   // prevent the highest MCS using short GI when 1T and low throughput
-                               {
-                                       MCS7 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_12)
-                               {
-                                       MCS12 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_13)
-                               {
-                                       MCS13 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_14)
-                               {
-                                       MCS14 = idx;
-                               }
-                               else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))  //we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI
-                               {
-                                       MCS15 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
-                               {
-                                       MCS20 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_21)
-                               {
-                                       MCS21 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_22)
-                               {
-                                       MCS22 = idx;
-                               }
-                               else if (pCurrTxRate->CurrMCS == MCS_23)
-                               {
-                                       MCS23 = idx;
-                               }
-                               idx ++;
-                       }
-
-                       if (pAd->LatchRfRegs.Channel <= 14)
-                       {
-                               if (pAd->NicConfig2.field.ExternalLNAForG)
-                               {
-                                       RssiOffset = 2;
-                               }
-                               else
-                               {
-                                       RssiOffset = 5;
-                               }
-                       }
-                       else
-                       {
-                               if (pAd->NicConfig2.field.ExternalLNAForA)
-                               {
-                                       RssiOffset = 5;
-                               }
-                               else
-                               {
-                                       RssiOffset = 8;
-                               }
-                       }
-
-                       /*if (MCS15)*/
-                       if ((pTable == RateSwitchTable11BGN3S) ||
-                               (pTable == RateSwitchTable11N3S) ||
-                               (pTable == RateSwitchTable))
-                       {// N mode with 3 stream // 3*3
-                               if (MCS23 && (Rssi >= -70))
-                                       TxRateIdx = MCS15;
-                               else if (MCS22 && (Rssi >= -72))
-                                       TxRateIdx = MCS14;
-                   else if (MCS21 && (Rssi >= -76))
-                                       TxRateIdx = MCS13;
-                               else if (MCS20 && (Rssi >= -78))
-                                       TxRateIdx = MCS12;
-                       else if (MCS4 && (Rssi >= -82))
-                               TxRateIdx = MCS4;
-                       else if (MCS3 && (Rssi >= -84))
-                               TxRateIdx = MCS3;
-                       else if (MCS2 && (Rssi >= -86))
-                               TxRateIdx = MCS2;
-                       else if (MCS1 && (Rssi >= -88))
-                               TxRateIdx = MCS1;
-                       else
-                               TxRateIdx = MCS0;
-               }
-               else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
-                       {// N mode with 2 stream
-                               if (MCS15 && (Rssi >= (-70+RssiOffset)))
-                                       TxRateIdx = MCS15;
-                               else if (MCS14 && (Rssi >= (-72+RssiOffset)))
-                                       TxRateIdx = MCS14;
-                               else if (MCS13 && (Rssi >= (-76+RssiOffset)))
-                                       TxRateIdx = MCS13;
-                               else if (MCS12 && (Rssi >= (-78+RssiOffset)))
-                                       TxRateIdx = MCS12;
-                               else if (MCS4 && (Rssi >= (-82+RssiOffset)))
-                                       TxRateIdx = MCS4;
-                               else if (MCS3 && (Rssi >= (-84+RssiOffset)))
-                                       TxRateIdx = MCS3;
-                               else if (MCS2 && (Rssi >= (-86+RssiOffset)))
-                                       TxRateIdx = MCS2;
-                               else if (MCS1 && (Rssi >= (-88+RssiOffset)))
-                                       TxRateIdx = MCS1;
-                               else
-                                       TxRateIdx = MCS0;
-                       }
-                       else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
-                       {// N mode with 1 stream
-                               if (MCS7 && (Rssi > (-72+RssiOffset)))
-                                       TxRateIdx = MCS7;
-                               else if (MCS6 && (Rssi > (-74+RssiOffset)))
-                                       TxRateIdx = MCS6;
-                               else if (MCS5 && (Rssi > (-77+RssiOffset)))
-                                       TxRateIdx = MCS5;
-                               else if (MCS4 && (Rssi > (-79+RssiOffset)))
-                                       TxRateIdx = MCS4;
-                               else if (MCS3 && (Rssi > (-81+RssiOffset)))
-                                       TxRateIdx = MCS3;
-                               else if (MCS2 && (Rssi > (-83+RssiOffset)))
-                                       TxRateIdx = MCS2;
-                               else if (MCS1 && (Rssi > (-86+RssiOffset)))
-                                       TxRateIdx = MCS1;
-                               else
-                                       TxRateIdx = MCS0;
-                       }
-                       else
-                       {// Legacy mode
-                               if (MCS7 && (Rssi > -70))
-                                       TxRateIdx = MCS7;
-                               else if (MCS6 && (Rssi > -74))
-                                       TxRateIdx = MCS6;
-                               else if (MCS5 && (Rssi > -78))
-                                       TxRateIdx = MCS5;
-                               else if (MCS4 && (Rssi > -82))
-                                       TxRateIdx = MCS4;
-                               else if (MCS4 == 0)     // for B-only mode
-                                       TxRateIdx = MCS3;
-                               else if (MCS3 && (Rssi > -85))
-                                       TxRateIdx = MCS3;
-                               else if (MCS2 && (Rssi > -87))
-                                       TxRateIdx = MCS2;
-                               else if (MCS1 && (Rssi > -90))
-                                       TxRateIdx = MCS1;
-                               else
-                                       TxRateIdx = MCS0;
-                       }
-
-                       {
-                               pEntry->CurrTxRateIndex = TxRateIdx;
-                               pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
-                               MlmeSetTxRate(pAd, pEntry, pNextTxRate);
-                       }
-
-                       NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-                       NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-                       pEntry->fLastSecAccordingRSSI = TRUE;
-                       // reset all OneSecTx counters
-                       RESET_ONE_SEC_TX_CNT(pEntry);
-
-                       continue;
-               }
-
-               if (pEntry->fLastSecAccordingRSSI == TRUE)
-               {
-                       pEntry->fLastSecAccordingRSSI = FALSE;
-                       pEntry->LastSecTxRateChangeAction = 0;
-                       // reset all OneSecTx counters
-                       RESET_ONE_SEC_TX_CNT(pEntry);
-
-                       continue;
-               }
-
-               do
-               {
-                       BOOLEAN bTrainUpDown = FALSE;
-
-                       pEntry->CurrTxRateStableTime ++;
-
-                       // downgrade TX quality if PER >= Rate-Down threshold
-                       if (TxErrorRatio >= TrainDown)
-                       {
-                               bTrainUpDown = TRUE;
-                               pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-                       }
-                       // upgrade TX quality if PER <= Rate-Up threshold
-                       else if (TxErrorRatio <= TrainUp)
-                       {
-                               bTrainUpDown = TRUE;
-                               bUpgradeQuality = TRUE;
-                               if (pEntry->TxQuality[CurrRateIdx])
-                                       pEntry->TxQuality[CurrRateIdx] --;  // quality very good in CurrRate
-
-                               if (pEntry->TxRateUpPenalty)
-                                       pEntry->TxRateUpPenalty --;
-                               else if (pEntry->TxQuality[UpRateIdx])
-                                       pEntry->TxQuality[UpRateIdx] --;    // may improve next UP rate's quality
-                       }
-
-                       pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
-
-                       if (bTrainUpDown)
-                       {
-                               // perform DRS - consider TxRate Down first, then rate up.
-                               if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
-                               {
-                                       pEntry->CurrTxRateIndex = DownRateIdx;
-                               }
-                               else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
-                               {
-                                       pEntry->CurrTxRateIndex = UpRateIdx;
-                               }
-                       }
-               } while (FALSE);
-
-               // if rate-up happen, clear all bad history of all TX rates
-               if (pEntry->CurrTxRateIndex > CurrRateIdx)
-               {
-                       pEntry->CurrTxRateStableTime = 0;
-                       pEntry->TxRateUpPenalty = 0;
-                       pEntry->LastSecTxRateChangeAction = 1; // rate UP
-                       NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-                       NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-
-                       //
-                       // For TxRate fast train up
-                       //
-                       if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
-                       {
-                               RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
-                               pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
-                       }
-                       bTxRateChanged = TRUE;
-               }
-               // if rate-down happen, only clear DownRate's bad history
-               else if (pEntry->CurrTxRateIndex < CurrRateIdx)
-               {
-                       pEntry->CurrTxRateStableTime = 0;
-                       pEntry->TxRateUpPenalty = 0;           // no penalty
-                       pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
-                       pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
-                       pEntry->PER[pEntry->CurrTxRateIndex] = 0;
-
-                       //
-                       // For TxRate fast train down
-                       //
-                       if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
-                       {
-                               RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
-                               pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
-                       }
-                       bTxRateChanged = TRUE;
-               }
-               else
-               {
-                       pEntry->LastSecTxRateChangeAction = 0; // rate no change
-                       bTxRateChanged = FALSE;
-               }
-
-               pEntry->LastTxOkCount = TxSuccess;
-
-               // reset all OneSecTx counters
-               RESET_ONE_SEC_TX_CNT(pEntry);
-
-               pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
-               if (bTxRateChanged && pNextTxRate)
-               {
-                       MlmeSetTxRate(pAd, pEntry, pNextTxRate);
-               }
-       }
-}
-
-/*
-       ========================================================================
-       Routine Description:
-               Station side, Auto TxRate faster train up timer call back function.
-
-       Arguments:
-               SystemSpecific1                 - Not used.
-               FunctionContext                 - Pointer to our Adapter context.
-               SystemSpecific2                 - Not used.
-               SystemSpecific3                 - Not used.
-
-       Return Value:
-               None
-
-       ========================================================================
-*/
-VOID StaQuickResponeForRateUpExec(
-       IN PVOID SystemSpecific1,
-       IN PVOID FunctionContext,
-       IN PVOID SystemSpecific2,
-       IN PVOID SystemSpecific3)
-{
-       PRTMP_ADAPTER                   pAd = (PRTMP_ADAPTER)FunctionContext;
-       UCHAR                                   UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
-       ULONG                                   TxTotalCnt;
-       ULONG                                   TxErrorRatio = 0;
-#ifdef RT2860
-       BOOLEAN                                 bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE;
-#endif
-#ifdef RT2870
-       BOOLEAN                                 bTxRateChanged; //, bUpgradeQuality = FALSE;
-#endif
-       PRTMP_TX_RATE_SWITCH    pCurrTxRate, pNextTxRate = NULL;
-       PUCHAR                                  pTable;
-       UCHAR                                   TableSize = 0;
-       UCHAR                                   InitTxRateIdx = 0, TrainUp, TrainDown;
-       TX_STA_CNT1_STRUC               StaTx1;
-       TX_STA_CNT0_STRUC               TxStaCnt0;
-       CHAR                                    Rssi, ratio;
-       ULONG                                   TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
-       MAC_TABLE_ENTRY                 *pEntry;
-       ULONG                                   i;
-
-       pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
-
-    //
-    // walk through MAC table, see if need to change AP's TX rate toward each entry
-    //
-       for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
-       {
-               pEntry = &pAd->MacTab.Content[i];
-
-               // check if this entry need to switch rate automatically
-               if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
-                       continue;
-
-#ifdef RT2860
-               //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
-           if (pAd->Antenna.field.TxPath > 1)
-                       Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
-               else
-                       Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
-#endif
-#ifdef RT2870
-               if (INFRA_ON(pAd) && (i == 1))
-                       Rssi = RTMPMaxRssi(pAd,
-                                                          pAd->StaCfg.RssiSample.AvgRssi0,
-                                                          pAd->StaCfg.RssiSample.AvgRssi1,
-                                                          pAd->StaCfg.RssiSample.AvgRssi2);
-               else
-                       Rssi = RTMPMaxRssi(pAd,
-                                                          pEntry->RssiSample.AvgRssi0,
-                                                          pEntry->RssiSample.AvgRssi1,
-                                                          pEntry->RssiSample.AvgRssi2);
-#endif
-
-               CurrRateIdx = pAd->CommonCfg.TxRateIndex;
-
-                       MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
-
-               // decide the next upgrade rate and downgrade rate, if any
-               if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
-               {
-                       UpRateIdx = CurrRateIdx + 1;
-                       DownRateIdx = CurrRateIdx -1;
-               }
-               else if (CurrRateIdx == 0)
-               {
-                       UpRateIdx = CurrRateIdx + 1;
-                       DownRateIdx = CurrRateIdx;
-               }
-               else if (CurrRateIdx == (TableSize - 1))
-               {
-                       UpRateIdx = CurrRateIdx;
-                       DownRateIdx = CurrRateIdx - 1;
-               }
-
-               pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
-
-               if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
-               {
-                       TrainUp         = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
-                       TrainDown       = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
-               }
-               else
-               {
-                       TrainUp         = pCurrTxRate->TrainUp;
-                       TrainDown       = pCurrTxRate->TrainDown;
-               }
-
-               if (pAd->MacTab.Size == 1)
-               {
-                       // Update statistic counter
-                       RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
-                       RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-
-                       TxRetransmit = StaTx1.field.TxRetransmit;
-                       TxSuccess = StaTx1.field.TxSuccess;
-                       TxFailCount = TxStaCnt0.field.TxFailCount;
-                       TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
-
-                       pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
-                       pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
-                       pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
-                       pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
-                       pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
-                       pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
-
-                       if (TxTotalCnt)
-                               TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
-               }
-               else
-               {
-                       TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
-                                pEntry->OneSecTxRetryOkCount +
-                                pEntry->OneSecTxFailCount;
-
-                       if (TxTotalCnt)
-                               TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
-               }
-
-
-               //
-               // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
-               //         (criteria copied from RT2500 for Netopia case)
-               //
-               if (TxTotalCnt <= 12)
-               {
-                       NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-                       NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-
-                       if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
-                       {
-                               pAd->CommonCfg.TxRateIndex = DownRateIdx;
-                               pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-                       }
-                       else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
-                       {
-                               pAd->CommonCfg.TxRateIndex = UpRateIdx;
-                       }
-
-                       DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
-                       return;
-               }
-
-               do
-               {
-                       ULONG OneSecTxNoRetryOKRationCount;
-
-                       if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
-                               ratio = 5;
-                       else
-                               ratio = 4;
-
-                       // downgrade TX quality if PER >= Rate-Down threshold
-                       if (TxErrorRatio >= TrainDown)
-                       {
-                               pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-                       }
-
-                       pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
-
-                       OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
-
-                       // perform DRS - consider TxRate Down first, then rate up.
-                       if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
-                       {
-                               if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
-                               {
-                                       pAd->CommonCfg.TxRateIndex = DownRateIdx;
-                                       pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
-
-                               }
-
-                       }
-                       else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
-                       {
-                               if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
-                               {
-
-                               }
-                               else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
-                               {
-                                       pAd->CommonCfg.TxRateIndex = UpRateIdx;
-                               }
-                       }
-               }while (FALSE);
-
-               // if rate-up happen, clear all bad history of all TX rates
-               if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
-               {
-                       pAd->DrsCounters.TxRateUpPenalty = 0;
-                       NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
-                       NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
-#ifdef RT2870
-                       bTxRateChanged = TRUE;
-#endif
-               }
-               // if rate-down happen, only clear DownRate's bad history
-               else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
-               {
-                       DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
-
-                       pAd->DrsCounters.TxRateUpPenalty = 0;           // no penalty
-                       pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
-                       pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
-#ifdef RT2870
-                       bTxRateChanged = TRUE;
-#endif
-               }
-               else
-               {
-                       bTxRateChanged = FALSE;
-               }
-
-               pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
-               if (bTxRateChanged && pNextTxRate)
-               {
-                       MlmeSetTxRate(pAd, pEntry, pNextTxRate);
-               }
-       }
-}
-
-/*
-       ==========================================================================
-       Description:
-               This routine is executed periodically inside MlmePeriodicExec() after
-               association with an AP.
-               It checks if StaCfg.Psm is consistent with user policy (recorded in
-               StaCfg.WindowsPowerMode). If not, enforce user policy. However,
-               there're some conditions to consider:
-               1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
-                  the time when Mibss==TRUE
-               2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
-                  if outgoing traffic available in TxRing or MgmtRing.
-       Output:
-               1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
-
-       IRQL = DISPATCH_LEVEL
-
-       ==========================================================================
- */
-VOID MlmeCheckPsmChange(
-       IN PRTMP_ADAPTER pAd,
-       IN ULONG        Now32)
-{
-       ULONG   PowerMode;
-
-       // condition -
-       // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
-       // 2. user wants either MAX_PSP or FAST_PSP
-       // 3. but current psm is not in PWR_SAVE
-       // 4. CNTL state machine is not doing SCANning
-       // 5. no TX SUCCESS event for the past 1-sec period
-#ifdef NDIS51_MINIPORT
-       if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
-               PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
-       else
-#endif
-               PowerMode = pAd->StaCfg.WindowsPowerMode;
-
-       if (INFRA_ON(pAd) &&
-               (PowerMode != Ndis802_11PowerModeCAM) &&
-               (pAd->StaCfg.Psm == PWR_ACTIVE) &&
-#ifdef RT2860
-               RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
-#else
-               (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
-#endif
-       {
-               // add by johnli, use Rx OK data count per second to calculate throughput
-               // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
-               // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
-               if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
-                               (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
-                       ((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
-                       (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
-               {
-                               // Get this time
-                       NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
-                       pAd->RalinkCounters.RxCountSinceLastNULL = 0;
-                       MlmeSetPsmBit(pAd, PWR_SAVE);
-                       if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
-                       {
-                               RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
-                       }
-                       else
-                       {
-                               RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-                       }
-               }
-       }
-}
-
-// IRQL = PASSIVE_LEVEL
-// IRQL = DISPATCH_LEVEL
-VOID MlmeSetPsmBit(
-       IN PRTMP_ADAPTER pAd,
-       IN USHORT psm)
-{
-       AUTO_RSP_CFG_STRUC csr4;
-
-       pAd->StaCfg.Psm = psm;
-       RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
-       csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
-       RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
-
-       DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeSetTxPreamble(
-       IN PRTMP_ADAPTER pAd,
-       IN USHORT TxPreamble)
-{
-       AUTO_RSP_CFG_STRUC csr4;
-
-       //
-       // Always use Long preamble before verifiation short preamble functionality works well.
-       // Todo: remove the following line if short preamble functionality works
-       //
-       //TxPreamble = Rt802_11PreambleLong;
-
-       RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
-       if (TxPreamble == Rt802_11PreambleLong)
-       {
-               DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
-               OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-               csr4.field.AutoResponderPreamble = 0;
-       }
-       else
-       {
-               // NOTE: 1Mbps should always use long preamble
-               DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
-               OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-               csr4.field.AutoResponderPreamble = 1;
-       }
-
-       RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
-}
-
-/*
-    ==========================================================================
-    Description:
-        Update basic rate bitmap
-    ==========================================================================
- */
-
-VOID UpdateBasicRateBitmap(
-    IN  PRTMP_ADAPTER   pAdapter)
-{
-    INT  i, j;
-                  /* 1  2  5.5, 11,  6,  9, 12, 18, 24, 36, 48,  54 */
-    UCHAR rate[] = { 2, 4,  11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
-    UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
-    UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
-    ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
-
-
-    /* if A mode, always use fix BasicRateBitMap */
-    //if (pAdapter->CommonCfg.Channel == PHY_11A)
-       if (pAdapter->CommonCfg.Channel > 14)
-        pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
-    /* End of if */
-
-    if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
-    {
-        /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
-        return;
-    } /* End of if */
-
-    for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-    {
-        sup_p[i] &= 0x7f;
-        ext_p[i] &= 0x7f;
-    } /* End of for */
-
-    for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-    {
-        if (bitmap & (1 << i))
-        {
-            for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
-            {
-                if (sup_p[j] == rate[i])
-                    sup_p[j] |= 0x80;
-                /* End of if */
-            } /* End of for */
-
-            for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
-            {
-                if (ext_p[j] == rate[i])
-                    ext_p[j] |= 0x80;
-                /* End of if */
-            } /* End of for */
-        } /* End of if */
-    } /* End of for */
-} /* End of UpdateBasicRateBitmap */
-
-// IRQL = PASSIVE_LEVEL
-// IRQL = DISPATCH_LEVEL
-// bLinkUp is to identify the inital link speed.
-// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
-VOID MlmeUpdateTxRates(
-       IN PRTMP_ADAPTER                pAd,
-       IN      BOOLEAN                         bLinkUp,
-       IN      UCHAR                           apidx)
-{
-       int i, num;
-       UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
-       UCHAR MinSupport = RATE_54;
-       ULONG BasicRateBitmap = 0;
-       UCHAR CurrBasicRate = RATE_1;
-       UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
-       PHTTRANSMIT_SETTING             pHtPhy = NULL;
-       PHTTRANSMIT_SETTING             pMaxHtPhy = NULL;
-       PHTTRANSMIT_SETTING             pMinHtPhy = NULL;
-       BOOLEAN                                 *auto_rate_cur_p;
-       UCHAR                                   HtMcs = MCS_AUTO;
-
-       // find max desired rate
-       UpdateBasicRateBitmap(pAd);
-
-       num = 0;
-       auto_rate_cur_p = NULL;
-       for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-       {
-               switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
-               {
-                       case 2:  Rate = RATE_1;   num++;   break;
-                       case 4:  Rate = RATE_2;   num++;   break;
-                       case 11: Rate = RATE_5_5; num++;   break;
-                       case 22: Rate = RATE_11;  num++;   break;
-                       case 12: Rate = RATE_6;   num++;   break;
-                       case 18: Rate = RATE_9;   num++;   break;
-                       case 24: Rate = RATE_12;  num++;   break;
-                       case 36: Rate = RATE_18;  num++;   break;
-                       case 48: Rate = RATE_24;  num++;   break;
-                       case 72: Rate = RATE_36;  num++;   break;
-                       case 96: Rate = RATE_48;  num++;   break;
-                       case 108: Rate = RATE_54; num++;   break;
-                       //default: Rate = RATE_1;   break;
-               }
-               if (MaxDesire < Rate)  MaxDesire = Rate;
-       }
-
-//===========================================================================
-//===========================================================================
-       {
-               pHtPhy          = &pAd->StaCfg.HTPhyMode;
-               pMaxHtPhy       = &pAd->StaCfg.MaxHTPhyMode;
-               pMinHtPhy       = &pAd->StaCfg.MinHTPhyMode;
-
-               auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
-               HtMcs           = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
-
-               if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
-                       (pAd->CommonCfg.PhyMode == PHY_11B) &&
-                       (MaxDesire > RATE_11))
-               {
-                       MaxDesire = RATE_11;
-               }
-       }
-
-       pAd->CommonCfg.MaxDesiredRate = MaxDesire;
-       pMinHtPhy->word = 0;
-       pMaxHtPhy->word = 0;
-       pHtPhy->word = 0;
-
-       // Auto rate switching is enabled only if more than one DESIRED RATES are
-       // specified; otherwise disabled
-       if (num <= 1)
-       {
-               *auto_rate_cur_p = FALSE;
-       }
-       else
-       {
-               *auto_rate_cur_p = TRUE;
-       }
-
-#if 1
-       if (HtMcs != MCS_AUTO)
-       {
-               *auto_rate_cur_p = FALSE;
-       }
-       else
-       {
-               *auto_rate_cur_p = TRUE;
-       }
-#endif
-
-       if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
-       {
-               pSupRate = &pAd->StaActive.SupRate[0];
-               pExtRate = &pAd->StaActive.ExtRate[0];
-               SupRateLen = pAd->StaActive.SupRateLen;
-               ExtRateLen = pAd->StaActive.ExtRateLen;
-       }
-       else
-       {
-               pSupRate = &pAd->CommonCfg.SupRate[0];
-               pExtRate = &pAd->CommonCfg.ExtRate[0];
-               SupRateLen = pAd->CommonCfg.SupRateLen;
-               ExtRateLen = pAd->CommonCfg.ExtRateLen;
-       }
-
-       // find max supported rate
-       for (i=0; i<SupRateLen; i++)
-       {
-               switch (pSupRate[i] & 0x7f)
-               {
-                       case 2:   Rate = RATE_1;        if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001;       break;
-                       case 4:   Rate = RATE_2;        if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002;       break;
-                       case 11:  Rate = RATE_5_5;      if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004;       break;
-                       case 22:  Rate = RATE_11;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008;       break;
-                       case 12:  Rate = RATE_6;        /*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
-                       case 18:  Rate = RATE_9;        if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020;       break;
-                       case 24:  Rate = RATE_12;       /*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
-                       case 36:  Rate = RATE_18;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080;       break;
-                       case 48:  Rate = RATE_24;       /*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
-                       case 72:  Rate = RATE_36;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200;       break;
-                       case 96:  Rate = RATE_48;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400;       break;
-                       case 108: Rate = RATE_54;       if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800;       break;
-                       default:  Rate = RATE_1;        break;
-               }
-               if (MaxSupport < Rate)  MaxSupport = Rate;
-
-               if (MinSupport > Rate) MinSupport = Rate;
-       }
-
-       for (i=0; i<ExtRateLen; i++)
-       {
-               switch (pExtRate[i] & 0x7f)
-               {
-                       case 2:   Rate = RATE_1;        if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001;       break;
-                       case 4:   Rate = RATE_2;        if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002;       break;
-                       case 11:  Rate = RATE_5_5;      if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004;       break;
-                       case 22:  Rate = RATE_11;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008;       break;
-                       case 12:  Rate = RATE_6;        /*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
-                       case 18:  Rate = RATE_9;        if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020;       break;
-                       case 24:  Rate = RATE_12;       /*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
-                       case 36:  Rate = RATE_18;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080;       break;
-                       case 48:  Rate = RATE_24;       /*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
-                       case 72:  Rate = RATE_36;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200;       break;
-                       case 96:  Rate = RATE_48;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400;       break;
-                       case 108: Rate = RATE_54;       if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800;       break;
-                       default:  Rate = RATE_1;        break;
-               }
-               if (MaxSupport < Rate)  MaxSupport = Rate;
-
-               if (MinSupport > Rate) MinSupport = Rate;
-       }
-
-       RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
-
-       // calculate the exptected ACK rate for each TX rate. This info is used to caculate
-       // the DURATION field of outgoing uniicast DATA/MGMT frame
-       for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
-       {
-               if (BasicRateBitmap & (0x01 << i))
-                       CurrBasicRate = (UCHAR)i;
-               pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
-       }
-
-       DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
-       // max tx rate = min {max desire rate, max supported rate}
-       if (MaxSupport < MaxDesire)
-               pAd->CommonCfg.MaxTxRate = MaxSupport;
-       else
-               pAd->CommonCfg.MaxTxRate = MaxDesire;
-
-       pAd->CommonCfg.MinTxRate = MinSupport;
-       if (*auto_rate_cur_p)
-       {
-               short dbm = 0;
-
-               dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
-
-               if (bLinkUp == TRUE)
-                       pAd->CommonCfg.TxRate = RATE_24;
-               else
-                       pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-
-               if (dbm < -75)
-                       pAd->CommonCfg.TxRate = RATE_11;
-               else if (dbm < -70)
-                       pAd->CommonCfg.TxRate = RATE_24;
-
-               // should never exceed MaxTxRate (consider 11B-only mode)
-               if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
-                       pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-
-               pAd->CommonCfg.TxRateIndex = 0;
-       }
-       else
-       {
-               pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-               pHtPhy->field.MCS       = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
-               pHtPhy->field.MODE      = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
-
-               pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC    = pHtPhy->field.STBC;
-               pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
-               pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS             = pHtPhy->field.MCS;
-               pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE    = pHtPhy->field.MODE;
-       }
-
-       if (pAd->CommonCfg.TxRate <= RATE_11)
-       {
-               pMaxHtPhy->field.MODE = MODE_CCK;
-               pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
-               pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
-       }
-       else
-       {
-               pMaxHtPhy->field.MODE = MODE_OFDM;
-               pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
-               if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
-                       {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
-               else
-                       {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
-       }
-
-       pHtPhy->word = (pMaxHtPhy->word);
-       if (bLinkUp && (pAd->OpMode == OPMODE_STA))
-       {
-                       pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
-                       pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
-                       pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
-       }
-       else
-       {
-               switch (pAd->CommonCfg.PhyMode)
-               {
-                       case PHY_11BG_MIXED:
-                       case PHY_11B:
-                       case PHY_11BGN_MIXED:
-                               pAd->CommonCfg.MlmeRate = RATE_1;
-                               pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-                               pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
-                               pAd->CommonCfg.RtsRate = RATE_11;
-                               break;
-                       case PHY_11G:
-                       case PHY_11A:
-                       case PHY_11AGN_MIXED:
-                       case PHY_11GN_MIXED:
-                       case PHY_11N_2_4G:
-                       case PHY_11AN_MIXED:
-                       case PHY_11N_5G:
-                               pAd->CommonCfg.MlmeRate = RATE_6;
-                               pAd->CommonCfg.RtsRate = RATE_6;
-                               pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-                               pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-                               break;
-                       case PHY_11ABG_MIXED:
-                       case PHY_11ABGN_MIXED:
-                               if (pAd->CommonCfg.Channel <= 14)
-                               {
-                                       pAd->CommonCfg.MlmeRate = RATE_1;
-                                       pAd->CommonCfg.RtsRate = RATE_1;
-                                       pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-                                       pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
-                               }
-                               else
-                               {
-                                       pAd->CommonCfg.MlmeRate = RATE_6;
-                                       pAd->CommonCfg.RtsRate = RATE_6;
-                                       pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-                                       pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-                               }
-                               break;
-                       default: // error
-                               pAd->CommonCfg.MlmeRate = RATE_6;
-                               pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-                               pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-                               pAd->CommonCfg.RtsRate = RATE_1;
-                               break;
-               }
-               //
-               // Keep Basic Mlme Rate.
-               //
-               pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
-               if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
-                       pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
-               else
-                       pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
-               pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
-       }
-
-       DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
-                        RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
-                        /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
-       DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
-                        RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
-       DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
-                        pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word ));
-}
-
-/*
-       ==========================================================================
-       Description:
-               This function update HT Rate setting.
-               Input Wcid value is valid for 2 case :
-               1. it's used for Station in infra mode that copy AP rate to Mactable.
-               2. OR Station   in adhoc mode to copy peer's HT rate to Mactable.
-
-       IRQL = DISPATCH_LEVEL
-
-       ==========================================================================
- */
-VOID MlmeUpdateHtTxRates(
-       IN PRTMP_ADAPTER                pAd,
-       IN      UCHAR                           apidx)
-{
-       UCHAR   StbcMcs; //j, StbcMcs, bitmask;
-       CHAR    i; // 3*3
-       RT_HT_CAPABILITY        *pRtHtCap = NULL;
-       RT_HT_PHY_INFO          *pActiveHtPhy = NULL;
-       ULONG           BasicMCS;
-       UCHAR j, bitmask;
-       PRT_HT_PHY_INFO                 pDesireHtPhy = NULL;
-       PHTTRANSMIT_SETTING             pHtPhy = NULL;
-       PHTTRANSMIT_SETTING             pMaxHtPhy = NULL;
-       PHTTRANSMIT_SETTING             pMinHtPhy = NULL;
-       BOOLEAN                                 *auto_rate_cur_p;
-
-       DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
-
-       auto_rate_cur_p = NULL;
-
-       {
-               pDesireHtPhy    = &pAd->StaCfg.DesiredHtPhyInfo;
-               pActiveHtPhy    = &pAd->StaCfg.DesiredHtPhyInfo;
-               pHtPhy          = &pAd->StaCfg.HTPhyMode;
-               pMaxHtPhy       = &pAd->StaCfg.MaxHTPhyMode;
-               pMinHtPhy       = &pAd->StaCfg.MinHTPhyMode;
-
-               auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
-       }
-
-       if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
-       {
-               if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
-                       return;
-
-               pRtHtCap = &pAd->StaActive.SupportedHtPhy;
-               pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
-               StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
-               BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
-               if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
-                       pMaxHtPhy->field.STBC = STBC_USE;
-               else
-                       pMaxHtPhy->field.STBC = STBC_NONE;
-       }
-       else
-       {
-               if (pDesireHtPhy->bHtEnable == FALSE)
-                       return;
-
-               pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
-               StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
-               BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
-               if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
-                       pMaxHtPhy->field.STBC = STBC_USE;
-               else
-                       pMaxHtPhy->field.STBC = STBC_NONE;
-       }
-
-       // Decide MAX ht rate.
-       if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
-               pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
-       else
-               pMaxHtPhy->field.MODE = MODE_HTMIX;
-
-    if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
-               pMaxHtPhy->field.BW = BW_40;
-       else
-               pMaxHtPhy->field.BW = BW_20;
-
-    if (pMaxHtPhy->field.BW == BW_20)
-               pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
-       else
-               pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
-
-       for (i=23; i>=0; i--) // 3*3
-       {
-               j = i/8;
-               bitmask = (1<<(i-(j*8)));
-
-               if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
-               {
-                       pMaxHtPhy->field.MCS = i;
-                       break;
-               }
-
-               if (i==0)
-                       break;
-       }
-
-       // Copy MIN ht rate.  rt2860???
-       pMinHtPhy->field.BW = BW_20;
-       pMinHtPhy->field.MCS = 0;
-       pMinHtPhy->field.STBC = 0;
-       pMinHtPhy->field.ShortGI = 0;
-       //If STA assigns fixed rate. update to fixed here.
-       if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
-       {
-               if (pDesireHtPhy->MCSSet[4] != 0)
-               {
-                       pMaxHtPhy->field.MCS = 32;
-                       pMinHtPhy->field.MCS = 32;
-                       DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
-               }
-
-               for (i=23; (CHAR)i >= 0; i--) // 3*3
-               {
-                       j = i/8;
-                       bitmask = (1<<(i-(j*8)));
-                       if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
-                       {
-                               pMaxHtPhy->field.MCS = i;
-                               pMinHtPhy->field.MCS = i;
-                               break;
-                       }
-                       if (i==0)
-                               break;
-               }
-       }
-
-       // Decide ht rate
-       pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
-       pHtPhy->field.BW = pMaxHtPhy->field.BW;
-       pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
-       pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
-       pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
-
-       // use default now. rt2860
-       if (pDesireHtPhy->MCSSet[0] != 0xff)
-               *auto_rate_cur_p = FALSE;
-       else
-               *auto_rate_cur_p = TRUE;
-
-       DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d  \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
-       DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d,  \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
-               pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
-       DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeRadioOff(
-       IN PRTMP_ADAPTER pAd)
-{
-       RT28XX_MLME_RADIO_OFF(pAd);
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID MlmeRadioOn(
-       IN PRTMP_ADAPTER pAd)
-{
-       RT28XX_MLME_RADIO_ON(pAd);
-}
-
-// ===========================================================================================
-// bss_table.c
-// ===========================================================================================
-
-
-/*! \brief initialize BSS table
- *     \param p_tab pointer to the table
- *     \return none
- *     \pre
- *     \post
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-VOID BssTableInit(
-       IN BSS_TABLE *Tab)
-{
-       int i;
-
-       Tab->BssNr = 0;
-    Tab->BssOverlapNr = 0;
-       for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
-       {
-               NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
-               Tab->BssEntry[i].Rssi = -127;   // initial the rssi as a minimum value
-       }
-}
-
-VOID BATableInit(
-       IN PRTMP_ADAPTER pAd,
-    IN BA_TABLE *Tab)
-{
-       int i;
-
-       Tab->numAsOriginator = 0;
-       Tab->numAsRecipient = 0;
-       NdisAllocateSpinLock(&pAd->BATabLock);
-       for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
-       {
-               Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
-               NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
-       }
-       for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
-       {
-               Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
-       }
-}
-
-/*! \brief search the BSS table by SSID
- *     \param p_tab pointer to the bss table
- *     \param ssid SSID string
- *     \return index of the table, BSS_NOT_FOUND if not in the table
- *     \pre
- *     \post
- *     \note search by sequential search
-
- IRQL = DISPATCH_LEVEL
-
- */
-ULONG BssTableSearch(
-       IN BSS_TABLE *Tab,
-       IN PUCHAR        pBssid,
-       IN UCHAR         Channel)
-{
-       UCHAR i;
-
-       for (i = 0; i < Tab->BssNr; i++)
-       {
-               //
-               // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
-               // We should distinguish this case.
-               //
-               if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-                        ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-                       MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
-               {
-                       return i;
-               }
-       }
-       return (ULONG)BSS_NOT_FOUND;
-}
-
-ULONG BssSsidTableSearch(
-       IN BSS_TABLE *Tab,
-       IN PUCHAR        pBssid,
-       IN PUCHAR        pSsid,
-       IN UCHAR         SsidLen,
-       IN UCHAR         Channel)
-{
-       UCHAR i;
-
-       for (i = 0; i < Tab->BssNr; i++)
-       {
-               //
-               // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
-               // We should distinguish this case.
-               //
-               if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-                        ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-                       MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
-                       SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
-               {
-                       return i;
-               }
-       }
-       return (ULONG)BSS_NOT_FOUND;
-}
-
-ULONG BssTableSearchWithSSID(
-       IN BSS_TABLE *Tab,
-       IN PUCHAR        Bssid,
-       IN PUCHAR        pSsid,
-       IN UCHAR         SsidLen,
-       IN UCHAR         Channel)
-{
-       UCHAR i;
-
-       for (i = 0; i < Tab->BssNr; i++)
-       {
-               if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-                       ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-                       MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
-                       (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
-                       (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
-                       (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
-               {
-                       return i;
-               }
-       }
-       return (ULONG)BSS_NOT_FOUND;
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID BssTableDeleteEntry(
-       IN OUT  BSS_TABLE *Tab,
-       IN              PUCHAR    pBssid,
-       IN              UCHAR     Channel)
-{
-       UCHAR i, j;
-
-       for (i = 0; i < Tab->BssNr; i++)
-       {
-               if ((Tab->BssEntry[i].Channel == Channel) &&
-                       (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
-               {
-                       for (j = i; j < Tab->BssNr - 1; j++)
-                       {
-                               NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
-                       }
-                       NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
-                       Tab->BssNr -= 1;
-                       return;
-               }
-       }
-}
-
-/*
-       ========================================================================
-       Routine Description:
-               Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
-
-       Arguments:
-       // IRQL = DISPATCH_LEVEL
-       ========================================================================
-*/
-VOID BATableDeleteORIEntry(
-       IN OUT  PRTMP_ADAPTER pAd,
-       IN              BA_ORI_ENTRY    *pBAORIEntry)
-{
-
-       if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
-       {
-               NdisAcquireSpinLock(&pAd->BATabLock);
-               if (pBAORIEntry->ORI_BA_Status == Originator_Done)
-               {
-                       pAd->BATable.numAsOriginator -= 1;
-                       DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
-                       // Erase Bitmap flag.
-               }
-               pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) ));       // If STA mode,  erase flag here
-               pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0;    // If STA mode,  erase flag here
-               pBAORIEntry->ORI_BA_Status = Originator_NONE;
-               pBAORIEntry->Token = 1;
-               // Not clear Sequence here.
-               NdisReleaseSpinLock(&pAd->BATabLock);
-       }
-}
-
-/*! \brief
- *     \param
- *     \return
- *     \pre
- *     \post
-
- IRQL = DISPATCH_LEVEL
-
- */
-VOID BssEntrySet(
-       IN PRTMP_ADAPTER        pAd,
-       OUT BSS_ENTRY *pBss,
-       IN PUCHAR pBssid,
-       IN CHAR Ssid[],
-       IN UCHAR SsidLen,
-       IN UCHAR BssType,
-       IN USHORT BeaconPeriod,
-       IN PCF_PARM pCfParm,
-       IN USHORT AtimWin,
-       IN USHORT CapabilityInfo,
-       IN UCHAR SupRate[],
-       IN UCHAR SupRateLen,
-       IN UCHAR ExtRate[],
-       IN UCHAR ExtRateLen,
-       IN HT_CAPABILITY_IE *pHtCapability,
-       IN ADD_HT_INFO_IE *pAddHtInfo,  // AP might use this additional ht info IE
-       IN UCHAR                        HtCapabilityLen,
-       IN UCHAR                        AddHtInfoLen,
-       IN UCHAR                        NewExtChanOffset,
-       IN UCHAR Channel,
-       IN CHAR Rssi,
-       IN LARGE_INTEGER TimeStamp,
-       IN UCHAR CkipFlag,
-       IN PEDCA_PARM pEdcaParm,
-       IN PQOS_CAPABILITY_PARM pQosCapability,
-       IN PQBSS_LOAD_PARM pQbssLoad,
-       IN USHORT LengthVIE,
-       IN PNDIS_802_11_VARIABLE_IEs pVIE)
-{
-       COPY_MAC_ADDR(pBss->Bssid, pBssid);
-       // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
-       pBss->Hidden = 1;
-       if (SsidLen > 0)
-       {
-               // For hidden SSID AP, it might send beacon with SSID len equal to 0
-               // Or send beacon /probe response with SSID len matching real SSID length,
-               // but SSID is all zero. such as "00-00-00-00" with length 4.
-               // We have to prevent this case overwrite correct table
-               if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
-               {
-                   NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
-                       NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
-                       pBss->SsidLen = SsidLen;
-                       pBss->Hidden = 0;
-               }
-       }
-       else
-               pBss->SsidLen = 0;
-       pBss->BssType = BssType;
-       pBss->BeaconPeriod = BeaconPeriod;
-       if (BssType == BSS_INFRA)
-       {
-               if (pCfParm->bValid)
-               {
-                       pBss->CfpCount = pCfParm->CfpCount;
-                       pBss->CfpPeriod = pCfParm->CfpPeriod;
-                       pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
-                       pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
-               }
-       }
-       else
-       {
-               pBss->AtimWin = AtimWin;
-       }
-
-       pBss->CapabilityInfo = CapabilityInfo;
-       // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
-       // Combine with AuthMode, they will decide the connection methods.
-       pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
-       ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
-       if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
-               NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
-       else
-               NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-       pBss->SupRateLen = SupRateLen;
-       ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
-       NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
-       NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
-       NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
-       pBss->NewExtChanOffset = NewExtChanOffset;
-       pBss->ExtRateLen = ExtRateLen;
-       pBss->Channel = Channel;
-       pBss->CentralChannel = Channel;
-       pBss->Rssi = Rssi;
-       // Update CkipFlag. if not exists, the value is 0x0
-       pBss->CkipFlag = CkipFlag;
-
-       // New for microsoft Fixed IEs
-       NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
-       pBss->FixIEs.BeaconInterval = BeaconPeriod;
-       pBss->FixIEs.Capabilities = CapabilityInfo;
-
-       // New for microsoft Variable IEs
-       if (LengthVIE != 0)
-       {
-               pBss->VarIELen = LengthVIE;
-               NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
-       }
-       else
-       {
-               pBss->VarIELen = 0;
-       }
-
-       pBss->AddHtInfoLen = 0;
-       pBss->HtCapabilityLen = 0;
-
-       if (HtCapabilityLen> 0)
-       {
-               pBss->HtCapabilityLen = HtCapabilityLen;
-               NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
-               if (AddHtInfoLen > 0)
-               {
-                       pBss->AddHtInfoLen = AddHtInfoLen;
-                       NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
-
-                               if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
-                               {
-                                       pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
-                               }
-                               else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
-                               {
-                                               pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
-                               }
-               }
-       }
-
-       BssCipherParse(pBss);
-
-       // new for QOS
-       if (pEdcaParm)
-               NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
-       else
-               pBss->EdcaParm.bValid = FALSE;
-       if (pQosCapability)
-               NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
-       else
-               pBss->QosCapability.bValid = FALSE;
-       if (pQbssLoad)
-               NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
-       else
-               pBss->QbssLoad.bValid = FALSE;
-
-       {
-               PEID_STRUCT     pEid;
-               USHORT          Length = 0;
-
-
-               NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
-               NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
-
-               pEid = (PEID_STRUCT) pVIE;
-
-               while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
-               {
-                       switch(pEid->Eid)
-                       {
-                               case IE_WPA:
-                                       if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
-                                       {
-                                               if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
-                                               {
-                                                       pBss->WpaIE.IELen = 0;
-                                                       break;
-                                               }
-                                               pBss->WpaIE.IELen = pEid->Len + 2;
-                                               NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
-                                       }
-                                       break;
-                case IE_RSN:
-                    if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
-                                       {
-                                               if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
-                                               {
-                                                       pBss->RsnIE.IELen = 0;
-                                                       break;
-                                               }
-                                               pBss->RsnIE.IELen = pEid->Len + 2;
-                                               NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
-                       }
-                               break;
-            }
-                       Length = Length + 2 + (USHORT)pEid->Len;  // Eid[1] + Len[1]+ content[Len]
-                       pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
-               }
-       }
-}
-
-/*!
- *     \brief insert an entry into the bss table
- *     \param p_tab The BSS table
- *     \param Bssid BSSID
- *     \param ssid SSID
- *     \param ssid_len Length of SSID
- *     \param bss_type
- *     \param beacon_period
- *     \param timestamp
- *     \param p_cf
- *     \param atim_win
- *     \param cap
- *     \param rates
- *     \param rates_len
- *     \param channel_idx
- *     \return none
- *     \pre
- *     \post
- *     \note If SSID is identical, the old entry will be replaced by the new one
-
- IRQL = DISPATCH_LEVEL
-
- */
-ULONG BssTableSetEntry(
-       IN      PRTMP_ADAPTER   pAd,
-       OUT BSS_TABLE *Tab,
-       IN PUCHAR pBssid,
-       IN CHAR Ssid[],
-       IN UCHAR SsidLen,
-       IN UCHAR BssType,
-       IN USHORT BeaconPeriod,
-       IN CF_PARM *CfParm,
-       IN USHORT AtimWin,
-       IN USHORT CapabilityInfo,
-       IN UCHAR SupRate[],
-       IN UCHAR SupRateLen,
-       IN UCHAR ExtRate[],
-       IN UCHAR ExtRateLen,
-       IN HT_CAPABILITY_IE *pHtCapability,
-       IN ADD_HT_INFO_IE *pAddHtInfo,  // AP might use this additional ht info IE
-       IN UCHAR                        HtCapabilityLen,
-       IN UCHAR                        AddHtInfoLen,
-       IN UCHAR                        NewExtChanOffset,
-       IN UCHAR ChannelNo,
-       IN CHAR Rssi,
-       IN LARGE_INTEGER TimeStamp,
-       IN UCHAR CkipFlag,
-       IN PEDCA_PARM pEdcaParm,
-       IN PQOS_CAPABILITY_PARM pQosCapability,
-       IN PQBSS_LOAD_PARM pQbssLoad,
-       IN USHORT LengthVIE,
-       IN PNDIS_802_11_VARIABLE_IEs pVIE)
-{
-       ULONG   Idx;
-
-       Idx = BssTableSearchWithSSID(Tab, pBssid,  Ssid, SsidLen, ChannelNo);
-       if (Idx == BSS_NOT_FOUND)
-       {
-               if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
-           {
-                       //
-                       // It may happen when BSS Table was full.
-                       // The desired AP will not be added into BSS Table
-                       // In this case, if we found the desired AP then overwrite BSS Table.
-                       //
-                       if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-                       {
-                               if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
-                                       SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
-                               {
-                                       Idx = Tab->BssOverlapNr;
-                                       BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
-                                               CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
-                                               NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
-                    Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
-                               }
-                               return Idx;
-                       }
-                       else
-                       {
-                       return BSS_NOT_FOUND;
-                       }
-               }
-               Idx = Tab->BssNr;
-               BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
-                                       CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
-                                       NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
-               Tab->BssNr++;
-       }
-       else
-       {
-               /* avoid  Hidden SSID form beacon to overwirite correct SSID from probe response */
-               if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
-                       (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
-               {
-               BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
-                                       CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
-                                       NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
-               }
-       }
-
-       return Idx;
-}
-
-// IRQL = DISPATCH_LEVEL
-VOID BssTableSsidSort(
-       IN      PRTMP_ADAPTER   pAd,
-       OUT BSS_TABLE *OutTab,
-       IN      CHAR Ssid[],
-       IN      UCHAR SsidLen)
-{
-       INT i;
-       BssTableInit(OutTab);
-
-       for (i = 0; i < pAd->ScanTab.BssNr; i++)
-       {
-               BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
-               BOOLEAN bIsHiddenApIncluded = FALSE;
-
-               if (((pAd->CommonCfg.bIEEE80211H == 1) &&
-            (pAd->MlmeAux.Channel > 14) &&
-             RadarChannelCheck(pAd, pInBss->Channel))
-            )
-               {
-                       if (pInBss->Hidden)
-                               bIsHiddenApIncluded = TRUE;
-               }
-
-               if ((pInBss->BssType == pAd->StaCfg.BssType) &&
-                       (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
-               {
-                       BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
-
-                       // 2.4G/5G N only mode
-                       if ((pInBss->HtCapabilityLen == 0) &&
-                               ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
-                       {
-                               DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
-                               continue;
-                       }
-
-                       // New for WPA2
-                       // Check the Authmode first
-                       if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-                       {
-                               // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
-                               if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
-                                       // None matched
-                                       continue;
-
-                               // Check cipher suite, AP must have more secured cipher than station setting
-                               if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-                               {
-                                       // If it's not mixed mode, we should only let BSS pass with the same encryption
-                                       if (pInBss->WPA.bMixMode == FALSE)
-                                               if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
-                                                       continue;
-
-                                       // check group cipher
-                                       if (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled &&
-                                           pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled &&
-                                           pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
-                                               continue;
-
-                                       // check pairwise cipher, skip if none matched
-                                       // If profile set to AES, let it pass without question.
-                                       // If profile set to TKIP, we must find one mateched
-                                       if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-                                               (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
-                                               (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
-                                               continue;
-                               }
-                               else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-                               {
-                                       // If it's not mixed mode, we should only let BSS pass with the same encryption
-                                       if (pInBss->WPA2.bMixMode == FALSE)
-                                               if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
-                                                       continue;
-
-                                       // check group cipher
-                                       if (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled &&
-                                           pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled &&
-                                           pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
-                                               continue;
-
-                                       // check pairwise cipher, skip if none matched
-                                       // If profile set to AES, let it pass without question.
-                                       // If profile set to TKIP, we must find one mateched
-                                       if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-                                               (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
-                                               (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
-                                               continue;
-                               }
-                       }
-                       // Bss Type matched, SSID matched.
-                       // We will check wepstatus for qualification Bss
-                       else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
-                       {
-                               DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
-                               //
-                               // For the SESv2 case, we will not qualify WepStatus.
-                               //
-                               if (!pInBss->bSES)
-                                       continue;
-                       }
-
-                       // Since the AP is using hidden SSID, and we are trying to connect to ANY
-                       // It definitely will fail. So, skip it.
-                       // CCX also require not even try to connect it!!
-                       if (SsidLen == 0)
-                               continue;
-
-                       // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
-                       // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
-                       if ((pInBss->CentralChannel != pInBss->Channel) &&
-                               (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
-                       {
-                               if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
-                               {
-                                       pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
-                                       SetCommonHT(pAd);
-                                       pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
-                               }
-                               else
-                               {
-                                       if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
-                                       {
-                                               SetCommonHT(pAd);
-                                       }
-                               }
-                       }
-
-                       // copy matching BSS from InTab to OutTab
-                       NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
-
-                       OutTab->BssNr++;
-               }
-               else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
-               {
-                       BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
-
-                       // 2.4G/5G N only mode
-                       if ((pInBss->HtCapabilityLen == 0) &&
-                               ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
-                       {
-                               DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
-                               continue;
-                       }
-
-                       // New for WPA2
-                       // Check the Authmode first
-                       if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-                       {
-                               // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
-                               if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
-                                       // None matched
-                                       continue;
-
-                               // Check cipher suite, AP must have more secured cipher than station setting
-                               if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
-                               {
-                                       // If it's not mixed mode, we should only let BSS pass with the same encryption
-                                       if (pInBss->WPA.bMixMode == FALSE)
-                                               if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
-                                                       continue;
-
-                                       // check group cipher
-                                       if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
-                                               continue;
-
-                                       // check pairwise cipher, skip if none matched
-                                       // If profile set to AES, let it pass without question.
-                                       // If profile set to TKIP, we must find one mateched
-                                       if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-                                               (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
-                                               (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
-                                               continue;
-                               }
-                               else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-                               {
-                                       // If it's not mixed mode, we should only let BSS pass with the same encryption
-                                       if (pInBss->WPA2.bMixMode == FALSE)
-                                               if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
-                                                       continue;
-
-                                       // check group cipher
-                                       if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
-                                               continue;
-
-                                       // check pairwise cipher, skip if none matched
-                                       // If profile set to AES, let it pass without question.
-                                       // If profile set to TKIP, we must find one mateched
-                                       if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
-                                               (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
-                                               (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
-                                               continue;
-                               }
-                       }
-                       // Bss Type matched, SSID matched.
-                       // We will check wepstatus for qualification Bss
-                       else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
-                                       continue;
-
-                       // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
-                       // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
-                       if ((pInBss->CentralChannel != pInBss->Channel) &&
-                               (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
-                       {
-                               if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
-                               {
-                                       pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
-                                       SetCommonHT(pAd);
-                                       pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
-                               }
-                       }
-
-                       // copy matching BSS from InTab to OutTab
-                       NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
-
-                       OutTab->BssNr++;
-               }
-
-               if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
-                       break;
-       }
-
-       BssTableSortByRssi(OutTab);
-}
-
-
-// IRQL = DISPATCH_LEVEL
-VOID BssTableSortByRssi(
-       IN OUT BSS_TABLE *OutTab)
-{
-       INT       i, j;
-       BSS_ENTRY TmpBss;
-
-       for (i = 0; i < OutTab->BssNr - 1; i++)
-       {
-               for (j = i+1; j < OutTab->BssNr; j++)
-               {
-                       if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
-                       {
-                               NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
-                               NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
-                               NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
-                       }
-               }
-       }
-}
-
-VOID BssCipherParse(
-       IN OUT  PBSS_ENTRY      pBss)
-{
-       PEID_STRUCT              pEid;
-       PUCHAR                          pTmp;
-       PRSN_IE_HEADER_STRUCT                   pRsnHeader;
-       PCIPHER_SUITE_STRUCT                    pCipher;
-       PAKM_SUITE_STRUCT                               pAKM;
-       USHORT                                                  Count;
-       INT                                                             Length;
-       NDIS_802_11_ENCRYPTION_STATUS   TmpCipher;
-
-       //
-       // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
-       //
-       if (pBss->Privacy)
-       {
-               pBss->WepStatus         = Ndis802_11WEPEnabled;
-       }
-       else
-       {
-               pBss->WepStatus         = Ndis802_11WEPDisabled;
-       }
-       // Set default to disable & open authentication before parsing variable IE
-       pBss->AuthMode          = Ndis802_11AuthModeOpen;
-       pBss->AuthModeAux       = Ndis802_11AuthModeOpen;
-
-       // Init WPA setting
-       pBss->WPA.PairCipher    = Ndis802_11WEPDisabled;
-       pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
-       pBss->WPA.GroupCipher   = Ndis802_11WEPDisabled;
-       pBss->WPA.RsnCapability = 0;
-       pBss->WPA.bMixMode              = FALSE;
-
-       // Init WPA2 setting
-       pBss->WPA2.PairCipher    = Ndis802_11WEPDisabled;
-       pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
-       pBss->WPA2.GroupCipher   = Ndis802_11WEPDisabled;
-       pBss->WPA2.RsnCapability = 0;
-       pBss->WPA2.bMixMode      = FALSE;
-
-
-       Length = (INT) pBss->VarIELen;
-
-       while (Length > 0)
-       {
-               // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
-               pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
-               pEid = (PEID_STRUCT) pTmp;
-               switch (pEid->Eid)
-               {
-                       case IE_WPA:
-                               //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
-                               if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
-                               {
-                                       pTmp   += 11;
-                                       switch (*pTmp)
-                                       {
-                                               case 1:
-                                               case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
-                                                       pBss->WepStatus = Ndis802_11Encryption1Enabled;
-                                                       pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
-                                                       pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
-                                                       break;
-                                               case 2:
-                                                       pBss->WepStatus = Ndis802_11Encryption2Enabled;
-                                                       pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
-                                                       pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
-                                                       break;
-                                               case 4:
-                                                       pBss->WepStatus = Ndis802_11Encryption3Enabled;
-                                                       pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
-                                                       pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
-                                                       break;
-                                               default:
-                                                       break;
-                                       }
-
-                                       // if Cisco IE_WPA, break
-                                       break;
-                               }
-                               else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
-                               {
-                                       pBss->bSES = TRUE;
-                                       break;
-                               }
-                               else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
-                               {
-                                       // if unsupported vendor specific IE
-                                       break;
-                               }
-                               // Skip OUI, version, and multicast suite
-                               // This part should be improved in the future when AP supported multiple cipher suite.
-                               // For now, it's OK since almost all APs have fixed cipher suite supported.
-                               // pTmp = (PUCHAR) pEid->Octet;
-                               pTmp   += 11;
-
-                               // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
-                               //      Value      Meaning
-                               //      0                       None
-                               //      1                       WEP-40
-                               //      2                       Tkip
-                               //      3                       WRAP
-                               //      4                       AES
-                               //      5                       WEP-104
-                               // Parse group cipher
-                               switch (*pTmp)
-                               {
-                                       case 1:
-                                               pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
-                                               break;
-                                       case 5:
-                                               pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
-                                               break;
-                                       case 2:
-                                               pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
-                                               break;
-                                       case 4:
-                                               pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
-                                               break;
-                                       default:
-                                               break;
-                               }
-                               // number of unicast suite
-                               pTmp   += 1;
-
-                               // skip all unicast cipher suites
-                               //Count = *(PUSHORT) pTmp;
-                               Count = (pTmp[1]<<8) + pTmp[0];
-                               pTmp   += sizeof(USHORT);
-
-                               // Parsing all unicast cipher suite
-                               while (Count > 0)
-                               {
-                                       // Skip OUI
-                                       pTmp += 3;
-                                       TmpCipher = Ndis802_11WEPDisabled;
-                                       switch (*pTmp)
-                                       {
-                                               case 1:
-                                               case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
-                                                       TmpCipher = Ndis802_11Encryption1Enabled;
-                                                       break;
-                                               case 2:
-                                                       TmpCipher = Ndis802_11Encryption2Enabled;
-                                                       break;
-                                               case 4:
-                                                       TmpCipher = Ndis802_11Encryption3Enabled;
-                                                       break;
-                                               default:
-                                                       break;
-                                       }
-                                       if (TmpCipher > pBss->WPA.PairCipher)
-                                       {
-                                               // Move the lower cipher suite to PairCipherAux
-                                               pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
-                                               pBss->WPA.PairCipher    = TmpCipher;
-                                       }
-                                       else
-                                       {
-                                               pBss->WPA.PairCipherAux = TmpCipher;
-                                       }
-                                       pTmp++;
-                                       Count--;
-                               }
-
-                               // 4. get AKM suite counts
-                               //Count = *(PUSHORT) pTmp;
-                               Count = (pTmp[1]<<8) + pTmp[0];
-                               pTmp   += sizeof(USHORT);
-                               pTmp   += 3;
-
-                               switch (*pTmp)
-                               {
-                                       case 1:
-                                               // Set AP support WPA mode
-                                               if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-                                                       pBss->AuthMode = Ndis802_11AuthModeWPA;
-                                               else
-                                                       pBss->AuthModeAux = Ndis802_11AuthModeWPA;
-                                               break;
-                                       case 2:
-                                               // Set AP support WPA mode
-                                               if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-                                                       pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
-                                               else
-                                                       pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
-                                               break;
-                                       default:
-                                               break;
-                               }
-                               pTmp   += 1;
-
-                               // Fixed for WPA-None
-                               if (pBss->BssType == BSS_ADHOC)
-                               {
-                                       pBss->AuthMode    = Ndis802_11AuthModeWPANone;
-                                       pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
-                                       pBss->WepStatus   = pBss->WPA.GroupCipher;
-                                       if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
-                                               pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
-                               }
-                               else
-                                       pBss->WepStatus   = pBss->WPA.PairCipher;
-
-                               // Check the Pair & Group, if different, turn on mixed mode flag
-                               if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
-                                       pBss->WPA.bMixMode = TRUE;
-
-                               break;
-
-                       case IE_RSN:
-                               pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
-
-                               // 0. Version must be 1
-                               if (le2cpu16(pRsnHeader->Version) != 1)
-                                       break;
-                               pTmp   += sizeof(RSN_IE_HEADER_STRUCT);
-
-                               // 1. Check group cipher
-                               pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
-                               if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
-                                       break;
-
-                               // Parse group cipher
-                               switch (pCipher->Type)
-                               {
-                                       case 1:
-                                               pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
-                                               break;
-                                       case 5:
-                                               pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
-                                               break;
-                                       case 2:
-                                               pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
-                                               break;
-                                       case 4:
-                                               pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
-                                               break;
-                                       default:
-                                               break;
-                               }
-                               // set to correct offset for next parsing
-                               pTmp   += sizeof(CIPHER_SUITE_STRUCT);
-
-                               // 2. Get pairwise cipher counts
-                               //Count = *(PUSHORT) pTmp;
-                               Count = (pTmp[1]<<8) + pTmp[0];
-                               pTmp   += sizeof(USHORT);
-
-                               // 3. Get pairwise cipher
-                               // Parsing all unicast cipher suite
-                               while (Count > 0)
-                               {
-                                       // Skip OUI
-                                       pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
-                                       TmpCipher = Ndis802_11WEPDisabled;
-                                       switch (pCipher->Type)
-                                       {
-                                               case 1:
-                                               case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
-                                                       TmpCipher = Ndis802_11Encryption1Enabled;
-                                                       break;
-                                               case 2:
-                                                       TmpCipher = Ndis802_11Encryption2Enabled;
-                                                       break;
-                                               case 4:
-                                                       TmpCipher = Ndis802_11Encryption3Enabled;
-                                                       break;
-                                               default:
-                                                       break;
-                                       }
-                                       if (TmpCipher > pBss->WPA2.PairCipher)
-                                       {
-                                               // Move the lower cipher suite to PairCipherAux
-                                               pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
-                                               pBss->WPA2.PairCipher    = TmpCipher;
-                                       }
-                                       else
-                                       {
-                                               pBss->WPA2.PairCipherAux = TmpCipher;
-                                       }
-                                       pTmp += sizeof(CIPHER_SUITE_STRUCT);
-                                       Count--;
-                               }
-
-                               // 4. get AKM suite counts
-                               //Count = *(PUSHORT) pTmp;
-                               Count = (pTmp[1]<<8) + pTmp[0];
-                               pTmp   += sizeof(USHORT);
-
-                               // 5. Get AKM ciphers
-                               pAKM = (PAKM_SUITE_STRUCT) pTmp;
-                               if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
-                                       break;
-
-                               switch (pAKM->Type)
-                               {
-                                       case 1:
-                                               // Set AP support WPA mode
-                                               if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-                                                       pBss->AuthMode = Ndis802_11AuthModeWPA2;
-                                               else
-                                                       pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
-                                               break;
-                                       case 2:
-                                               // Set AP support WPA mode
-                                               if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-                                                       pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
-                                               else
-                                                       pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
-                                               break;
-                                       default:
-                                               break;
-                               }
-                               pTmp   += (Count * sizeof(AKM_SUITE_STRUCT));
-
-                               // Fixed for WPA-None
-                               if (pBss->BssType == BSS_ADHOC)
-                               {
-                                       pBss->AuthMode = Ndis802_11AuthModeWPANone;
-                                       pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
-                                       pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
-                                       pBss->WPA.GroupCipher   = pBss->WPA2.GroupCipher;
-                                       pBss->WepStatus                 = pBss->WPA.GroupCipher;
-                                       if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
-                                               pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
-                               }
-                               pBss->WepStatus   = pBss->WPA2.PairCipher;
-
-                               // 6. Get RSN capability
-                               //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
-                               pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
-                               pTmp += sizeof(USHORT);
-
-                               // Check the Pair & Group, if different, turn on mixed mode flag
-                               if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
-                                       pBss->WPA2.bMixMode = TRUE;
-
-                               break;
-                       default:
-                               break;
-               }
-               Length -= (pEid->Len + 2);
-       }
-}
-
-// ===========================================================================================
-// mac_table.c
-// ===========================================================================================
-
-/*! \brief generates a random mac address value for IBSS BSSID
- *     \param Addr the bssid location
- *     \return none
- *     \pre
- *     \post
- */
-VOID MacAddrRandomBssid(
-       IN PRTMP_ADAPTER pAd,
-       OUT PUCHAR pAddr)
-{
-       INT i;
-
-       for (i = 0; i < MAC_ADDR_LEN; i++)
-       {
-               pAddr[i] = RandomByte(pAd);
-       }
-
-       pAddr[0] = (pAddr[0] & 0xfe) | 0x02;  // the first 2 bits must be 01xxxxxxxx
-}
-
-/*! \brief init the management mac frame header
- *     \param p_hdr mac header
- *     \param subtype subtype of the frame
- *     \param p_ds destination address, don't care if it is a broadcast address
- *     \return none
- *     \pre the station has the following information in the pAd->StaCfg
- *      - bssid
- *      - station address
- *     \post
- *     \note this function initializes the following field
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-VOID MgtMacHeaderInit(
-       IN      PRTMP_ADAPTER   pAd,
-       IN OUT PHEADER_802_11 pHdr80211,
-       IN UCHAR SubType,
-       IN UCHAR ToDs,
-       IN PUCHAR pDA,
-       IN PUCHAR pBssid)
-{
-       NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
-
-       pHdr80211->FC.Type = BTYPE_MGMT;
-       pHdr80211->FC.SubType = SubType;
-       pHdr80211->FC.ToDs = ToDs;
-       COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
-
-       COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
-
-       COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
-}
-
-// ===========================================================================================
-// mem_mgmt.c
-// ===========================================================================================
-
-/*!***************************************************************************
- * This routine build an outgoing frame, and fill all information specified
- * in argument list to the frame body. The actual frame size is the summation
- * of all arguments.
- * input params:
- *             Buffer - pointer to a pre-allocated memory segment
- *             args - a list of <int arg_size, arg> pairs.
- *             NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
- *                                                function will FAIL!!!
- * return:
- *             Size of the buffer
- * usage:
- *             MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- ****************************************************************************/
-ULONG MakeOutgoingFrame(
-       OUT CHAR *Buffer,
-       OUT ULONG *FrameLen, ...)
-{
-       CHAR   *p;
-       int     leng;
-       ULONG   TotLeng;
-       va_list Args;
-
-       // calculates the total length
-       TotLeng = 0;
-       va_start(Args, FrameLen);
-       do
-       {
-               leng = va_arg(Args, int);
-               if (leng == END_OF_ARGS)
-               {
-                       break;
-               }
-               p = va_arg(Args, PVOID);
-               NdisMoveMemory(&Buffer[TotLeng], p, leng);
-               TotLeng = TotLeng + leng;
-       } while(TRUE);
-
-       va_end(Args); /* clean up */
-       *FrameLen = TotLeng;
-       return TotLeng;
-}
-
-// ===========================================================================================
-// mlme_queue.c
-// ===========================================================================================
-
-/*! \brief     Initialize The MLME Queue, used by MLME Functions
- *     \param  *Queue     The MLME Queue
- *     \return Always     Return NDIS_STATE_SUCCESS in this implementation
- *     \pre
- *     \post
- *     \note   Because this is done only once (at the init stage), no need to be locked
-
- IRQL = PASSIVE_LEVEL
-
- */
-NDIS_STATUS MlmeQueueInit(
-       IN MLME_QUEUE *Queue)
-{
-       INT i;
-
-       NdisAllocateSpinLock(&Queue->Lock);
-
-       Queue->Num      = 0;
-       Queue->Head = 0;
-       Queue->Tail = 0;
+                               if (pEntry->TxRateUpPenalty)
+                                       pEntry->TxRateUpPenalty--;
+                               else if (pEntry->TxQuality[UpRateIdx])
+                                       pEntry->TxQuality[UpRateIdx]--; /* may improve next UP rate's quality */
+                       }
 
-       for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
-       {
-               Queue->Entry[i].Occupied = FALSE;
-               Queue->Entry[i].MsgLen = 0;
-               NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
-       }
+                       pEntry->PER[CurrRateIdx] = (u8)TxErrorRatio;
 
-       return NDIS_STATUS_SUCCESS;
-}
+                       if (bTrainUpDown) {
+                               /* perform DRS - consider TxRate Down first, then rate up. */
+                               if ((CurrRateIdx != DownRateIdx)
+                                   && (pEntry->TxQuality[CurrRateIdx] >=
+                                       DRS_TX_QUALITY_WORST_BOUND)) {
+                                       pEntry->CurrTxRateIndex = DownRateIdx;
+                               } else if ((CurrRateIdx != UpRateIdx)
+                                          && (pEntry->TxQuality[UpRateIdx] <=
+                                              0)) {
+                                       pEntry->CurrTxRateIndex = UpRateIdx;
+                               }
+                       }
+               } while (FALSE);
 
-/*! \brief      Enqueue a message for other threads, if they want to send messages to MLME thread
- *     \param  *Queue    The MLME Queue
- *     \param   Machine  The State Machine Id
- *     \param   MsgType  The Message Type
- *     \param   MsgLen   The Message length
- *     \param  *Msg      The message pointer
- *     \return  TRUE if enqueue is successful, FALSE if the queue is full
- *     \pre
- *     \post
- *     \note    The message has to be initialized
+               /* if rate-up happen, clear all bad history of all TX rates */
+               if (pEntry->CurrTxRateIndex > CurrRateIdx) {
+                       pEntry->CurrTxRateStableTime = 0;
+                       pEntry->TxRateUpPenalty = 0;
+                       pEntry->LastSecTxRateChangeAction = 1;  /* rate UP */
+                       NdisZeroMemory(pEntry->TxQuality,
+                                      sizeof(u16)*
+                                      MAX_STEP_OF_TX_RATE_SWITCH);
+                       NdisZeroMemory(pEntry->PER,
+                                      sizeof(u8)*
+                                      MAX_STEP_OF_TX_RATE_SWITCH);
+
+                       /* */
+                       /* For TxRate fast train up */
+                       /* */
+                       if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) {
+                               RTMPSetTimer(&pAd->StaCfg.
+                                            StaQuickResponeForRateUpTimer,
+                                            100);
+
+                               pAd->StaCfg.
+                                   StaQuickResponeForRateUpTimerRunning = TRUE;
+                       }
+                       bTxRateChanged = TRUE;
+               }
+               /* if rate-down happen, only clear DownRate's bad history */
+               else if (pEntry->CurrTxRateIndex < CurrRateIdx) {
+                       pEntry->CurrTxRateStableTime = 0;
+                       pEntry->TxRateUpPenalty = 0;    /* no penalty */
+                       pEntry->LastSecTxRateChangeAction = 2;  /* rate DOWN */
+                       pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
+                       pEntry->PER[pEntry->CurrTxRateIndex] = 0;
 
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
+                       /* */
+                       /* For TxRate fast train down */
+                       /* */
+                       if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) {
+                               RTMPSetTimer(&pAd->StaCfg.
+                                            StaQuickResponeForRateUpTimer,
+                                            100);
 
- */
-BOOLEAN MlmeEnqueue(
-       IN      PRTMP_ADAPTER   pAd,
-       IN ULONG Machine,
-       IN ULONG MsgType,
-       IN ULONG MsgLen,
-       IN VOID *Msg)
-{
-       INT Tail;
-       MLME_QUEUE      *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+                               pAd->StaCfg.
+                                   StaQuickResponeForRateUpTimerRunning = TRUE;
+                       }
+                       bTxRateChanged = TRUE;
+               } else {
+                       pEntry->LastSecTxRateChangeAction = 0;  /* rate no change */
+                       bTxRateChanged = FALSE;
+               }
 
-       // 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 FALSE;
+               pEntry->LastTxOkCount = TxSuccess;
+               {
+                       u8 tmpTxRate;
+
+                       /* to fix tcp ack issue */
+                       if (!bTxRateChanged
+                           && (pAd->RalinkCounters.OneSecReceivedByteCount >
+                               (pAd->RalinkCounters.
+                                OneSecTransmittedByteCount * 5))) {
+                               tmpTxRate = DownRateIdx;
+                               DBGPRINT_RAW(RT_DEBUG_TRACE,
+                                            ("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n",
+                                             pAd->RalinkCounters.
+                                             OneSecReceivedByteCount,
+                                             pAd->RalinkCounters.
+                                             OneSecTransmittedByteCount,
+                                             pEntry->CurrTxRateIndex,
+                                             tmpTxRate));
+                       } else {
+                               tmpTxRate = pEntry->CurrTxRateIndex;
+                       }
 
-       // First check the size, it MUST not exceed the mlme queue size
-       if (MsgLen > MGMT_DMA_BUFFER_SIZE)
-       {
-               DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
-               return FALSE;
+                       pNextTxRate =
+                           (struct rt_rtmp_tx_rate_switch *) & pTable[(tmpTxRate + 1) *
+                                                           5];
+               }
+               if (bTxRateChanged && pNextTxRate) {
+                       MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+               }
+               /* reset all OneSecTx counters */
+               RESET_ONE_SEC_TX_CNT(pEntry);
        }
+}
 
-       if (MlmeQueueFull(Queue))
-       {
-               return FALSE;
-       }
+/*
+       ========================================================================
+       Routine Description:
+               Station side, Auto TxRate faster train up timer call back function.
 
-       NdisAcquireSpinLock(&(Queue->Lock));
-       Tail = Queue->Tail;
-       Queue->Tail++;
-       Queue->Num++;
-       if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
-       {
-               Queue->Tail = 0;
-       }
+       Arguments:
+               SystemSpecific1                 - Not used.
+               FunctionContext                 - Pointer to our Adapter context.
+               SystemSpecific2                 - Not used.
+               SystemSpecific3                 - Not used.
 
-       Queue->Entry[Tail].Wcid = RESERVED_WCID;
-       Queue->Entry[Tail].Occupied = TRUE;
-       Queue->Entry[Tail].Machine = Machine;
-       Queue->Entry[Tail].MsgType = MsgType;
-       Queue->Entry[Tail].MsgLen  = MsgLen;
+       Return Value:
+               None
 
-       if (Msg != NULL)
-       {
-               NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
-       }
+       ========================================================================
+*/
+void StaQuickResponeForRateUpExec(void *SystemSpecific1,
+                                 void *FunctionContext,
+                                 void *SystemSpecific2,
+                                 void *SystemSpecific3)
+{
+       struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+       u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
+       unsigned long TxTotalCnt;
+       unsigned long TxErrorRatio = 0;
+       BOOLEAN bTxRateChanged; /*, bUpgradeQuality = FALSE; */
+       struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL;
+       u8 *pTable;
+       u8 TableSize = 0;
+       u8 InitTxRateIdx = 0, TrainUp, TrainDown;
+       TX_STA_CNT1_STRUC StaTx1;
+       TX_STA_CNT0_STRUC TxStaCnt0;
+       char Rssi, ratio;
+       unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+       struct rt_mac_table_entry *pEntry;
+       unsigned long i;
 
-       NdisReleaseSpinLock(&(Queue->Lock));
-       return TRUE;
-}
+       pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
 
-/*! \brief      This function is used when Recv gets a MLME message
- *     \param  *Queue                   The MLME Queue
- *     \param   TimeStampHigh   The upper 32 bit of timestamp
- *     \param   TimeStampLow    The lower 32 bit of timestamp
- *     \param   Rssi                    The receiving RSSI strength
- *     \param   MsgLen                  The length of the message
- *     \param  *Msg                     The message pointer
- *     \return  TRUE if everything ok, FALSE otherwise (like Queue Full)
- *     \pre
- *     \post
+       /* */
+       /* walk through MAC table, see if need to change AP's TX rate toward each entry */
+       /* */
+       for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
+               pEntry = &pAd->MacTab.Content[i];
 
- IRQL = DISPATCH_LEVEL
+               /* check if this entry need to switch rate automatically */
+               if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+                       continue;
 
- */
-BOOLEAN MlmeEnqueueForRecv(
-       IN      PRTMP_ADAPTER   pAd,
-       IN ULONG Wcid,
-       IN ULONG TimeStampHigh,
-       IN ULONG TimeStampLow,
-       IN UCHAR Rssi0,
-       IN UCHAR Rssi1,
-       IN UCHAR Rssi2,
-       IN ULONG MsgLen,
-       IN VOID *Msg,
-       IN UCHAR Signal)
-{
-       INT              Tail, Machine;
-       PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
-       INT              MsgType;
-       MLME_QUEUE      *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
-
-       // 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))
-       {
-               DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
-               return FALSE;
-       }
+               if (INFRA_ON(pAd) && (i == 1))
+                       Rssi = RTMPMaxRssi(pAd,
+                                          pAd->StaCfg.RssiSample.AvgRssi0,
+                                          pAd->StaCfg.RssiSample.AvgRssi1,
+                                          pAd->StaCfg.RssiSample.AvgRssi2);
+               else
+                       Rssi = RTMPMaxRssi(pAd,
+                                          pEntry->RssiSample.AvgRssi0,
+                                          pEntry->RssiSample.AvgRssi1,
+                                          pEntry->RssiSample.AvgRssi2);
 
-       // First check the size, it MUST not exceed the mlme queue size
-       if (MsgLen > MGMT_DMA_BUFFER_SIZE)
-       {
-               DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
-               return FALSE;
-       }
+               CurrRateIdx = pAd->CommonCfg.TxRateIndex;
 
-       if (MlmeQueueFull(Queue))
-       {
-               return FALSE;
-       }
+               MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
+                                     &InitTxRateIdx);
 
-       {
-               if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
-               {
-                       DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
-                       return FALSE;
+               /* decide the next upgrade rate and downgrade rate, if any */
+               if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) {
+                       UpRateIdx = CurrRateIdx + 1;
+                       DownRateIdx = CurrRateIdx - 1;
+               } else if (CurrRateIdx == 0) {
+                       UpRateIdx = CurrRateIdx + 1;
+                       DownRateIdx = CurrRateIdx;
+               } else if (CurrRateIdx == (TableSize - 1)) {
+                       UpRateIdx = CurrRateIdx;
+                       DownRateIdx = CurrRateIdx - 1;
                }
-       }
 
-       // OK, we got all the informations, it is time to put things into queue
-       NdisAcquireSpinLock(&(Queue->Lock));
-       Tail = Queue->Tail;
-       Queue->Tail++;
-       Queue->Num++;
-       if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
-       {
-               Queue->Tail = 0;
-       }
-       Queue->Entry[Tail].Occupied = TRUE;
-       Queue->Entry[Tail].Machine = Machine;
-       Queue->Entry[Tail].MsgType = MsgType;
-       Queue->Entry[Tail].MsgLen  = MsgLen;
-       Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
-       Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
-       Queue->Entry[Tail].Rssi0 = Rssi0;
-       Queue->Entry[Tail].Rssi1 = Rssi1;
-       Queue->Entry[Tail].Rssi2 = Rssi2;
-       Queue->Entry[Tail].Signal = Signal;
-       Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
+               pCurrTxRate =
+                   (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
 
-       Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
+               if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) {
+                       TrainUp =
+                           (pCurrTxRate->TrainUp +
+                            (pCurrTxRate->TrainUp >> 1));
+                       TrainDown =
+                           (pCurrTxRate->TrainDown +
+                            (pCurrTxRate->TrainDown >> 1));
+               } else {
+                       TrainUp = pCurrTxRate->TrainUp;
+                       TrainDown = pCurrTxRate->TrainDown;
+               }
 
-       if (Msg != NULL)
-       {
-               NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
-       }
+               if (pAd->MacTab.Size == 1) {
+                       /* Update statistic counter */
+                       RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+                       RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
 
-       NdisReleaseSpinLock(&(Queue->Lock));
+                       TxRetransmit = StaTx1.field.TxRetransmit;
+                       TxSuccess = StaTx1.field.TxSuccess;
+                       TxFailCount = TxStaCnt0.field.TxFailCount;
+                       TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
 
-       RT28XX_MLME_HANDLER(pAd);
+                       pAd->RalinkCounters.OneSecTxRetryOkCount +=
+                           StaTx1.field.TxRetransmit;
+                       pAd->RalinkCounters.OneSecTxNoRetryOkCount +=
+                           StaTx1.field.TxSuccess;
+                       pAd->RalinkCounters.OneSecTxFailCount +=
+                           TxStaCnt0.field.TxFailCount;
+                       pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
+                           StaTx1.field.TxSuccess;
+                       pAd->WlanCounters.RetryCount.u.LowPart +=
+                           StaTx1.field.TxRetransmit;
+                       pAd->WlanCounters.FailedCount.u.LowPart +=
+                           TxStaCnt0.field.TxFailCount;
 
-       return TRUE;
-}
+                       if (TxTotalCnt)
+                               TxErrorRatio =
+                                   ((TxRetransmit +
+                                     TxFailCount) * 100) / TxTotalCnt;
+               } else {
+                       TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+                           pEntry->OneSecTxRetryOkCount +
+                           pEntry->OneSecTxFailCount;
 
+                       if (TxTotalCnt)
+                               TxErrorRatio =
+                                   ((pEntry->OneSecTxRetryOkCount +
+                                     pEntry->OneSecTxFailCount) * 100) /
+                                   TxTotalCnt;
+               }
+
+               /* */
+               /* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */
+               /*         (criteria copied from RT2500 for Netopia case) */
+               /* */
+               if (TxTotalCnt <= 12) {
+                       NdisZeroMemory(pAd->DrsCounters.TxQuality,
+                                      sizeof(u16)*
+                                      MAX_STEP_OF_TX_RATE_SWITCH);
+                       NdisZeroMemory(pAd->DrsCounters.PER,
+                                      sizeof(u8)*
+                                      MAX_STEP_OF_TX_RATE_SWITCH);
+
+                       if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1)
+                           && (CurrRateIdx != DownRateIdx)) {
+                               pAd->CommonCfg.TxRateIndex = DownRateIdx;
+                               pAd->DrsCounters.TxQuality[CurrRateIdx] =
+                                   DRS_TX_QUALITY_WORST_BOUND;
+                       } else
+                           if ((pAd->DrsCounters.LastSecTxRateChangeAction ==
+                                2) && (CurrRateIdx != UpRateIdx)) {
+                               pAd->CommonCfg.TxRateIndex = UpRateIdx;
+                       }
 
-/*! \brief      Dequeue a message from the MLME Queue
- *     \param  *Queue    The MLME Queue
- *     \param  *Elem     The message dequeued from MLME Queue
- *     \return  TRUE if the Elem contains something, FALSE otherwise
- *     \pre
- *     \post
+                       DBGPRINT_RAW(RT_DEBUG_TRACE,
+                                    ("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
+                       return;
+               }
 
- IRQL = DISPATCH_LEVEL
+               do {
+                       unsigned long OneSecTxNoRetryOKRationCount;
 
- */
-BOOLEAN MlmeDequeue(
-       IN MLME_QUEUE *Queue,
-       OUT MLME_QUEUE_ELEM **Elem)
-{
-       NdisAcquireSpinLock(&(Queue->Lock));
-       *Elem = &(Queue->Entry[Queue->Head]);
-       Queue->Num--;
-       Queue->Head++;
-       if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
-       {
-               Queue->Head = 0;
-       }
-       NdisReleaseSpinLock(&(Queue->Lock));
-       return TRUE;
-}
+                       if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
+                               ratio = 5;
+                       else
+                               ratio = 4;
 
-// IRQL = DISPATCH_LEVEL
-VOID   MlmeRestartStateMachine(
-       IN      PRTMP_ADAPTER   pAd)
-{
-#ifdef RT2860
-       MLME_QUEUE_ELEM         *Elem = NULL;
-#endif
-       BOOLEAN                         Cancelled;
+                       /* downgrade TX quality if PER >= Rate-Down threshold */
+                       if (TxErrorRatio >= TrainDown) {
+                               pAd->DrsCounters.TxQuality[CurrRateIdx] =
+                                   DRS_TX_QUALITY_WORST_BOUND;
+                       }
 
-       DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
+                       pAd->DrsCounters.PER[CurrRateIdx] =
+                           (u8)TxErrorRatio;
 
-#ifdef RT2860
-       NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-       if(pAd->Mlme.bRunning)
-       {
-               NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-               return;
-       }
-       else
-       {
-               pAd->Mlme.bRunning = TRUE;
-       }
-       NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+                       OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
 
-       // Remove all Mlme queues elements
-       while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
-       {
-               //From message type, determine which state machine I should drive
-               if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
-               {
-                       // free MLME element
-                       Elem->Occupied = FALSE;
-                       Elem->MsgLen = 0;
+                       /* perform DRS - consider TxRate Down first, then rate up. */
+                       if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1)
+                           && (CurrRateIdx != DownRateIdx)) {
+                               if ((pAd->DrsCounters.LastTxOkCount + 2) >=
+                                   OneSecTxNoRetryOKRationCount) {
+                                       pAd->CommonCfg.TxRateIndex =
+                                           DownRateIdx;
+                                       pAd->DrsCounters.
+                                           TxQuality[CurrRateIdx] =
+                                           DRS_TX_QUALITY_WORST_BOUND;
 
-               }
-               else {
-                       DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
-               }
-       }
-#endif /* RT2860 */
+                               }
 
-       {
-               // Cancel all timer events
-               // Be careful to cancel new added timer
-               RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,         &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,   &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,           &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,         &Cancelled);
-               RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,           &Cancelled);
-       }
+                       } else
+                           if ((pAd->DrsCounters.LastSecTxRateChangeAction ==
+                                2) && (CurrRateIdx != UpRateIdx)) {
+                               if ((TxErrorRatio >= 50)
+                                   || (TxErrorRatio >= TrainDown)) {
 
-       // Change back to original channel in case of doing scan
-       AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-       AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+                               } else if ((pAd->DrsCounters.LastTxOkCount + 2)
+                                          >= OneSecTxNoRetryOKRationCount) {
+                                       pAd->CommonCfg.TxRateIndex = UpRateIdx;
+                               }
+                       }
+               } while (FALSE);
 
-       // Resume MSDU which is turned off durning scan
-       RTMPResumeMsduTransmission(pAd);
+               /* if rate-up happen, clear all bad history of all TX rates */
+               if (pAd->CommonCfg.TxRateIndex > CurrRateIdx) {
+                       pAd->DrsCounters.TxRateUpPenalty = 0;
+                       NdisZeroMemory(pAd->DrsCounters.TxQuality,
+                                      sizeof(u16)*
+                                      MAX_STEP_OF_TX_RATE_SWITCH);
+                       NdisZeroMemory(pAd->DrsCounters.PER,
+                                      sizeof(u8)*
+                                      MAX_STEP_OF_TX_RATE_SWITCH);
+                       bTxRateChanged = TRUE;
+               }
+               /* if rate-down happen, only clear DownRate's bad history */
+               else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx) {
+                       DBGPRINT_RAW(RT_DEBUG_TRACE,
+                                    ("QuickDRS: --TX rate from %d to %d \n",
+                                     CurrRateIdx, pAd->CommonCfg.TxRateIndex));
 
-       {
-               // Set all state machines back IDLE
-               pAd->Mlme.CntlMachine.CurrState    = CNTL_IDLE;
-               pAd->Mlme.AssocMachine.CurrState   = ASSOC_IDLE;
-               pAd->Mlme.AuthMachine.CurrState    = AUTH_REQ_IDLE;
-               pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
-               pAd->Mlme.SyncMachine.CurrState    = SYNC_IDLE;
-               pAd->Mlme.ActMachine.CurrState    = ACT_IDLE;
-       }
+                       pAd->DrsCounters.TxRateUpPenalty = 0;   /* no penalty */
+                       pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] =
+                           0;
+                       pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
+                       bTxRateChanged = TRUE;
+               } else {
+                       bTxRateChanged = FALSE;
+               }
 
-#ifdef RT2860
-       // Remove running state
-       NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-       pAd->Mlme.bRunning = FALSE;
-       NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-#endif
+               pNextTxRate =
+                   (struct rt_rtmp_tx_rate_switch *) &
+                   pTable[(pAd->CommonCfg.TxRateIndex + 1) * 5];
+               if (bTxRateChanged && pNextTxRate) {
+                       MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+               }
+       }
 }
 
-/*! \brief     test if the MLME Queue is empty
- *     \param  *Queue    The MLME Queue
- *     \return TRUE if the Queue is empty, FALSE otherwise
- *     \pre
- *     \post
+/*
+       ==========================================================================
+       Description:
+               This routine is executed periodically inside MlmePeriodicExec() after
+               association with an AP.
+               It checks if StaCfg.Psm is consistent with user policy (recorded in
+               StaCfg.WindowsPowerMode). If not, enforce user policy. However,
+               there're some conditions to consider:
+               1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
+                  the time when Mibss==TRUE
+               2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
+                  if outgoing traffic available in TxRing or MgmtRing.
+       Output:
+               1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
 
- IRQL = DISPATCH_LEVEL
      IRQL = DISPATCH_LEVEL
 
+       ==========================================================================
  */
-BOOLEAN MlmeQueueEmpty(
-       IN MLME_QUEUE *Queue)
+void MlmeCheckPsmChange(struct rt_rtmp_adapter *pAd, unsigned long Now32)
 {
-       BOOLEAN Ans;
+       unsigned long PowerMode;
 
-       NdisAcquireSpinLock(&(Queue->Lock));
-       Ans = (Queue->Num == 0);
-       NdisReleaseSpinLock(&(Queue->Lock));
+       /* condition - */
+       /* 1. Psm maybe ON only happen in INFRASTRUCTURE mode */
+       /* 2. user wants either MAX_PSP or FAST_PSP */
+       /* 3. but current psm is not in PWR_SAVE */
+       /* 4. CNTL state machine is not doing SCANning */
+       /* 5. no TX SUCCESS event for the past 1-sec period */
+       PowerMode = pAd->StaCfg.WindowsPowerMode;
 
-       return Ans;
+       if (INFRA_ON(pAd) &&
+           (PowerMode != Ndis802_11PowerModeCAM) &&
+           (pAd->StaCfg.Psm == PWR_ACTIVE) &&
+/*              (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) */
+           (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+           RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)
+           /*&&
+              (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+              (pAd->RalinkCounters.OneSecTxRetryOkCount == 0) */
+           ) {
+               NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
+               pAd->RalinkCounters.RxCountSinceLastNULL = 0;
+               RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
+               if (!
+                   (pAd->CommonCfg.bAPSDCapable
+                    && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) {
+                       RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
+               } else {
+                       RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+               }
+       }
 }
 
-/*! \brief      test if the MLME Queue is full
- *     \param   *Queue          The MLME Queue
- *     \return  TRUE if the Queue is empty, FALSE otherwise
- *     \pre
- *     \post
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeQueueFull(
-       IN MLME_QUEUE *Queue)
+/* IRQL = PASSIVE_LEVEL */
+/* IRQL = DISPATCH_LEVEL */
+void MlmeSetPsmBit(struct rt_rtmp_adapter *pAd, u16 psm)
 {
-       BOOLEAN Ans;
+       AUTO_RSP_CFG_STRUC csr4;
 
-       NdisAcquireSpinLock(&(Queue->Lock));
-       Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
-       NdisReleaseSpinLock(&(Queue->Lock));
+       pAd->StaCfg.Psm = psm;
+       RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+       csr4.field.AckCtsPsmBit = (psm == PWR_SAVE) ? 1 : 0;
+       RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
 
-       return Ans;
+       DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
 }
 
-/*! \brief      The destructor of MLME Queue
- *     \param
- *     \return
- *     \pre
- *     \post
*     \note   Clear Mlme Queue, Set Queue->Num to Zero.
+/*
+       ==========================================================================
+       Description:
+               This routine calculates TxPER, RxPER of the past N-sec period. And
+               according to the calculation result, ChannelQuality is calculated here
              to decide if current AP is still doing the job.
 
- IRQL = PASSIVE_LEVEL
+               If ChannelQuality is not good, a ROAMing attempt may be tried later.
+       Output:
+               StaCfg.ChannelQuality - 0..100
+
+       IRQL = DISPATCH_LEVEL
 
+       NOTE: This routine decide channle quality based on RX CRC error ratio.
+               Caller should make sure a function call to NICUpdateRawCounters(pAd)
+               is performed right before this routine, so that this routine can decide
+               channel quality based on the most up-to-date information
+       ==========================================================================
  */
-VOID MlmeQueueDestroy(
-       IN MLME_QUEUE *pQueue)
+void MlmeCalculateChannelQuality(struct rt_rtmp_adapter *pAd,
+                                struct rt_mac_table_entry *pMacEntry, unsigned long Now32)
 {
-       NdisAcquireSpinLock(&(pQueue->Lock));
-       pQueue->Num  = 0;
-       pQueue->Head = 0;
-       pQueue->Tail = 0;
-       NdisReleaseSpinLock(&(pQueue->Lock));
-       NdisFreeSpinLock(&(pQueue->Lock));
+       unsigned long TxOkCnt, TxCnt, TxPER, TxPRR;
+       unsigned long RxCnt, RxPER;
+       u8 NorRssi;
+       char MaxRssi;
+       struct rt_rssi_sample *pRssiSample = NULL;
+       u32 OneSecTxNoRetryOkCount = 0;
+       u32 OneSecTxRetryOkCount = 0;
+       u32 OneSecTxFailCount = 0;
+       u32 OneSecRxOkCnt = 0;
+       u32 OneSecRxFcsErrCnt = 0;
+       unsigned long ChannelQuality = 0;       /* 0..100, Channel Quality Indication for Roaming */
+       unsigned long BeaconLostTime = pAd->StaCfg.BeaconLostTime;
+
+       if (pAd->OpMode == OPMODE_STA) {
+               pRssiSample = &pAd->StaCfg.RssiSample;
+               OneSecTxNoRetryOkCount =
+                   pAd->RalinkCounters.OneSecTxNoRetryOkCount;
+               OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount;
+               OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount;
+               OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
+               OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
+       }
+
+       MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0,
+                             pRssiSample->LastRssi1, pRssiSample->LastRssi2);
+
+       /* */
+       /* calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics */
+       /* */
+       TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount;
+       TxCnt = TxOkCnt + OneSecTxFailCount;
+       if (TxCnt < 5) {
+               TxPER = 0;
+               TxPRR = 0;
+       } else {
+               TxPER = (OneSecTxFailCount * 100) / TxCnt;
+               TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt;
+       }
+
+       /* */
+       /* calculate RX PER - don't take RxPER into consideration if too few sample */
+       /* */
+       RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt;
+       if (RxCnt < 5)
+               RxPER = 0;
+       else
+               RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt;
+
+       /* */
+       /* decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER */
+       /* */
+       if ((pAd->OpMode == OPMODE_STA) && INFRA_ON(pAd) && (OneSecTxNoRetryOkCount < 2) &&     /* no heavy traffic */
+           ((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32)) {
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n",
+                         BeaconLostTime, TxOkCnt));
+               ChannelQuality = 0;
+       } else {
+               /* Normalize Rssi */
+               if (MaxRssi > -40)
+                       NorRssi = 100;
+               else if (MaxRssi < -90)
+                       NorRssi = 0;
+               else
+                       NorRssi = (MaxRssi + 90) * 2;
+
+               /* ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER        (RSSI 0..100), (TxPER 100..0), (RxPER 100..0) */
+               ChannelQuality = (RSSI_WEIGHTING * NorRssi +
+                                 TX_WEIGHTING * (100 - TxPRR) +
+                                 RX_WEIGHTING * (100 - RxPER)) / 100;
+       }
+
+       if (pAd->OpMode == OPMODE_STA)
+               pAd->Mlme.ChannelQuality =
+                   (ChannelQuality > 100) ? 100 : ChannelQuality;
+
 }
 
-/*! \brief      To substitute the message type if the message is coming from external
- *     \param  pFrame             The frame received
- *     \param  *Machine           The state machine
- *     \param  *MsgType           the message type for the state machine
- *     \return TRUE if the substitution is successful, FALSE otherwise
- *     \pre
- *     \post
+/* IRQL = DISPATCH_LEVEL */
+void MlmeSetTxPreamble(struct rt_rtmp_adapter *pAd, u16 TxPreamble)
+{
+       AUTO_RSP_CFG_STRUC csr4;
 
- IRQL = DISPATCH_LEVEL
+       /* */
+       /* Always use Long preamble before verifiation short preamble functionality works well. */
+       /* Todo: remove the following line if short preamble functionality works */
+       /* */
+       /*TxPreamble = Rt802_11PreambleLong; */
+
+       RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+       if (TxPreamble == Rt802_11PreambleLong) {
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("MlmeSetTxPreamble (= long PREAMBLE)\n"));
+               OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+               csr4.field.AutoResponderPreamble = 0;
+       } else {
+               /* NOTE: 1Mbps should always use long preamble */
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("MlmeSetTxPreamble (= short PREAMBLE)\n"));
+               OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+               csr4.field.AutoResponderPreamble = 1;
+       }
+
+       RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
+}
 
+/*
+    ==========================================================================
+    Description:
+        Update basic rate bitmap
+    ==========================================================================
  */
-BOOLEAN MsgTypeSubst(
-       IN PRTMP_ADAPTER  pAd,
-       IN PFRAME_802_11 pFrame,
-       OUT INT *Machine,
-       OUT INT *MsgType)
+
+void UpdateBasicRateBitmap(struct rt_rtmp_adapter *pAdapter)
+{
+       int i, j;
+       /* 1  2  5.5, 11,  6,  9, 12, 18, 24, 36, 48,  54 */
+       u8 rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
+       u8 *sup_p = pAdapter->CommonCfg.SupRate;
+       u8 *ext_p = pAdapter->CommonCfg.ExtRate;
+       unsigned long bitmap = pAdapter->CommonCfg.BasicRateBitmap;
+
+       /* if A mode, always use fix BasicRateBitMap */
+       /*if (pAdapter->CommonCfg.Channel == PHY_11A) */
+       if (pAdapter->CommonCfg.Channel > 14)
+               pAdapter->CommonCfg.BasicRateBitmap = 0x150;    /* 6, 12, 24M */
+       /* End of if */
+
+       if (pAdapter->CommonCfg.BasicRateBitmap > 4095) {
+               /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
+               return;
+       }
+       /* End of if */
+       for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
+               sup_p[i] &= 0x7f;
+               ext_p[i] &= 0x7f;
+       }                       /* End of for */
+
+       for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
+               if (bitmap & (1 << i)) {
+                       for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) {
+                               if (sup_p[j] == rate[i])
+                                       sup_p[j] |= 0x80;
+                               /* End of if */
+                       }       /* End of for */
+
+                       for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) {
+                               if (ext_p[j] == rate[i])
+                                       ext_p[j] |= 0x80;
+                               /* End of if */
+                       }       /* End of for */
+               }               /* End of if */
+       }                       /* End of for */
+}                              /* End of UpdateBasicRateBitmap */
+
+/* IRQL = PASSIVE_LEVEL */
+/* IRQL = DISPATCH_LEVEL */
+/* bLinkUp is to identify the inital link speed. */
+/* TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps. */
+void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd, IN BOOLEAN bLinkUp, u8 apidx)
 {
-       USHORT  Seq;
-       UCHAR   EAPType;
-       PUCHAR  pData;
+       int i, num;
+       u8 Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
+       u8 MinSupport = RATE_54;
+       unsigned long BasicRateBitmap = 0;
+       u8 CurrBasicRate = RATE_1;
+       u8 *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
+       PHTTRANSMIT_SETTING pHtPhy = NULL;
+       PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+       PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+       BOOLEAN *auto_rate_cur_p;
+       u8 HtMcs = MCS_AUTO;
+
+       /* find max desired rate */
+       UpdateBasicRateBitmap(pAd);
 
-       // Pointer to start of data frames including SNAP header
-       pData = (PUCHAR) pFrame + LENGTH_802_11;
+       num = 0;
+       auto_rate_cur_p = NULL;
+       for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
+               switch (pAd->CommonCfg.DesireRate[i] & 0x7f) {
+               case 2:
+                       Rate = RATE_1;
+                       num++;
+                       break;
+               case 4:
+                       Rate = RATE_2;
+                       num++;
+                       break;
+               case 11:
+                       Rate = RATE_5_5;
+                       num++;
+                       break;
+               case 22:
+                       Rate = RATE_11;
+                       num++;
+                       break;
+               case 12:
+                       Rate = RATE_6;
+                       num++;
+                       break;
+               case 18:
+                       Rate = RATE_9;
+                       num++;
+                       break;
+               case 24:
+                       Rate = RATE_12;
+                       num++;
+                       break;
+               case 36:
+                       Rate = RATE_18;
+                       num++;
+                       break;
+               case 48:
+                       Rate = RATE_24;
+                       num++;
+                       break;
+               case 72:
+                       Rate = RATE_36;
+                       num++;
+                       break;
+               case 96:
+                       Rate = RATE_48;
+                       num++;
+                       break;
+               case 108:
+                       Rate = RATE_54;
+                       num++;
+                       break;
+                       /*default: Rate = RATE_1;   break; */
+               }
+               if (MaxDesire < Rate)
+                       MaxDesire = Rate;
+       }
 
-       // The only data type will pass to this function is EAPOL frame
-       if (pFrame->Hdr.FC.Type == BTYPE_DATA)
+/*=========================================================================== */
+/*=========================================================================== */
        {
-               if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
-               {
-                       // Cisco Aironet SNAP header
-                       *Machine = AIRONET_STATE_MACHINE;
-                       *MsgType = MT2_AIRONET_MSG;
-                       return (TRUE);
+               pHtPhy = &pAd->StaCfg.HTPhyMode;
+               pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+               pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
+
+               auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+               HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+
+               if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
+                   (pAd->CommonCfg.PhyMode == PHY_11B) &&
+                   (MaxDesire > RATE_11)) {
+                       MaxDesire = RATE_11;
                }
-               {
-                       *Machine = WPA_PSK_STATE_MACHINE;
-                       EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
-                       return(WpaMsgTypeSubst(EAPType, MsgType));
+       }
+
+       pAd->CommonCfg.MaxDesiredRate = MaxDesire;
+       pMinHtPhy->word = 0;
+       pMaxHtPhy->word = 0;
+       pHtPhy->word = 0;
+
+       /* Auto rate switching is enabled only if more than one DESIRED RATES are */
+       /* specified; otherwise disabled */
+       if (num <= 1) {
+               /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
+               /*pAd->CommonCfg.bAutoTxRateSwitch      = FALSE; */
+               *auto_rate_cur_p = FALSE;
+       } else {
+               /*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
+               /*pAd->CommonCfg.bAutoTxRateSwitch      = TRUE; */
+               *auto_rate_cur_p = TRUE;
+       }
+
+       if (HtMcs != MCS_AUTO) {
+               /*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
+               /*pAd->CommonCfg.bAutoTxRateSwitch      = FALSE; */
+               *auto_rate_cur_p = FALSE;
+       } else {
+               /*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
+               /*pAd->CommonCfg.bAutoTxRateSwitch      = TRUE; */
+               *auto_rate_cur_p = TRUE;
+       }
+
+       if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) {
+               pSupRate = &pAd->StaActive.SupRate[0];
+               pExtRate = &pAd->StaActive.ExtRate[0];
+               SupRateLen = pAd->StaActive.SupRateLen;
+               ExtRateLen = pAd->StaActive.ExtRateLen;
+       } else {
+               pSupRate = &pAd->CommonCfg.SupRate[0];
+               pExtRate = &pAd->CommonCfg.ExtRate[0];
+               SupRateLen = pAd->CommonCfg.SupRateLen;
+               ExtRateLen = pAd->CommonCfg.ExtRateLen;
+       }
+
+       /* find max supported rate */
+       for (i = 0; i < SupRateLen; i++) {
+               switch (pSupRate[i] & 0x7f) {
+               case 2:
+                       Rate = RATE_1;
+                       if (pSupRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0001;
+                       break;
+               case 4:
+                       Rate = RATE_2;
+                       if (pSupRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0002;
+                       break;
+               case 11:
+                       Rate = RATE_5_5;
+                       if (pSupRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0004;
+                       break;
+               case 22:
+                       Rate = RATE_11;
+                       if (pSupRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0008;
+                       break;
+               case 12:
+                       Rate = RATE_6;  /*if (pSupRate[i] & 0x80) */
+                       BasicRateBitmap |= 0x0010;
+                       break;
+               case 18:
+                       Rate = RATE_9;
+                       if (pSupRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0020;
+                       break;
+               case 24:
+                       Rate = RATE_12; /*if (pSupRate[i] & 0x80) */
+                       BasicRateBitmap |= 0x0040;
+                       break;
+               case 36:
+                       Rate = RATE_18;
+                       if (pSupRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0080;
+                       break;
+               case 48:
+                       Rate = RATE_24; /*if (pSupRate[i] & 0x80) */
+                       BasicRateBitmap |= 0x0100;
+                       break;
+               case 72:
+                       Rate = RATE_36;
+                       if (pSupRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0200;
+                       break;
+               case 96:
+                       Rate = RATE_48;
+                       if (pSupRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0400;
+                       break;
+               case 108:
+                       Rate = RATE_54;
+                       if (pSupRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0800;
+                       break;
+               default:
+                       Rate = RATE_1;
+                       break;
                }
+               if (MaxSupport < Rate)
+                       MaxSupport = Rate;
+
+               if (MinSupport > Rate)
+                       MinSupport = Rate;
        }
 
-       switch (pFrame->Hdr.FC.SubType)
-       {
-               case SUBTYPE_ASSOC_REQ:
-                       *Machine = ASSOC_STATE_MACHINE;
-                       *MsgType = MT2_PEER_ASSOC_REQ;
+       for (i = 0; i < ExtRateLen; i++) {
+               switch (pExtRate[i] & 0x7f) {
+               case 2:
+                       Rate = RATE_1;
+                       if (pExtRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0001;
                        break;
-               case SUBTYPE_ASSOC_RSP:
-                       *Machine = ASSOC_STATE_MACHINE;
-                       *MsgType = MT2_PEER_ASSOC_RSP;
+               case 4:
+                       Rate = RATE_2;
+                       if (pExtRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0002;
                        break;
-               case SUBTYPE_REASSOC_REQ:
-                       *Machine = ASSOC_STATE_MACHINE;
-                       *MsgType = MT2_PEER_REASSOC_REQ;
+               case 11:
+                       Rate = RATE_5_5;
+                       if (pExtRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0004;
                        break;
-               case SUBTYPE_REASSOC_RSP:
-                       *Machine = ASSOC_STATE_MACHINE;
-                       *MsgType = MT2_PEER_REASSOC_RSP;
+               case 22:
+                       Rate = RATE_11;
+                       if (pExtRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0008;
                        break;
-               case SUBTYPE_PROBE_REQ:
-                       *Machine = SYNC_STATE_MACHINE;
-                       *MsgType = MT2_PEER_PROBE_REQ;
+               case 12:
+                       Rate = RATE_6;  /*if (pExtRate[i] & 0x80) */
+                       BasicRateBitmap |= 0x0010;
                        break;
-               case SUBTYPE_PROBE_RSP:
-                       *Machine = SYNC_STATE_MACHINE;
-                       *MsgType = MT2_PEER_PROBE_RSP;
+               case 18:
+                       Rate = RATE_9;
+                       if (pExtRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0020;
                        break;
-               case SUBTYPE_BEACON:
-                       *Machine = SYNC_STATE_MACHINE;
-                       *MsgType = MT2_PEER_BEACON;
+               case 24:
+                       Rate = RATE_12; /*if (pExtRate[i] & 0x80) */
+                       BasicRateBitmap |= 0x0040;
                        break;
-               case SUBTYPE_ATIM:
-                       *Machine = SYNC_STATE_MACHINE;
-                       *MsgType = MT2_PEER_ATIM;
+               case 36:
+                       Rate = RATE_18;
+                       if (pExtRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0080;
                        break;
-               case SUBTYPE_DISASSOC:
-                       *Machine = ASSOC_STATE_MACHINE;
-                       *MsgType = MT2_PEER_DISASSOC_REQ;
+               case 48:
+                       Rate = RATE_24; /*if (pExtRate[i] & 0x80) */
+                       BasicRateBitmap |= 0x0100;
                        break;
-               case SUBTYPE_AUTH:
-                       // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
-                       NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
-                       if (Seq == 1 || Seq == 3)
-                       {
-                               *Machine = AUTH_RSP_STATE_MACHINE;
-                               *MsgType = MT2_PEER_AUTH_ODD;
-                       }
-                       else if (Seq == 2 || Seq == 4)
-                       {
-                               *Machine = AUTH_STATE_MACHINE;
-                               *MsgType = MT2_PEER_AUTH_EVEN;
-                       }
-                       else
-                       {
-                               return FALSE;
-                       }
+               case 72:
+                       Rate = RATE_36;
+                       if (pExtRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0200;
                        break;
-               case SUBTYPE_DEAUTH:
-                       *Machine = AUTH_RSP_STATE_MACHINE;
-                       *MsgType = MT2_PEER_DEAUTH;
+               case 96:
+                       Rate = RATE_48;
+                       if (pExtRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0400;
                        break;
-               case SUBTYPE_ACTION:
-                       *Machine = ACTION_STATE_MACHINE;
-                       //  Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
-                       if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
-                       {
-                               *MsgType = MT2_ACT_INVALID;
-                       }
-                       else
-                       {
-                               *MsgType = (pFrame->Octet[0]&0x7F);
-                       }
+               case 108:
+                       Rate = RATE_54;
+                       if (pExtRate[i] & 0x80)
+                               BasicRateBitmap |= 0x0800;
                        break;
                default:
-                       return FALSE;
+                       Rate = RATE_1;
                        break;
+               }
+               if (MaxSupport < Rate)
+                       MaxSupport = Rate;
+
+               if (MinSupport > Rate)
+                       MinSupport = Rate;
        }
 
-       return TRUE;
-}
+       RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
 
-// ===========================================================================================
-// state_machine.c
-// ===========================================================================================
+       /* bug fix */
+       /* pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap; */
 
-/*! \brief Initialize the state machine.
- *     \param *S                       pointer to the state machine
- *     \param  Trans           State machine transition function
- *     \param  StNr            number of states
- *     \param  MsgNr           number of messages
- *     \param  DefFunc         default function, when there is invalid state/message combination
- *     \param  InitState       initial state of the state machine
- *     \param  Base            StateMachine base, internal use only
- *     \pre p_sm should be a legal pointer
- *     \post
+       /* calculate the exptected ACK rate for each TX rate. This info is used to caculate */
+       /* the DURATION field of outgoing uniicast DATA/MGMT frame */
+       for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
+               if (BasicRateBitmap & (0x01 << i))
+                       CurrBasicRate = (u8)i;
+               pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
+       }
 
- IRQL = PASSIVE_LEVEL
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n",
+                 RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
+       /* max tx rate = min {max desire rate, max supported rate} */
+       if (MaxSupport < MaxDesire)
+               pAd->CommonCfg.MaxTxRate = MaxSupport;
+       else
+               pAd->CommonCfg.MaxTxRate = MaxDesire;
 
- */
-VOID StateMachineInit(
-       IN STATE_MACHINE *S,
-       IN STATE_MACHINE_FUNC Trans[],
-       IN ULONG StNr,
-       IN ULONG MsgNr,
-       IN STATE_MACHINE_FUNC DefFunc,
-       IN ULONG InitState,
-       IN ULONG Base)
-{
-       ULONG i, j;
+       pAd->CommonCfg.MinTxRate = MinSupport;
+       /* 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success */
+       /* ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending */
+       /* on average RSSI */
+       /*       1. RSSI >= -70db, start at 54 Mbps (short distance) */
+       /*       2. -70 > RSSI >= -75, start at 24 Mbps (mid distance) */
+       /*       3. -75 > RSSI, start at 11 Mbps (long distance) */
+       if (*auto_rate_cur_p) {
+               short dbm = 0;
 
-       // set number of states and messages
-       S->NrState = StNr;
-       S->NrMsg   = MsgNr;
-       S->Base    = Base;
+               dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
+
+               if (bLinkUp == TRUE)
+                       pAd->CommonCfg.TxRate = RATE_24;
+               else
+                       pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
 
-       S->TransFunc  = Trans;
+               if (dbm < -75)
+                       pAd->CommonCfg.TxRate = RATE_11;
+               else if (dbm < -70)
+                       pAd->CommonCfg.TxRate = RATE_24;
 
-       // init all state transition to default function
-       for (i = 0; i < StNr; i++)
-       {
-               for (j = 0; j < MsgNr; j++)
-               {
-                       S->TransFunc[i * MsgNr + j] = DefFunc;
+               /* should never exceed MaxTxRate (consider 11B-only mode) */
+               if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
+                       pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+
+               pAd->CommonCfg.TxRateIndex = 0;
+       } else {
+               pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+               pHtPhy->field.MCS =
+                   (pAd->CommonCfg.MaxTxRate >
+                    3) ? (pAd->CommonCfg.MaxTxRate -
+                          4) : pAd->CommonCfg.MaxTxRate;
+               pHtPhy->field.MODE =
+                   (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
+
+               pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC =
+                   pHtPhy->field.STBC;
+               pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI =
+                   pHtPhy->field.ShortGI;
+               pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS =
+                   pHtPhy->field.MCS;
+               pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE =
+                   pHtPhy->field.MODE;
+       }
+
+       if (pAd->CommonCfg.TxRate <= RATE_11) {
+               pMaxHtPhy->field.MODE = MODE_CCK;
+               pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
+               pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
+       } else {
+               pMaxHtPhy->field.MODE = MODE_OFDM;
+               pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
+               if (pAd->CommonCfg.MinTxRate >= RATE_6
+                   && (pAd->CommonCfg.MinTxRate <= RATE_54)) {
+                       pMinHtPhy->field.MCS =
+                           OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];
+               } else {
+                       pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
+               }
+       }
+
+       pHtPhy->word = (pMaxHtPhy->word);
+       if (bLinkUp && (pAd->OpMode == OPMODE_STA)) {
+               pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
+               pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word =
+                   pMaxHtPhy->word;
+               pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word =
+                   pMinHtPhy->word;
+       } else {
+               switch (pAd->CommonCfg.PhyMode) {
+               case PHY_11BG_MIXED:
+               case PHY_11B:
+               case PHY_11BGN_MIXED:
+                       pAd->CommonCfg.MlmeRate = RATE_1;
+                       pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+                       pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+
+/*#ifdef        WIFI_TEST */
+                       pAd->CommonCfg.RtsRate = RATE_11;
+/*#else */
+/*                              pAd->CommonCfg.RtsRate = RATE_1; */
+/*#endif */
+                       break;
+               case PHY_11G:
+               case PHY_11A:
+               case PHY_11AGN_MIXED:
+               case PHY_11GN_MIXED:
+               case PHY_11N_2_4G:
+               case PHY_11AN_MIXED:
+               case PHY_11N_5G:
+                       pAd->CommonCfg.MlmeRate = RATE_6;
+                       pAd->CommonCfg.RtsRate = RATE_6;
+                       pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+                       pAd->CommonCfg.MlmeTransmit.field.MCS =
+                           OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+                       break;
+               case PHY_11ABG_MIXED:
+               case PHY_11ABGN_MIXED:
+                       if (pAd->CommonCfg.Channel <= 14) {
+                               pAd->CommonCfg.MlmeRate = RATE_1;
+                               pAd->CommonCfg.RtsRate = RATE_1;
+                               pAd->CommonCfg.MlmeTransmit.field.MODE =
+                                   MODE_CCK;
+                               pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+                       } else {
+                               pAd->CommonCfg.MlmeRate = RATE_6;
+                               pAd->CommonCfg.RtsRate = RATE_6;
+                               pAd->CommonCfg.MlmeTransmit.field.MODE =
+                                   MODE_OFDM;
+                               pAd->CommonCfg.MlmeTransmit.field.MCS =
+                                   OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+                       }
+                       break;
+               default:        /* error */
+                       pAd->CommonCfg.MlmeRate = RATE_6;
+                       pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+                       pAd->CommonCfg.MlmeTransmit.field.MCS =
+                           OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+                       pAd->CommonCfg.RtsRate = RATE_1;
+                       break;
                }
+               /* */
+               /* Keep Basic Mlme Rate. */
+               /* */
+               pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word =
+                   pAd->CommonCfg.MlmeTransmit.word;
+               if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
+                       pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
+                           OfdmRateToRxwiMCS[RATE_24];
+               else
+                       pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
+                           RATE_1;
+               pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
        }
 
-       // set the starting state
-       S->CurrState = InitState;
+       DBGPRINT(RT_DEBUG_TRACE,
+                (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
+                 RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport],
+                 RateIdToMbps[pAd->CommonCfg.MaxTxRate],
+                 RateIdToMbps[pAd->CommonCfg.MinTxRate],
+                 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) */
+                 *auto_rate_cur_p));
+       DBGPRINT(RT_DEBUG_TRACE,
+                (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
+                 RateIdToMbps[pAd->CommonCfg.TxRate],
+                 RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
+                 pAd->CommonCfg.MlmeTransmit.word,
+                 pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word,
+                 pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word,
+                 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word));
 }
 
-/*! \brief This function fills in the function pointer into the cell in the state machine
- *     \param *S       pointer to the state machine
- *     \param St       state
- *     \param Msg      incoming message
- *     \param f        the function to be executed when (state, message) combination occurs at the state machine
- *     \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
- *     \post
+/*
+       ==========================================================================
+       Description:
+               This function update HT Rate setting.
+               Input Wcid value is valid for 2 case :
+               1. it's used for Station in infra mode that copy AP rate to Mactable.
+               2. OR Station   in adhoc mode to copy peer's HT rate to Mactable.
 
- IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
 
+       ==========================================================================
  */
-VOID StateMachineSetAction(
-       IN STATE_MACHINE *S,
-       IN ULONG St,
-       IN ULONG Msg,
-       IN STATE_MACHINE_FUNC Func)
+void MlmeUpdateHtTxRates(struct rt_rtmp_adapter *pAd, u8 apidx)
 {
-       ULONG MsgIdx;
+       u8 StbcMcs;             /*j, StbcMcs, bitmask; */
+       char i;                 /* 3*3 */
+       struct rt_ht_capability *pRtHtCap = NULL;
+       struct rt_ht_phy_info *pActiveHtPhy = NULL;
+       unsigned long BasicMCS;
+       u8 j, bitmask;
+       struct rt_ht_phy_info *pDesireHtPhy = NULL;
+       PHTTRANSMIT_SETTING pHtPhy = NULL;
+       PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+       PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+       BOOLEAN *auto_rate_cur_p;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates===> \n"));
 
-       MsgIdx = Msg - S->Base;
+       auto_rate_cur_p = NULL;
 
-       if (St < S->NrState && MsgIdx < S->NrMsg)
        {
-               // boundary checking before setting the action
-               S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
-       }
-}
-
-/*! \brief      This function does the state transition
- *     \param   *Adapter the NIC adapter pointer
- *     \param   *S       the state machine
- *     \param   *Elem    the message to be executed
- *     \return   None
+               pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+               pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+               pHtPhy = &pAd->StaCfg.HTPhyMode;
+               pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+               pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
 
- IRQL = DISPATCH_LEVEL
-
- */
-VOID StateMachinePerformAction(
-       IN      PRTMP_ADAPTER   pAd,
-       IN STATE_MACHINE *S,
-       IN MLME_QUEUE_ELEM *Elem)
-{
-       (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
-}
-
-/*
-       ==========================================================================
-       Description:
-               The drop function, when machine executes this, the message is simply
-               ignored. This function does nothing, the message is freed in
-               StateMachinePerformAction()
-       ==========================================================================
- */
-VOID Drop(
-       IN PRTMP_ADAPTER pAd,
-       IN MLME_QUEUE_ELEM *Elem)
-{
-}
+               auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+       }
 
-// ===========================================================================================
-// lfsr.c
-// ===========================================================================================
+       if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) {
+               if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+                       return;
 
-/*
-       ==========================================================================
-       Description:
+               pRtHtCap = &pAd->StaActive.SupportedHtPhy;
+               pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
+               StbcMcs = (u8)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
+               BasicMCS =
+                   pAd->MlmeAux.AddHtInfo.MCSSet[0] +
+                   (pAd->MlmeAux.AddHtInfo.MCSSet[1] << 8) + (StbcMcs << 16);
+               if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC)
+                   && (pAd->Antenna.field.TxPath == 2))
+                       pMaxHtPhy->field.STBC = STBC_USE;
+               else
+                       pMaxHtPhy->field.STBC = STBC_NONE;
+       } else {
+               if (pDesireHtPhy->bHtEnable == FALSE)
+                       return;
 
-       IRQL = PASSIVE_LEVEL
+               pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
+               StbcMcs = (u8)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
+               BasicMCS =
+                   pAd->CommonCfg.AddHTInfo.MCSSet[0] +
+                   (pAd->CommonCfg.AddHTInfo.MCSSet[1] << 8) + (StbcMcs << 16);
+               if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC)
+                   && (pAd->Antenna.field.TxPath == 2))
+                       pMaxHtPhy->field.STBC = STBC_USE;
+               else
+                       pMaxHtPhy->field.STBC = STBC_NONE;
+       }
 
-       ==========================================================================
- */
-VOID LfsrInit(
-       IN PRTMP_ADAPTER pAd,
-       IN ULONG Seed)
-{
-       if (Seed == 0)
-               pAd->Mlme.ShiftReg = 1;
+       /* Decide MAX ht rate. */
+       if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+               pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
        else
-               pAd->Mlme.ShiftReg = Seed;
-}
+               pMaxHtPhy->field.MODE = MODE_HTMIX;
 
-/*
-       ==========================================================================
-       Description:
-       ==========================================================================
- */
-UCHAR RandomByte(
-       IN PRTMP_ADAPTER pAd)
-{
-       ULONG i;
-       UCHAR R, Result;
+       if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth)
+           && (pRtHtCap->ChannelWidth))
+               pMaxHtPhy->field.BW = BW_40;
+       else
+               pMaxHtPhy->field.BW = BW_20;
 
-       R = 0;
+       if (pMaxHtPhy->field.BW == BW_20)
+               pMaxHtPhy->field.ShortGI =
+                   (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->
+                    ShortGIfor20);
+       else
+               pMaxHtPhy->field.ShortGI =
+                   (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->
+                    ShortGIfor40);
 
-       if (pAd->Mlme.ShiftReg == 0)
-       NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
+       if (pDesireHtPhy->MCSSet[4] != 0) {
+               pMaxHtPhy->field.MCS = 32;
+       }
 
-       for (i = 0; i < 8; i++)
+       for (i = 23; i >= 0; i--)       /* 3*3 */
        {
-               if (pAd->Mlme.ShiftReg & 0x00000001)
-               {
-                       pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
-                       Result = 1;
-               }
-               else
-               {
-                       pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
-                       Result = 0;
+               j = i / 8;
+               bitmask = (1 << (i - (j * 8)));
+
+               if ((pActiveHtPhy->MCSSet[j] & bitmask)
+                   && (pDesireHtPhy->MCSSet[j] & bitmask)) {
+                       pMaxHtPhy->field.MCS = i;
+                       break;
                }
-               R = (R << 1) | Result;
+
+               if (i == 0)
+                       break;
        }
 
-       return R;
-}
+       /* Copy MIN ht rate.  rt2860??? */
+       pMinHtPhy->field.BW = BW_20;
+       pMinHtPhy->field.MCS = 0;
+       pMinHtPhy->field.STBC = 0;
+       pMinHtPhy->field.ShortGI = 0;
+       /*If STA assigns fixed rate. update to fixed here. */
+       if ((pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff)) {
+               if (pDesireHtPhy->MCSSet[4] != 0) {
+                       pMaxHtPhy->field.MCS = 32;
+                       pMinHtPhy->field.MCS = 32;
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",
+                                 pMinHtPhy->field.MCS));
+               }
 
-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)
+               for (i = 23; (char)i >= 0; i--) /* 3*3 */
                {
-                       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;
-                                       }
-                               }
+                       j = i / 8;
+                       bitmask = (1 << (i - (j * 8)));
+                       if ((pDesireHtPhy->MCSSet[j] & bitmask)
+                           && (pActiveHtPhy->MCSSet[j] & bitmask)) {
+                               pMaxHtPhy->field.MCS = i;
+                               pMinHtPhy->field.MCS = i;
                                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));
-                                               }
-                                       }
-                               }
+                       }
+                       if (i == 0)
                                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);
-}
+       /* Decide ht rate */
+       pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
+       pHtPhy->field.BW = pMaxHtPhy->field.BW;
+       pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
+       pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
+       pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
 
-/*
-       ========================================================================
+       /* use default now. rt2860 */
+       if (pDesireHtPhy->MCSSet[0] != 0xff)
+               *auto_rate_cur_p = FALSE;
+       else
+               *auto_rate_cur_p = TRUE;
 
-       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)
+       DBGPRINT(RT_DEBUG_TRACE,
+                (" MlmeUpdateHtTxRates<---.AMsduSize = %d  \n",
+                 pAd->CommonCfg.DesiredHtPhy.AmsduSize));
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d,  \n",
+                 pActiveHtPhy->MCSSet[0], pHtPhy->field.MCS, pHtPhy->field.BW,
+                 pHtPhy->field.ShortGI, pHtPhy->field.MODE));
+       DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates<=== \n"));
+}
+
+void BATableInit(struct rt_rtmp_adapter *pAd, struct rt_ba_table *Tab)
 {
-       PROT_CFG_STRUC  ProtCfg, ProtCfg4;
-       UINT32 Protect[6];
-       USHORT                  offset;
-       UCHAR                   i;
-       UINT32 MacReg = 0;
+       int i;
 
-       if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
-       {
-               return;
+       Tab->numAsOriginator = 0;
+       Tab->numAsRecipient = 0;
+       Tab->numDoneOriginator = 0;
+       NdisAllocateSpinLock(&pAd->BATabLock);
+       for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
+               Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
+               NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
        }
-
-       if (pAd->BATable.numAsOriginator)
-       {
-               //
-               // enable the RTS/CTS to avoid channel collision
-               //
-               SetMask = ALLN_SETPROTECT;
-               OperationMode = 8;
+       for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++) {
+               Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
        }
+}
 
-       // 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;
-       }
-       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;
-       }
+/* IRQL = DISPATCH_LEVEL */
+void MlmeRadioOff(struct rt_rtmp_adapter *pAd)
+{
+       RTMP_MLME_RADIO_OFF(pAd);
+}
 
-       // 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;
+/* IRQL = DISPATCH_LEVEL */
+void MlmeRadioOn(struct rt_rtmp_adapter *pAd)
+{
+       RTMP_MLME_RADIO_ON(pAd);
+}
 
-                       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;
+/* =========================================================================================== */
+/* bss_table.c */
+/* =========================================================================================== */
 
-                       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;
+/*! \brief initialize BSS table
+ *     \param p_tab pointer to the table
+ *     \return none
+ *     \pre
+ *     \post
 
-                               pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
-                               break;
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
 
-                       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;
+ */
+void BssTableInit(struct rt_bss_table *Tab)
+{
+       int i;
 
-                       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;
-               }
+       Tab->BssNr = 0;
+       Tab->BssOverlapNr = 0;
+       for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) {
+               NdisZeroMemory(&Tab->BssEntry[i], sizeof(struct rt_bss_entry));
+               Tab->BssEntry[i].Rssi = -127;   /* initial the rssi as a minimum value */
        }
+}
 
-       offset = CCK_PROT_CFG;
-       for (i = 0;i < 6;i++)
-       {
-               if ((SetMask & (1<< i)))
-               {
-                       RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+/*! \brief search the BSS table by SSID
+ *     \param p_tab pointer to the bss table
+ *     \param ssid SSID string
+ *     \return index of the table, BSS_NOT_FOUND if not in the table
+ *     \pre
+ *     \post
+ *     \note search by sequential search
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+unsigned long BssTableSearch(struct rt_bss_table *Tab, u8 *pBssid, u8 Channel)
+{
+       u8 i;
+
+       for (i = 0; i < Tab->BssNr; i++) {
+               /* */
+               /* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */
+               /* We should distinguish this case. */
+               /* */
+               if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+                    ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+                   MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)) {
+                       return i;
                }
        }
+       return (unsigned long)BSS_NOT_FOUND;
 }
 
-#ifdef RT2870
-/*
-       ==========================================================================
-       Description:
+unsigned long BssSsidTableSearch(struct rt_bss_table *Tab,
+                        u8 *pBssid,
+                        u8 *pSsid, u8 SsidLen, u8 Channel)
+{
+       u8 i;
 
-       Load RF normal operation-mode setup
+       for (i = 0; i < Tab->BssNr; i++) {
+               /* */
+               /* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */
+               /* We should distinguish this case. */
+               /* */
+               if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+                    ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+                   MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
+                   SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid,
+                              Tab->BssEntry[i].SsidLen)) {
+                       return i;
+               }
+       }
+       return (unsigned long)BSS_NOT_FOUND;
+}
 
-       ==========================================================================
- */
-VOID RT30xxLoadRFNormalModeSetup(
-       IN PRTMP_ADAPTER        pAd)
+unsigned long BssTableSearchWithSSID(struct rt_bss_table *Tab,
+                            u8 *Bssid,
+                            u8 *pSsid,
+                            u8 SsidLen, u8 Channel)
 {
-       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);
-
-       // 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;
+       u8 i;
+
+       for (i = 0; i < Tab->BssNr; i++) {
+               if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+                    ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+                   MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
+                   (SSID_EQUAL
+                    (pSsid, SsidLen, Tab->BssEntry[i].Ssid,
+                     Tab->BssEntry[i].SsidLen)
+                    || (NdisEqualMemory(pSsid, ZeroSsid, SsidLen))
+                    ||
+                    (NdisEqualMemory
+                     (Tab->BssEntry[i].Ssid, ZeroSsid,
+                      Tab->BssEntry[i].SsidLen)))) {
+                       return i;
+               }
        }
-       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);
-
-       // LDORF_VC, RF R27 register Bit 2 to 0
-       RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-       if ((pAd->MACVersion & 0xffff) < 0x0211)
-               RFValue = (RFValue & (~0x77)) | 0x3;
-       else
-               RFValue = (RFValue & (~0x77));
-       RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-       /* end johnli */
+       return (unsigned long)BSS_NOT_FOUND;
 }
 
-/*
-       ==========================================================================
-       Description:
+unsigned long BssSsidTableSearchBySSID(struct rt_bss_table *Tab,
+                              u8 *pSsid, u8 SsidLen)
+{
+       u8 i;
 
-       Load RF sleep-mode setup
+       for (i = 0; i < Tab->BssNr; i++) {
+               if (SSID_EQUAL
+                   (pSsid, SsidLen, Tab->BssEntry[i].Ssid,
+                    Tab->BssEntry[i].SsidLen)) {
+                       return i;
+               }
+       }
+       return (unsigned long)BSS_NOT_FOUND;
+}
 
-       ==========================================================================
- */
-VOID RT30xxLoadRFSleepModeSetup(
-       IN PRTMP_ADAPTER        pAd)
+/* IRQL = DISPATCH_LEVEL */
+void BssTableDeleteEntry(struct rt_bss_table *Tab,
+                        u8 *pBssid, u8 Channel)
 {
-       UCHAR RFValue;
-       UINT32 MACValue;
-
-       // 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);
-
-       // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
-       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);
-}
+       u8 i, j;
 
-/*
-       ==========================================================================
-       Description:
+       for (i = 0; i < Tab->BssNr; i++) {
+               if ((Tab->BssEntry[i].Channel == Channel) &&
+                   (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))) {
+                       for (j = i; j < Tab->BssNr - 1; j++) {
+                               NdisMoveMemory(&(Tab->BssEntry[j]),
+                                              &(Tab->BssEntry[j + 1]),
+                                              sizeof(struct rt_bss_entry));
+                       }
+                       NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]),
+                                      sizeof(struct rt_bss_entry));
+                       Tab->BssNr -= 1;
+                       return;
+               }
+       }
+}
 
-       Reverse RF sleep-mode setup
+/*
+       ========================================================================
+       Routine Description:
+               Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
 
-       ==========================================================================
- */
-VOID RT30xxReverseRFSleepModeSetup(
-       IN PRTMP_ADAPTER        pAd)
+       Arguments:
+       // IRQL = DISPATCH_LEVEL
+       ========================================================================
+*/
+void BATableDeleteORIEntry(struct rt_rtmp_adapter *pAd,
+                          struct rt_ba_ori_entry *pBAORIEntry)
 {
-       UCHAR RFValue;
-       UINT32 MACValue;
-
-       // 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);
-
-       // LDORF_VC, RF R27 register Bit 2 to 0
-       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 (pBAORIEntry->ORI_BA_Status != Originator_NONE) {
+               NdisAcquireSpinLock(&pAd->BATabLock);
+               if (pBAORIEntry->ORI_BA_Status == Originator_Done) {
+                       pAd->BATable.numAsOriginator -= 1;
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("BATableDeleteORIEntry numAsOriginator= %ld\n",
+                                 pAd->BATable.numAsRecipient));
+                       /* Erase Bitmap flag. */
+               }
+               pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1 << (pBAORIEntry->TID)));      /* If STA mode,  erase flag here */
+               pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0;    /* If STA mode,  erase flag here */
+               pBAORIEntry->ORI_BA_Status = Originator_NONE;
+               pBAORIEntry->Token = 1;
+               /* Not clear Sequence here. */
+               NdisReleaseSpinLock(&pAd->BATabLock);
        }
 }
-#endif
 
-/*
-       ==========================================================================
-       Description:
+/*! \brief
+ *     \param
+ *     \return
+ *     \pre
+ *     \post
 
-       IRQL = PASSIVE_LEVEL
-       IRQL = DISPATCH_LEVEL
+ IRQL = DISPATCH_LEVEL
 
-       ==========================================================================
  */
-VOID AsicSwitchChannel(
-                                         IN PRTMP_ADAPTER pAd,
-       IN      UCHAR                   Channel,
-       IN      BOOLEAN                 bScan)
+void BssEntrySet(struct rt_rtmp_adapter *pAd, struct rt_bss_entry *pBss, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * pCfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo, /* AP might use this additional ht info IE */
+                u8 HtCapabilityLen,
+                u8 AddHtInfoLen,
+                u8 NewExtChanOffset,
+                u8 Channel,
+                char Rssi,
+                IN LARGE_INTEGER TimeStamp,
+                u8 CkipFlag,
+                struct rt_edca_parm *pEdcaParm,
+                struct rt_qos_capability_parm *pQosCapability,
+                struct rt_qbss_load_parm *pQbssLoad,
+                u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE)
 {
-       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;
-
-       // 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;
+       COPY_MAC_ADDR(pBss->Bssid, pBssid);
+       /* Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID */
+       pBss->Hidden = 1;
+       if (SsidLen > 0) {
+               /* For hidden SSID AP, it might send beacon with SSID len equal to 0 */
+               /* Or send beacon /probe response with SSID len matching real SSID length, */
+               /* but SSID is all zero. such as "00-00-00-00" with length 4. */
+               /* We have to prevent this case overwrite correct table */
+               if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0) {
+                       NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
+                       NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
+                       pBss->SsidLen = SsidLen;
+                       pBss->Hidden = 0;
+               }
+       } else
+               pBss->SsidLen = 0;
+       pBss->BssType = BssType;
+       pBss->BeaconPeriod = BeaconPeriod;
+       if (BssType == BSS_INFRA) {
+               if (pCfParm->bValid) {
+                       pBss->CfpCount = pCfParm->CfpCount;
+                       pBss->CfpPeriod = pCfParm->CfpPeriod;
+                       pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
+                       pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
                }
+       } else {
+               pBss->AtimWin = AtimWin;
        }
 
-       if (index == MAX_NUM_OF_CHANNELS)
-               DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
+       pBss->CapabilityInfo = CapabilityInfo;
+       /* The privacy bit indicate security is ON, it maight be WEP, TKIP or AES */
+       /* Combine with AuthMode, they will decide the connection methods. */
+       pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
+       ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+       if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
+               NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
+       else
+               NdisMoveMemory(pBss->SupRate, SupRate,
+                              MAX_LEN_OF_SUPPORTED_RATES);
+       pBss->SupRateLen = SupRateLen;
+       ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+       NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
+       pBss->NewExtChanOffset = NewExtChanOffset;
+       pBss->ExtRateLen = ExtRateLen;
+       pBss->Channel = Channel;
+       pBss->CentralChannel = Channel;
+       pBss->Rssi = Rssi;
+       /* Update CkipFlag. if not exists, the value is 0x0 */
+       pBss->CkipFlag = CkipFlag;
+
+       /* New for microsoft Fixed IEs */
+       NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
+       pBss->FixIEs.BeaconInterval = BeaconPeriod;
+       pBss->FixIEs.Capabilities = CapabilityInfo;
 
-#ifdef RT2870
-       // The RF programming sequence is difference between 3xxx and 2xxx
-       if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && (
-            (pAd->RfIcType == RFIC_3022) || (pAd->RfIcType == RFIC_3021) ||
-            (pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
-       {
-               /* modify by WY for Read RF Reg. error */
-               UCHAR RFValue;
+       /* New for microsoft Variable IEs */
+       if (LengthVIE != 0) {
+               pBss->VarIELen = LengthVIE;
+               NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
+       } else {
+               pBss->VarIELen = 0;
+       }
 
-               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;
+       pBss->AddHtInfoLen = 0;
+       pBss->HtCapabilityLen = 0;
+       if (HtCapabilityLen > 0) {
+               pBss->HtCapabilityLen = HtCapabilityLen;
+               NdisMoveMemory(&pBss->HtCapability, pHtCapability,
+                              HtCapabilityLen);
+               if (AddHtInfoLen > 0) {
+                       pBss->AddHtInfoLen = AddHtInfoLen;
+                       NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo,
+                                      AddHtInfoLen);
+
+                       if ((pAddHtInfo->ControlChan > 2)
+                           && (pAddHtInfo->AddHtInfo.ExtChanOffset ==
+                               EXTCHA_BELOW)
+                           && (pHtCapability->HtCapInfo.ChannelWidth ==
+                               BW_40)) {
+                               pBss->CentralChannel =
+                                   pAddHtInfo->ControlChan - 2;
+                       } else
+                           if ((pAddHtInfo->AddHtInfo.ExtChanOffset ==
+                                EXTCHA_ABOVE)
+                               && (pHtCapability->HtCapInfo.ChannelWidth ==
+                                   BW_40)) {
+                               pBss->CentralChannel =
+                                   pAddHtInfo->ControlChan + 2;
                        }
                }
-
-               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));
        }
-       else
-#endif // RT2870 //
-       {
-               RFRegTable = RF2850RegTable;
 
-               switch (pAd->RfIcType)
-               {
-                       case RFIC_2820:
-                       case RFIC_2850:
-                       case RFIC_2720:
-                       case RFIC_2750:
+       BssCipherParse(pBss);
 
-                       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;
-                                       }
+       /* new for QOS */
+       if (pEdcaParm)
+               NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(struct rt_edca_parm));
+       else
+               pBss->EdcaParm.bValid = FALSE;
+       if (pQosCapability)
+               NdisMoveMemory(&pBss->QosCapability, pQosCapability,
+                              sizeof(struct rt_qos_capability_parm));
+       else
+               pBss->QosCapability.bValid = FALSE;
+       if (pQbssLoad)
+               NdisMoveMemory(&pBss->QbssLoad, pQbssLoad,
+                              sizeof(struct rt_qbss_load_parm));
+       else
+               pBss->QbssLoad.bValid = FALSE;
 
-                                       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
-                                       }
+       {
+               struct rt_eid * pEid;
+               u16 Length = 0;
 
-                                       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
+               NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
+               NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
+               pEid = (struct rt_eid *) pVIE;
+               while ((Length + 2 + (u16)pEid->Len) <= LengthVIE) {
+                       switch (pEid->Eid) {
+                       case IE_WPA:
+                               if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) {
+                                       if ((pEid->Len + 2) > MAX_CUSTOM_LEN) {
+                                               pBss->WpaIE.IELen = 0;
+                                               break;
                                        }
-
-                                       // Based on BBP current mode before changing RF channel.
-                                       if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
-                                       {
-                                               R4 |=0x200000;
+                                       pBss->WpaIE.IELen = pEid->Len + 2;
+                                       NdisMoveMemory(pBss->WpaIE.IE, pEid,
+                                                      pBss->WpaIE.IELen);
+                               }
+                               break;
+                       case IE_RSN:
+                               if (NdisEqualMemory
+                                   (pEid->Octet + 2, RSN_OUI, 3)) {
+                                       if ((pEid->Len + 2) > MAX_CUSTOM_LEN) {
+                                               pBss->RsnIE.IELen = 0;
+                                               break;
                                        }
-
-                                       // 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;
+                                       pBss->RsnIE.IELen = pEid->Len + 2;
+                                       NdisMoveMemory(pBss->RsnIE.IE, pEid,
+                                                      pBss->RsnIE.IELen);
                                }
+                               break;
                        }
-                       break;
-
-                       default:
-                       break;
+                       Length = Length + 2 + (u16)pEid->Len;   /* Eid[1] + Len[1]+ content[Len] */
+                       pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
                }
        }
+}
 
-       // 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
+/*!
+ *     \brief insert an entry into the bss table
+ *     \param p_tab The BSS table
+ *     \param Bssid BSSID
+ *     \param ssid SSID
+ *     \param ssid_len Length of SSID
+ *     \param bss_type
+ *     \param beacon_period
+ *     \param timestamp
+ *     \param p_cf
+ *     \param atim_win
+ *     \param cap
+ *     \param rates
+ *     \param rates_len
+ *     \param channel_idx
+ *     \return none
+ *     \pre
+ *     \post
+ *     \note If SSID is identical, the old entry will be replaced by the new one
 
-               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);
+ IRQL = DISPATCH_LEVEL
 
-               // Rx High power VGA offset for LNA select
-               if (pAd->NicConfig2.field.ExternalLNAForA)
-               {
-                       RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+ */
+unsigned long BssTableSetEntry(struct rt_rtmp_adapter *pAd, struct rt_bss_table *Tab, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,     /* AP might use this additional ht info IE */
+                      u8 HtCapabilityLen,
+                      u8 AddHtInfoLen,
+                      u8 NewExtChanOffset,
+                      u8 ChannelNo,
+                      char Rssi,
+                      IN LARGE_INTEGER TimeStamp,
+                      u8 CkipFlag,
+                      struct rt_edca_parm *pEdcaParm,
+                      struct rt_qos_capability_parm *pQosCapability,
+                      struct rt_qbss_load_parm *pQbssLoad,
+                      u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE)
+{
+       unsigned long Idx;
+
+       Idx =
+           BssTableSearchWithSSID(Tab, pBssid, (u8 *) Ssid, SsidLen,
+                                  ChannelNo);
+       if (Idx == BSS_NOT_FOUND) {
+               if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE) {
+                       /* */
+                       /* It may happen when BSS Table was full. */
+                       /* The desired AP will not be added into BSS Table */
+                       /* In this case, if we found the desired AP then overwrite BSS Table. */
+                       /* */
+                       if (!OPSTATUS_TEST_FLAG
+                           (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
+                               if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid)
+                                   || SSID_EQUAL(pAd->MlmeAux.Ssid,
+                                                 pAd->MlmeAux.SsidLen, Ssid,
+                                                 SsidLen)) {
+                                       Idx = Tab->BssOverlapNr;
+                                       BssEntrySet(pAd, &Tab->BssEntry[Idx],
+                                                   pBssid, Ssid, SsidLen,
+                                                   BssType, BeaconPeriod,
+                                                   CfParm, AtimWin,
+                                                   CapabilityInfo, SupRate,
+                                                   SupRateLen, ExtRate,
+                                                   ExtRateLen, pHtCapability,
+                                                   pAddHtInfo, HtCapabilityLen,
+                                                   AddHtInfoLen,
+                                                   NewExtChanOffset, ChannelNo,
+                                                   Rssi, TimeStamp, CkipFlag,
+                                                   pEdcaParm, pQosCapability,
+                                                   pQbssLoad, LengthVIE, pVIE);
+                                       Tab->BssOverlapNr =
+                                           (Tab->BssOverlapNr++) %
+                                           MAX_LEN_OF_BSS_TABLE;
+                               }
+                               return Idx;
+                       } else {
+                               return BSS_NOT_FOUND;
+                       }
                }
-               else
-               {
-                       RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+               Idx = Tab->BssNr;
+               BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen,
+                           BssType, BeaconPeriod, CfParm, AtimWin,
+                           CapabilityInfo, SupRate, SupRateLen, ExtRate,
+                           ExtRateLen, pHtCapability, pAddHtInfo,
+                           HtCapabilityLen, AddHtInfoLen, NewExtChanOffset,
+                           ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm,
+                           pQosCapability, pQbssLoad, LengthVIE, pVIE);
+               Tab->BssNr++;
+       } else {
+               /* avoid  Hidden SSID form beacon to overwirite correct SSID from probe response */
+               if ((SSID_EQUAL
+                    (Ssid, SsidLen, Tab->BssEntry[Idx].Ssid,
+                     Tab->BssEntry[Idx].SsidLen))
+                   ||
+                   (NdisEqualMemory
+                    (Tab->BssEntry[Idx].Ssid, ZeroSsid,
+                     Tab->BssEntry[Idx].SsidLen))) {
+                       BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid,
+                                   SsidLen, BssType, BeaconPeriod, CfParm,
+                                   AtimWin, CapabilityInfo, SupRate,
+                                   SupRateLen, ExtRate, ExtRateLen,
+                                   pHtCapability, pAddHtInfo, HtCapabilityLen,
+                                   AddHtInfoLen, NewExtChanOffset, ChannelNo,
+                                   Rssi, TimeStamp, CkipFlag, pEdcaParm,
+                                   pQosCapability, pQbssLoad, LengthVIE, pVIE);
                }
-
-               // 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);
-
-       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));
-}
-
-/*
-       ==========================================================================
-       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)
-{
+       return Idx;
 }
 
-VOID AsicRfTuningExec(
-       IN PVOID SystemSpecific1,
-       IN PVOID FunctionContext,
-       IN PVOID SystemSpecific2,
-       IN PVOID SystemSpecific3)
+/* IRQL = DISPATCH_LEVEL */
+void BssTableSsidSort(struct rt_rtmp_adapter *pAd,
+                     struct rt_bss_table *OutTab, char Ssid[], u8 SsidLen)
 {
-}
+       int i;
+       BssTableInit(OutTab);
 
-/*
-       ==========================================================================
-       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;
-
-#ifdef RT2860
-       if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-               || (pAd->bPCIclkOff == TRUE)
-               || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
-               || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-               return;
-#endif
+       for (i = 0; i < pAd->ScanTab.BssNr; i++) {
+               struct rt_bss_entry *pInBss = &pAd->ScanTab.BssEntry[i];
+               BOOLEAN bIsHiddenApIncluded = FALSE;
 
-       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];
+               if (((pAd->CommonCfg.bIEEE80211H == 1) &&
+                    (pAd->MlmeAux.Channel > 14) &&
+                    RadarChannelCheck(pAd, pInBss->Channel))
+                   ) {
+                       if (pInBss->Hidden)
+                               bIsHiddenApIncluded = TRUE;
                }
-       }
 
-       // 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 ((pInBss->BssType == pAd->StaCfg.BssType) &&
+                   (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen)
+                    || bIsHiddenApIncluded)) {
+                       struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
 
-               if (bAutoTxAgc)
-               {
-                       /* BbpR1 is unsigned char */
-                       RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+                       /* 2.4G/5G N only mode */
+                       if ((pInBss->HtCapabilityLen == 0) &&
+                           ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
+                            || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) {
+                               DBGPRINT(RT_DEBUG_TRACE,
+                                        ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+                               continue;
+                       }
+                       /* New for WPA2 */
+                       /* Check the Authmode first */
+                       if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
+                               /* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */
+                               if ((pAd->StaCfg.AuthMode != pInBss->AuthMode)
+                                   && (pAd->StaCfg.AuthMode !=
+                                       pInBss->AuthModeAux))
+                                       /* None matched */
+                                       continue;
+
+                               /* Check cipher suite, AP must have more secured cipher than station setting */
+                               if ((pAd->StaCfg.AuthMode ==
+                                    Ndis802_11AuthModeWPA)
+                                   || (pAd->StaCfg.AuthMode ==
+                                       Ndis802_11AuthModeWPAPSK)) {
+                                       /* If it's not mixed mode, we should only let BSS pass with the same encryption */
+                                       if (pInBss->WPA.bMixMode == FALSE)
+                                               if (pAd->StaCfg.WepStatus !=
+                                                   pInBss->WPA.GroupCipher)
+                                                       continue;
 
-                       /* (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 */
+                                       /* check group cipher */
+                                       if ((pAd->StaCfg.WepStatus <
+                                            pInBss->WPA.GroupCipher)
+                                           && (pInBss->WPA.GroupCipher !=
+                                               Ndis802_11GroupWEP40Enabled)
+                                           && (pInBss->WPA.GroupCipher !=
+                                               Ndis802_11GroupWEP104Enabled))
+                                               continue;
 
-                       /* [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] */
+                                       /* check pairwise cipher, skip if none matched */
+                                       /* If profile set to AES, let it pass without question. */
+                                       /* If profile set to TKIP, we must find one mateched */
+                                       if ((pAd->StaCfg.WepStatus ==
+                                            Ndis802_11Encryption2Enabled)
+                                           && (pAd->StaCfg.WepStatus !=
+                                               pInBss->WPA.PairCipher)
+                                           && (pAd->StaCfg.WepStatus !=
+                                               pInBss->WPA.PairCipherAux))
+                                               continue;
+                               } else
+                                   if ((pAd->StaCfg.AuthMode ==
+                                        Ndis802_11AuthModeWPA2)
+                                       || (pAd->StaCfg.AuthMode ==
+                                           Ndis802_11AuthModeWPA2PSK)) {
+                                       /* If it's not mixed mode, we should only let BSS pass with the same encryption */
+                                       if (pInBss->WPA2.bMixMode == FALSE)
+                                               if (pAd->StaCfg.WepStatus !=
+                                                   pInBss->WPA2.GroupCipher)
+                                                       continue;
 
-                       /* 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) */
+                                       /* check group cipher */
+                                       if ((pAd->StaCfg.WepStatus <
+                                            pInBss->WPA.GroupCipher)
+                                           && (pInBss->WPA2.GroupCipher !=
+                                               Ndis802_11GroupWEP40Enabled)
+                                           && (pInBss->WPA2.GroupCipher !=
+                                               Ndis802_11GroupWEP104Enabled))
+                                               continue;
 
-                       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;
+                                       /* check pairwise cipher, skip if none matched */
+                                       /* If profile set to AES, let it pass without question. */
+                                       /* If profile set to TKIP, we must find one mateched */
+                                       if ((pAd->StaCfg.WepStatus ==
+                                            Ndis802_11Encryption2Enabled)
+                                           && (pAd->StaCfg.WepStatus !=
+                                               pInBss->WPA2.PairCipher)
+                                           && (pAd->StaCfg.WepStatus !=
+                                               pInBss->WPA2.PairCipherAux))
+                                               continue;
                                }
-                               // The index is the step we should decrease, 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 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;
+                       /* Bss Type matched, SSID matched. */
+                       /* We will check wepstatus for qualification Bss */
+                       else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) {
+                               DBGPRINT(RT_DEBUG_TRACE,
+                                        ("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n",
+                                         pAd->StaCfg.WepStatus,
+                                         pInBss->WepStatus));
+                               /* */
+                               /* For the SESv2 case, we will not qualify WepStatus. */
+                               /* */
+                               if (!pInBss->bSES)
+                                       continue;
+                       }
+                       /* Since the AP is using hidden SSID, and we are trying to connect to ANY */
+                       /* It definitely will fail. So, skip it. */
+                       /* CCX also require not even try to connect it! */
+                       if (SsidLen == 0)
+                               continue;
+
+                       /* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */
+                       /* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */
+                       if ((pInBss->CentralChannel != pInBss->Channel) &&
+                           (pAd->CommonCfg.RegTransmitSetting.field.BW ==
+                            BW_40)) {
+                               if (RTMPCheckChannel
+                                   (pAd, pInBss->CentralChannel,
+                                    pInBss->Channel) == FALSE) {
+                                       pAd->CommonCfg.RegTransmitSetting.field.
+                                           BW = BW_20;
+                                       SetCommonHT(pAd);
+                                       pAd->CommonCfg.RegTransmitSetting.field.
+                                           BW = BW_40;
+                               } else {
+                                       if (pAd->CommonCfg.DesiredHtPhy.
+                                           ChannelWidth == BAND_WIDTH_20) {
+                                               SetCommonHT(pAd);
+                                       }
                                }
-                               // 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));
+                       /* copy matching BSS from InTab to OutTab */
+                       NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry));
+
+                       OutTab->BssNr++;
+               } else if ((pInBss->BssType == pAd->StaCfg.BssType)
+                          && (SsidLen == 0)) {
+                       struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+
+                       /* 2.4G/5G N only mode */
+                       if ((pInBss->HtCapabilityLen == 0) &&
+                           ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
+                            || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) {
+                               DBGPRINT(RT_DEBUG_TRACE,
+                                        ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+                               continue;
                        }
-               }
-       }
-       else
-       {
-               if (pAd->CommonCfg.Channel <= 14)
-               {
-                       bAutoTxAgc         = pAd->bAutoTxAgcG;
-                       pTxAgcCompensate   = &pAd->TxAgcCompensateG;
-               }
-               else
-               {
-                       bAutoTxAgc         = pAd->bAutoTxAgcA;
-                       pTxAgcCompensate   = &pAd->TxAgcCompensateA;
-               }
+                       /* New for WPA2 */
+                       /* Check the Authmode first */
+                       if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
+                               /* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */
+                               if ((pAd->StaCfg.AuthMode != pInBss->AuthMode)
+                                   && (pAd->StaCfg.AuthMode !=
+                                       pInBss->AuthModeAux))
+                                       /* None matched */
+                                       continue;
 
-               if (bAutoTxAgc)
-                       DeltaPwr += (*pTxAgcCompensate);
-       }
+                               /* Check cipher suite, AP must have more secured cipher than station setting */
+                               if ((pAd->StaCfg.AuthMode ==
+                                    Ndis802_11AuthModeWPA)
+                                   || (pAd->StaCfg.AuthMode ==
+                                       Ndis802_11AuthModeWPAPSK)) {
+                                       /* If it's not mixed mode, we should only let BSS pass with the same encryption */
+                                       if (pInBss->WPA.bMixMode == FALSE)
+                                               if (pAd->StaCfg.WepStatus !=
+                                                   pInBss->WPA.GroupCipher)
+                                                       continue;
 
-       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
-               ;
-       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;
-       }
+                                       /* check group cipher */
+                                       if (pAd->StaCfg.WepStatus <
+                                           pInBss->WPA.GroupCipher)
+                                               continue;
 
-       RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+                                       /* check pairwise cipher, skip if none matched */
+                                       /* If profile set to AES, let it pass without question. */
+                                       /* If profile set to TKIP, we must find one mateched */
+                                       if ((pAd->StaCfg.WepStatus ==
+                                            Ndis802_11Encryption2Enabled)
+                                           && (pAd->StaCfg.WepStatus !=
+                                               pInBss->WPA.PairCipher)
+                                           && (pAd->StaCfg.WepStatus !=
+                                               pInBss->WPA.PairCipherAux))
+                                               continue;
+                               } else
+                                   if ((pAd->StaCfg.AuthMode ==
+                                        Ndis802_11AuthModeWPA2)
+                                       || (pAd->StaCfg.AuthMode ==
+                                           Ndis802_11AuthModeWPA2PSK)) {
+                                       /* If it's not mixed mode, we should only let BSS pass with the same encryption */
+                                       if (pInBss->WPA2.bMixMode == FALSE)
+                                               if (pAd->StaCfg.WepStatus !=
+                                                   pInBss->WPA2.GroupCipher)
+                                                       continue;
 
-       /* 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 */
+                                       /* check group cipher */
+                                       if (pAd->StaCfg.WepStatus <
+                                           pInBss->WPA2.GroupCipher)
+                                               continue;
 
-                               if ((Value + DeltaPwr) < 0)
-                               {
-                                       Value = 0; /* min */
-                               }
-                               else if ((Value + DeltaPwr) > 0xF)
-                               {
-                                       Value = 0xF; /* max */
-                               }
-                               else
-                               {
-                                       Value += DeltaPwr; /* temperature compensation */
+                                       /* check pairwise cipher, skip if none matched */
+                                       /* If profile set to AES, let it pass without question. */
+                                       /* If profile set to TKIP, we must find one mateched */
+                                       if ((pAd->StaCfg.WepStatus ==
+                                            Ndis802_11Encryption2Enabled)
+                                           && (pAd->StaCfg.WepStatus !=
+                                               pInBss->WPA2.PairCipher)
+                                           && (pAd->StaCfg.WepStatus !=
+                                               pInBss->WPA2.PairCipherAux))
+                                               continue;
                                }
+                       }
+                       /* Bss Type matched, SSID matched. */
+                       /* We will check wepstatus for qualification Bss */
+                       else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+                               continue;
 
-                               /* fill new value to CSR offset */
-                               TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+                       /* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */
+                       /* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */
+                       if ((pInBss->CentralChannel != pInBss->Channel) &&
+                           (pAd->CommonCfg.RegTransmitSetting.field.BW ==
+                            BW_40)) {
+                               if (RTMPCheckChannel
+                                   (pAd, pInBss->CentralChannel,
+                                    pInBss->Channel) == FALSE) {
+                                       pAd->CommonCfg.RegTransmitSetting.field.
+                                           BW = BW_20;
+                                       SetCommonHT(pAd);
+                                       pAd->CommonCfg.RegTransmitSetting.field.
+                                           BW = BW_40;
+                               }
                        }
+                       /* copy matching BSS from InTab to OutTab */
+                       NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry));
 
-                       /* 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]);
+                       OutTab->BssNr++;
                }
+
+               if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
+                       break;
        }
 
+       BssTableSortByRssi(OutTab);
 }
 
-/*
-       ==========================================================================
-       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)
+/* IRQL = DISPATCH_LEVEL */
+void BssTableSortByRssi(struct rt_bss_table *OutTab)
 {
-    RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
+       int i, j;
+       struct rt_bss_entry TmpBss;
+
+       for (i = 0; i < OutTab->BssNr - 1; i++) {
+               for (j = i + 1; j < OutTab->BssNr; j++) {
+                       if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi) {
+                               NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j],
+                                              sizeof(struct rt_bss_entry));
+                               NdisMoveMemory(&OutTab->BssEntry[j],
+                                              &OutTab->BssEntry[i],
+                                              sizeof(struct rt_bss_entry));
+                               NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss,
+                                              sizeof(struct rt_bss_entry));
+                       }
+               }
+       }
 }
 
-/*
-       ==========================================================================
-       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)
+void BssCipherParse(struct rt_bss_entry *pBss)
 {
+       struct rt_eid * pEid;
+       u8 *pTmp;
+       struct rt_rsn_ie_header * pRsnHeader;
+       struct rt_cipher_suite_struct * pCipher;
+       struct rt_akm_suite * pAKM;
+       u16 Count;
+       int Length;
+       NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
+
+       /* */
+       /* WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame. */
+       /* */
+       if (pBss->Privacy) {
+               pBss->WepStatus = Ndis802_11WEPEnabled;
+       } else {
+               pBss->WepStatus = Ndis802_11WEPDisabled;
+       }
+       /* Set default to disable & open authentication before parsing variable IE */
+       pBss->AuthMode = Ndis802_11AuthModeOpen;
+       pBss->AuthModeAux = Ndis802_11AuthModeOpen;
+
+       /* Init WPA setting */
+       pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
+       pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
+       pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
+       pBss->WPA.RsnCapability = 0;
+       pBss->WPA.bMixMode = FALSE;
 
-}
+       /* Init WPA2 setting */
+       pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
+       pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
+       pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
+       pBss->WPA2.RsnCapability = 0;
+       pBss->WPA2.bMixMode = FALSE;
+
+       Length = (int)pBss->VarIELen;
+
+       while (Length > 0) {
+               /* Parse cipher suite base on WPA1 & WPA2, they should be parsed differently */
+               pTmp = ((u8 *)pBss->VarIEs) + pBss->VarIELen - Length;
+               pEid = (struct rt_eid *) pTmp;
+               switch (pEid->Eid) {
+               case IE_WPA:
+                       if (NdisEqualMemory(pEid->Octet, SES_OUI, 3)
+                           && (pEid->Len == 7)) {
+                               pBss->bSES = TRUE;
+                               break;
+                       } else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) !=
+                                  1) {
+                               /* if unsupported vendor specific IE */
+                               break;
+                       }
+                       /* Skip OUI, version, and multicast suite */
+                       /* This part should be improved in the future when AP supported multiple cipher suite. */
+                       /* For now, it's OK since almost all APs have fixed cipher suite supported. */
+                       /* pTmp = (u8 *)pEid->Octet; */
+                       pTmp += 11;
+
+                       /* Cipher Suite Selectors from Spec P802.11i/D3.2 P26. */
+                       /*      Value      Meaning */
+                       /*      0                       None */
+                       /*      1                       WEP-40 */
+                       /*      2                       Tkip */
+                       /*      3                       WRAP */
+                       /*      4                       AES */
+                       /*      5                       WEP-104 */
+                       /* Parse group cipher */
+                       switch (*pTmp) {
+                       case 1:
+                               pBss->WPA.GroupCipher =
+                                   Ndis802_11GroupWEP40Enabled;
+                               break;
+                       case 5:
+                               pBss->WPA.GroupCipher =
+                                   Ndis802_11GroupWEP104Enabled;
+                               break;
+                       case 2:
+                               pBss->WPA.GroupCipher =
+                                   Ndis802_11Encryption2Enabled;
+                               break;
+                       case 4:
+                               pBss->WPA.GroupCipher =
+                                   Ndis802_11Encryption3Enabled;
+                               break;
+                       default:
+                               break;
+                       }
+                       /* number of unicast suite */
+                       pTmp += 1;
+
+                       /* skip all unicast cipher suites */
+                       /*Count = *(u16 *)pTmp; */
+                       Count = (pTmp[1] << 8) + pTmp[0];
+                       pTmp += sizeof(u16);
+
+                       /* Parsing all unicast cipher suite */
+                       while (Count > 0) {
+                               /* Skip OUI */
+                               pTmp += 3;
+                               TmpCipher = Ndis802_11WEPDisabled;
+                               switch (*pTmp) {
+                               case 1:
+                               case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
+                                       TmpCipher =
+                                           Ndis802_11Encryption1Enabled;
+                                       break;
+                               case 2:
+                                       TmpCipher =
+                                           Ndis802_11Encryption2Enabled;
+                                       break;
+                               case 4:
+                                       TmpCipher =
+                                           Ndis802_11Encryption3Enabled;
+                                       break;
+                               default:
+                                       break;
+                               }
+                               if (TmpCipher > pBss->WPA.PairCipher) {
+                                       /* Move the lower cipher suite to PairCipherAux */
+                                       pBss->WPA.PairCipherAux =
+                                           pBss->WPA.PairCipher;
+                                       pBss->WPA.PairCipher = TmpCipher;
+                               } else {
+                                       pBss->WPA.PairCipherAux = TmpCipher;
+                               }
+                               pTmp++;
+                               Count--;
+                       }
 
-/*
-       ==========================================================================
-       Description:
-               AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
-               expired.
+                       /* 4. get AKM suite counts */
+                       /*Count = *(u16 *)pTmp; */
+                       Count = (pTmp[1] << 8) + pTmp[0];
+                       pTmp += sizeof(u16);
+                       pTmp += 3;
+
+                       switch (*pTmp) {
+                       case 1:
+                               /* Set AP support WPA-enterprise mode */
+                               if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+                                       pBss->AuthMode = Ndis802_11AuthModeWPA;
+                               else
+                                       pBss->AuthModeAux =
+                                           Ndis802_11AuthModeWPA;
+                               break;
+                       case 2:
+                               /* Set AP support WPA-PSK mode */
+                               if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+                                       pBss->AuthMode =
+                                           Ndis802_11AuthModeWPAPSK;
+                               else
+                                       pBss->AuthModeAux =
+                                           Ndis802_11AuthModeWPAPSK;
+                               break;
+                       default:
+                               break;
+                       }
+                       pTmp += 1;
+
+                       /* Fixed for WPA-None */
+                       if (pBss->BssType == BSS_ADHOC) {
+                               pBss->AuthMode = Ndis802_11AuthModeWPANone;
+                               pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+                               pBss->WepStatus = pBss->WPA.GroupCipher;
+                               /* Patched bugs for old driver */
+                               if (pBss->WPA.PairCipherAux ==
+                                   Ndis802_11WEPDisabled)
+                                       pBss->WPA.PairCipherAux =
+                                           pBss->WPA.GroupCipher;
+                       } else
+                               pBss->WepStatus = pBss->WPA.PairCipher;
+
+                       /* Check the Pair & Group, if different, turn on mixed mode flag */
+                       if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
+                               pBss->WPA.bMixMode = TRUE;
 
-       IRQL = PASSIVE_LEVEL
-       IRQL = DISPATCH_LEVEL
-       ==========================================================================
- */
-VOID AsicForceWakeup(
-       IN PRTMP_ADAPTER pAd,
-#ifdef RT2860
-       IN UCHAR         Level)
-#endif
-#ifdef RT2870
-       IN BOOLEAN    bFromTx)
-#endif
-{
-    DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
-#ifdef RT2860
-    RT28XX_STA_FORCE_WAKEUP(pAd, Level);
-#endif
-#ifdef RT2870
-    RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
-#endif
-}
+                       break;
 
-/*
-       ==========================================================================
-       Description:
-               Set My BSSID
+               case IE_RSN:
+                       pRsnHeader = (struct rt_rsn_ie_header *) pTmp;
 
-       IRQL = DISPATCH_LEVEL
+                       /* 0. Version must be 1 */
+                       if (le2cpu16(pRsnHeader->Version) != 1)
+                               break;
+                       pTmp += sizeof(struct rt_rsn_ie_header);
 
-       ==========================================================================
- */
-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]));
+                       /* 1. Check group cipher */
+                       pCipher = (struct rt_cipher_suite_struct *) pTmp;
+                       if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+                               break;
 
-       Addr4 = (ULONG)(pBssid[0])               |
-                       (ULONG)(pBssid[1] << 8)  |
-                       (ULONG)(pBssid[2] << 16) |
-                       (ULONG)(pBssid[3] << 24);
-       RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
+                       /* Parse group cipher */
+                       switch (pCipher->Type) {
+                       case 1:
+                               pBss->WPA2.GroupCipher =
+                                   Ndis802_11GroupWEP40Enabled;
+                               break;
+                       case 5:
+                               pBss->WPA2.GroupCipher =
+                                   Ndis802_11GroupWEP104Enabled;
+                               break;
+                       case 2:
+                               pBss->WPA2.GroupCipher =
+                                   Ndis802_11Encryption2Enabled;
+                               break;
+                       case 4:
+                               pBss->WPA2.GroupCipher =
+                                   Ndis802_11Encryption3Enabled;
+                               break;
+                       default:
+                               break;
+                       }
+                       /* set to correct offset for next parsing */
+                       pTmp += sizeof(struct rt_cipher_suite_struct);
+
+                       /* 2. Get pairwise cipher counts */
+                       /*Count = *(u16 *)pTmp; */
+                       Count = (pTmp[1] << 8) + pTmp[0];
+                       pTmp += sizeof(u16);
+
+                       /* 3. Get pairwise cipher */
+                       /* Parsing all unicast cipher suite */
+                       while (Count > 0) {
+                               /* Skip OUI */
+                               pCipher = (struct rt_cipher_suite_struct *) pTmp;
+                               TmpCipher = Ndis802_11WEPDisabled;
+                               switch (pCipher->Type) {
+                               case 1:
+                               case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
+                                       TmpCipher =
+                                           Ndis802_11Encryption1Enabled;
+                                       break;
+                               case 2:
+                                       TmpCipher =
+                                           Ndis802_11Encryption2Enabled;
+                                       break;
+                               case 4:
+                                       TmpCipher =
+                                           Ndis802_11Encryption3Enabled;
+                                       break;
+                               default:
+                                       break;
+                               }
+                               if (TmpCipher > pBss->WPA2.PairCipher) {
+                                       /* Move the lower cipher suite to PairCipherAux */
+                                       pBss->WPA2.PairCipherAux =
+                                           pBss->WPA2.PairCipher;
+                                       pBss->WPA2.PairCipher = TmpCipher;
+                               } else {
+                                       pBss->WPA2.PairCipherAux = TmpCipher;
+                               }
+                               pTmp += sizeof(struct rt_cipher_suite_struct);
+                               Count--;
+                       }
 
-       Addr4 = 0;
-       // always one BSSID in STA mode
-       Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
+                       /* 4. get AKM suite counts */
+                       /*Count = *(u16 *)pTmp; */
+                       Count = (pTmp[1] << 8) + pTmp[0];
+                       pTmp += sizeof(u16);
 
-       RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
-}
+                       /* 5. Get AKM ciphers */
+                       /* Parsing all AKM ciphers */
+                       while (Count > 0) {
+                               pAKM = (struct rt_akm_suite *) pTmp;
+                               if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+                                       break;
 
-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;
-}
+                               switch (pAKM->Type) {
+                               case 1:
+                                       /* Set AP support WPA-enterprise mode */
+                                       if (pBss->AuthMode ==
+                                           Ndis802_11AuthModeOpen)
+                                               pBss->AuthMode =
+                                                   Ndis802_11AuthModeWPA2;
+                                       else
+                                               pBss->AuthModeAux =
+                                                   Ndis802_11AuthModeWPA2;
+                                       break;
+                               case 2:
+                                       /* Set AP support WPA-PSK mode */
+                                       if (pBss->AuthMode ==
+                                           Ndis802_11AuthModeOpen)
+                                               pBss->AuthMode =
+                                                   Ndis802_11AuthModeWPA2PSK;
+                                       else
+                                               pBss->AuthModeAux =
+                                                   Ndis802_11AuthModeWPA2PSK;
+                                       break;
+                               default:
+                                       if (pBss->AuthMode ==
+                                           Ndis802_11AuthModeOpen)
+                                               pBss->AuthMode =
+                                                   Ndis802_11AuthModeMax;
+                                       else
+                                               pBss->AuthModeAux =
+                                                   Ndis802_11AuthModeMax;
+                                       break;
+                               }
+                               pTmp += (Count * sizeof(struct rt_akm_suite));
+                               Count--;
+                       }
 
-/*
-       ==========================================================================
-       Description:
+                       /* Fixed for WPA-None */
+                       if (pBss->BssType == BSS_ADHOC) {
+                               pBss->AuthMode = Ndis802_11AuthModeWPANone;
+                               pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+                               pBss->WPA.PairCipherAux =
+                                   pBss->WPA2.PairCipherAux;
+                               pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
+                               pBss->WepStatus = pBss->WPA.GroupCipher;
+                               /* Patched bugs for old driver */
+                               if (pBss->WPA.PairCipherAux ==
+                                   Ndis802_11WEPDisabled)
+                                       pBss->WPA.PairCipherAux =
+                                           pBss->WPA.GroupCipher;
+                       }
+                       pBss->WepStatus = pBss->WPA2.PairCipher;
 
-       IRQL = DISPATCH_LEVEL
+                       /* 6. Get RSN capability */
+                       /*pBss->WPA2.RsnCapability = *(u16 *)pTmp; */
+                       pBss->WPA2.RsnCapability = (pTmp[1] << 8) + pTmp[0];
+                       pTmp += sizeof(u16);
 
-       ==========================================================================
- */
-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);
-}
+                       /* Check the Pair & Group, if different, turn on mixed mode flag */
+                       if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
+                               pBss->WPA2.bMixMode = TRUE;
 
-/*
-       ==========================================================================
-       Description:
+                       break;
+               default:
+                       break;
+               }
+               Length -= (pEid->Len + 2);
+       }
+}
 
-       IRQL = DISPATCH_LEVEL
+/* =========================================================================================== */
+/* mac_table.c */
+/* =========================================================================================== */
 
-       ==========================================================================
+/*! \brief generates a random mac address value for IBSS BSSID
+ *     \param Addr the bssid location
+ *     \return none
+ *     \pre
+ *     \post
  */
-VOID AsicEnableRDG(
-       IN PRTMP_ADAPTER pAd)
+void MacAddrRandomBssid(struct rt_rtmp_adapter *pAd, u8 *pAddr)
 {
-       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);
+       int i;
 
-       RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-       Data  &= 0xFFFFFF00;
-       Data  |= 0x80;
-       RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+       for (i = 0; i < MAC_ADDR_LEN; i++) {
+               pAddr[i] = RandomByte(pAd);
+       }
 
-       //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+       pAddr[0] = (pAddr[0] & 0xfe) | 0x02;    /* the first 2 bits must be 01xxxxxxxx */
 }
 
-/*
-       ==========================================================================
-       Description:
+/*! \brief init the management mac frame header
+ *     \param p_hdr mac header
+ *     \param subtype subtype of the frame
+ *     \param p_ds destination address, don't care if it is a broadcast address
+ *     \return none
+ *     \pre the station has the following information in the pAd->StaCfg
+ *      - bssid
+ *      - station address
+ *     \post
+ *     \note this function initializes the following field
 
+       IRQL = PASSIVE_LEVEL
        IRQL = DISPATCH_LEVEL
 
-       ==========================================================================
  */
-VOID AsicDisableRDG(
-       IN PRTMP_ADAPTER pAd)
+void MgtMacHeaderInit(struct rt_rtmp_adapter *pAd,
+                     struct rt_header_802_11 * pHdr80211,
+                     u8 SubType,
+                     u8 ToDs, u8 *pDA, u8 *pBssid)
 {
-       TX_LINK_CFG_STRUC       TxLinkCfg;
-       UINT32                          Data = 0;
+       NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
 
-
-       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;
-       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);
+       pHdr80211->FC.Type = BTYPE_MGMT;
+       pHdr80211->FC.SubType = SubType;
+/*      if (SubType == SUBTYPE_ACK)     // sample, no use, it will conflict with ACTION frame sub type */
+/*              pHdr80211->FC.Type = BTYPE_CNTL; */
+       pHdr80211->FC.ToDs = ToDs;
+       COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+       COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+       COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
 }
 
-/*
-       ==========================================================================
-       Description:
+/* =========================================================================================== */
+/* mem_mgmt.c */
+/* =========================================================================================== */
 
-       IRQL = PASSIVE_LEVEL
+/*!***************************************************************************
+ * This routine build an outgoing frame, and fill all information specified
+ * in argument list to the frame body. The actual frame size is the summation
+ * of all arguments.
+ * input params:
+ *             Buffer - pointer to a pre-allocated memory segment
+ *             args - a list of <int arg_size, arg> pairs.
+ *             NOTE NOTE NOTE! the last argument must be NULL, otherwise this
+ *                                                function will FAIL!
+ * return:
+ *             Size of the buffer
+ * usage:
+ *             MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
+
+ IRQL = PASSIVE_LEVEL
        IRQL = DISPATCH_LEVEL
 
-       ==========================================================================
- */
-VOID AsicDisableSync(
-       IN PRTMP_ADAPTER pAd)
+ ****************************************************************************/
+unsigned long MakeOutgoingFrame(u8 * Buffer, unsigned long * FrameLen, ...)
 {
-       BCN_TIME_CFG_STRUC csr;
-
-       DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
+       u8 *p;
+       int leng;
+       unsigned long TotLeng;
+       va_list Args;
 
-       // 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);
+       /* calculates the total length */
+       TotLeng = 0;
+       va_start(Args, FrameLen);
+       do {
+               leng = va_arg(Args, int);
+               if (leng == END_OF_ARGS) {
+                       break;
+               }
+               p = va_arg(Args, void *);
+               NdisMoveMemory(&Buffer[TotLeng], p, leng);
+               TotLeng = TotLeng + leng;
+       } while (TRUE);
 
+       va_end(Args);           /* clean up */
+       *FrameLen = TotLeng;
+       return TotLeng;
 }
 
-/*
-       ==========================================================================
-       Description:
+/* =========================================================================================== */
+/* mlme_queue.c */
+/* =========================================================================================== */
+
+/*! \brief     Initialize The MLME Queue, used by MLME Functions
+ *     \param  *Queue     The MLME Queue
+ *     \return Always     Return NDIS_STATE_SUCCESS in this implementation
+ *     \pre
+ *     \post
+ *     \note   Because this is done only once (at the init stage), no need to be locked
 
      IRQL = DISPATCH_LEVEL
IRQL = PASSIVE_LEVEL
 
-       ==========================================================================
  */
-VOID AsicEnableBssSync(
-       IN PRTMP_ADAPTER pAd)
+int MlmeQueueInit(struct rt_mlme_queue *Queue)
 {
-       BCN_TIME_CFG_STRUC csr;
+       int i;
 
-       DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
+       NdisAllocateSpinLock(&Queue->Lock);
 
-       RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+       Queue->Num = 0;
+       Queue->Head = 0;
+       Queue->Tail = 0;
 
-       {
-               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;
+       for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++) {
+               Queue->Entry[i].Occupied = FALSE;
+               Queue->Entry[i].MsgLen = 0;
+               NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
        }
 
-       RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+       return NDIS_STATUS_SUCCESS;
 }
 
-/*
-       ==========================================================================
-       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.
+/*! \brief      Enqueue a message for other threads, if they want to send messages to MLME thread
+ *     \param  *Queue    The MLME Queue
+ *     \param   Machine  The State Machine Id
+ *     \param   MsgType  The Message Type
+ *     \param   MsgLen   The Message length
+ *     \param  *Msg      The message pointer
+ *     \return  TRUE if enqueue is successful, FALSE if the queue is full
+ *     \pre
+ *     \post
+ *     \note    The message has to be initialized
 
+       IRQL = PASSIVE_LEVEL
        IRQL = DISPATCH_LEVEL
 
-       ==========================================================================
  */
-VOID AsicEnableIbssSync(
-       IN PRTMP_ADAPTER pAd)
+BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd,
+                   unsigned long Machine,
+                   unsigned long MsgType, unsigned long MsgLen, void * Msg)
 {
-       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 RT2860
-       // 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;
+       int Tail;
+       struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue;
+
+       /* 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 FALSE;
+
+       /* First check the size, it MUST not exceed the mlme queue size */
+       if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
+               DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n",
+                             MsgLen));
+               return FALSE;
        }
 
-       // 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;
+       if (MlmeQueueFull(Queue)) {
+               return FALSE;
        }
-#endif
-#ifdef RT2870
-       // 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
-       {
-               RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
-               ptr += 2;
+
+       NdisAcquireSpinLock(&(Queue->Lock));
+       Tail = Queue->Tail;
+       Queue->Tail++;
+       Queue->Num++;
+       if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) {
+               Queue->Tail = 0;
        }
 
-       // start right after the 16-byte TXWI field
-       ptr = pAd->BeaconBuf;
-       for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
-       {
-               RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
-               ptr +=2;
+       Queue->Entry[Tail].Wcid = RESERVED_WCID;
+       Queue->Entry[Tail].Occupied = TRUE;
+       Queue->Entry[Tail].Machine = Machine;
+       Queue->Entry[Tail].MsgType = MsgType;
+       Queue->Entry[Tail].MsgLen = MsgLen;
+
+       if (Msg != NULL) {
+               NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
        }
-#endif // RT2870 //
-
-       // 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);
+
+       NdisReleaseSpinLock(&(Queue->Lock));
+       return TRUE;
 }
 
-/*
-       ==========================================================================
-       Description:
+/*! \brief      This function is used when Recv gets a MLME message
+ *     \param  *Queue                   The MLME Queue
+ *     \param   TimeStampHigh   The upper 32 bit of timestamp
+ *     \param   TimeStampLow    The lower 32 bit of timestamp
+ *     \param   Rssi                    The receiving RSSI strength
+ *     \param   MsgLen                  The length of the message
+ *     \param  *Msg                     The message pointer
+ *     \return  TRUE if everything ok, FALSE otherwise (like Queue Full)
+ *     \pre
+ *     \post
 
-       IRQL = PASSIVE_LEVEL
-       IRQL = DISPATCH_LEVEL
+ IRQL = DISPATCH_LEVEL
 
-       ==========================================================================
  */
-VOID AsicSetEdcaParm(
-       IN PRTMP_ADAPTER pAd,
-       IN PEDCA_PARM    pEdcaParm)
+BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd,
+                          unsigned long Wcid,
+                          unsigned long TimeStampHigh,
+                          unsigned long TimeStampLow,
+                          u8 Rssi0,
+                          u8 Rssi1,
+                          u8 Rssi2,
+                          unsigned long MsgLen, void * Msg, u8 Signal)
 {
-       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 .
-               //========================================================
-               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
-               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));
+       int Tail, Machine;
+       struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
+       int MsgType;
+       struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue;
+
+       /* 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)) {
+               DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
+               return FALSE;
+       }
+       /* First check the size, it MUST not exceed the mlme queue size */
+       if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
+               DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
+               return FALSE;
        }
-       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;
-               Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
-               Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
-               Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
-
-               {
-                       // 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: connexant 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 RT2870
-                       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
-               }
 
-               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];
+       if (MlmeQueueFull(Queue)) {
+               return FALSE;
+       }
 
-//#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 */
+       {
+               if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) {
+                       DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n", pFrame->Hdr.FC.SubType));
+                       return FALSE;
                }
-//#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);
+       /* OK, we got all the informations, it is time to put things into queue */
+       NdisAcquireSpinLock(&(Queue->Lock));
+       Tail = Queue->Tail;
+       Queue->Tail++;
+       Queue->Num++;
+       if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) {
+               Queue->Tail = 0;
+       }
+       Queue->Entry[Tail].Occupied = TRUE;
+       Queue->Entry[Tail].Machine = Machine;
+       Queue->Entry[Tail].MsgType = MsgType;
+       Queue->Entry[Tail].MsgLen = MsgLen;
+       Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
+       Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
+       Queue->Entry[Tail].Rssi0 = Rssi0;
+       Queue->Entry[Tail].Rssi1 = Rssi1;
+       Queue->Entry[Tail].Rssi2 = Rssi2;
+       Queue->Entry[Tail].Signal = Signal;
+       Queue->Entry[Tail].Wcid = (u8)Wcid;
 
-               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);
+       Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
 
-               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];
+       if (Msg != NULL) {
+               NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+       }
 
-               {
-                       // 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;
-                       }
-#ifdef RT2870
-                       if (INFRA_ON(pAd))
-                               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
-#endif
-               }
+       NdisReleaseSpinLock(&(Queue->Lock));
 
-               AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
-#ifdef RT2870
-               if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
-                       AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
-#endif
-               RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
+       RTMP_MLME_HANDLER(pAd);
 
-               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]));
-               }
-       }
+       return TRUE;
 }
 
-/*
-       ==========================================================================
-       Description:
+/*! \brief      Dequeue a message from the MLME Queue
+ *     \param  *Queue    The MLME Queue
+ *     \param  *Elem     The message dequeued from MLME Queue
+ *     \return  TRUE if the Elem contains something, FALSE otherwise
+ *     \pre
+ *     \post
 
-       IRQL = PASSIVE_LEVEL
-       IRQL = DISPATCH_LEVEL
+ IRQL = DISPATCH_LEVEL
 
-       ==========================================================================
  */
-VOID   AsicSetSlotTime(
-       IN PRTMP_ADAPTER pAd,
-       IN BOOLEAN bUseShortSlotTime)
+BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem ** Elem)
 {
-       ULONG   SlotTime;
-       UINT32  RegValue = 0;
-
-       if (pAd->CommonCfg.Channel > 14)
-               bUseShortSlotTime = TRUE;
-
-       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)
-                       SlotTime = 9;
+       NdisAcquireSpinLock(&(Queue->Lock));
+       *Elem = &(Queue->Entry[Queue->Head]);
+       Queue->Num--;
+       Queue->Head++;
+       if (Queue->Head == MAX_LEN_OF_MLME_QUEUE) {
+               Queue->Head = 0;
        }
-
-       //
-       // For some reasons, always set it to short slot time.
-       //
-       // ToDo: Should consider capability with 11B
-       //
-       if (pAd->StaCfg.BssType == BSS_ADHOC)
-               SlotTime = 20;
-
-       RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
-       RegValue = RegValue & 0xFFFFFF00;
-
-       RegValue |= SlotTime;
-
-       RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
+       NdisReleaseSpinLock(&(Queue->Lock));
+       return TRUE;
 }
 
-/*
-       ========================================================================
-       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)
+/* IRQL = DISPATCH_LEVEL */
+void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd)
 {
-       ULONG offset; //, csr0;
-       SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
-       INT   i;
-#endif
+#ifdef RTMP_MAC_PCI
+       struct rt_mlme_queue_elem *Elem = NULL;
+#endif /* RTMP_MAC_PCI // */
+       BOOLEAN Cancelled;
 
-       DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
-//============================================================================================
+       DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
 
-       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
-       //
-
-       offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
-#ifdef RT2860
-       for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
-       {
-               RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+#ifdef RTMP_MAC_PCI
+       NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+       if (pAd->Mlme.bRunning) {
+               NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+               return;
+       } else {
+               pAd->Mlme.bRunning = TRUE;
        }
-#endif
-#ifdef RT2870
-       RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
-#endif
-       offset += MAX_LEN_OF_SHARE_KEY;
-       if (pTxMic)
-       {
-#ifdef RT2860
-               for (i=0; i<8; i++)
-               {
-                       RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
+       NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+
+       /* Remove all Mlme queues elements */
+       while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) {
+               /*From message type, determine which state machine I should drive */
+               if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
+                       /* free MLME element */
+                       Elem->Occupied = FALSE;
+                       Elem->MsgLen = 0;
+
+               } else {
+                       DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
                }
-#endif
-#ifdef RT2870
-               RTUSBMultiWrite(pAd, offset, pTxMic, 8);
-#endif
        }
+#endif /* RTMP_MAC_PCI // */
 
-       offset += 8;
-       if (pRxMic)
        {
-#ifdef RT2860
-               for (i=0; i<8; i++)
-               {
-                       RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
-               }
-#endif
-#ifdef RT2870
-               RTUSBMultiWrite(pAd, offset, pRxMic, 8);
-#endif
+               /* Cancel all timer events */
+               /* Be careful to cancel new added timer */
+               RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+               RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+
        }
 
+       /* Change back to original channel in case of doing scan */
+       AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+       AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+       /* Resume MSDU which is turned off durning scan */
+       RTMPResumeMsduTransmission(pAd);
 
-       //
-       // 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;
+               /* Set all state machines back IDLE */
+               pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+               pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+               pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+               pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
+               pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+               pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
        }
-       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);
 
+#ifdef RTMP_MAC_PCI
+       /* Remove running state */
+       NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+       pAd->Mlme.bRunning = FALSE;
+       NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+#endif /* RTMP_MAC_PCI // */
 }
 
-//     IRQL = DISPATCH_LEVEL
-VOID AsicRemoveSharedKeyEntry(
-       IN PRTMP_ADAPTER pAd,
-       IN UCHAR                 BssIndex,
-       IN UCHAR                 KeyIdx)
-{
-       //ULONG SecCsr0;
-       SHAREDKEY_MODE_STRUC csr1;
+/*! \brief     test if the MLME Queue is empty
+ *     \param  *Queue    The MLME Queue
+ *     \return TRUE if the Queue is empty, FALSE otherwise
+ *     \pre
+ *     \post
 
-       DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
+ IRQL = DISPATCH_LEVEL
 
-       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);
+ */
+BOOLEAN MlmeQueueEmpty(struct rt_mlme_queue *Queue)
+{
+       BOOLEAN Ans;
+
+       NdisAcquireSpinLock(&(Queue->Lock));
+       Ans = (Queue->Num == 0);
+       NdisReleaseSpinLock(&(Queue->Lock));
 
+       return Ans;
 }
 
+/*! \brief      test if the MLME Queue is full
+ *     \param   *Queue          The MLME Queue
+ *     \return  TRUE if the Queue is empty, FALSE otherwise
+ *     \pre
+ *     \post
 
-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);
-}
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
 
-VOID AsicUpdateWCIDIVEIV(
-       IN PRTMP_ADAPTER pAd,
-       IN USHORT               WCID,
-       IN ULONG        uIV,
-       IN ULONG        uEIV)
+ */
+BOOLEAN MlmeQueueFull(struct rt_mlme_queue *Queue)
 {
-       ULONG   offset;
+       BOOLEAN Ans;
 
-       offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+       NdisAcquireSpinLock(&(Queue->Lock));
+       Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE
+              || Queue->Entry[Queue->Tail].Occupied);
+       NdisReleaseSpinLock(&(Queue->Lock));
 
-       RTMP_IO_WRITE32(pAd, offset, uIV);
-       RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
+       return Ans;
 }
 
-VOID AsicUpdateRxWCIDTable(
-       IN PRTMP_ADAPTER pAd,
-       IN USHORT               WCID,
-       IN PUCHAR        pAddr)
+/*! \brief      The destructor of MLME Queue
+ *     \param
+ *     \return
+ *     \pre
+ *     \post
+ *     \note   Clear Mlme Queue, Set Queue->Num to Zero.
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+void MlmeQueueDestroy(struct rt_mlme_queue *pQueue)
 {
-       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);
+       NdisAcquireSpinLock(&(pQueue->Lock));
+       pQueue->Num = 0;
+       pQueue->Head = 0;
+       pQueue->Tail = 0;
+       NdisReleaseSpinLock(&(pQueue->Lock));
+       NdisFreeSpinLock(&(pQueue->Lock));
 }
 
+/*! \brief      To substitute the message type if the message is coming from external
+ *     \param  pFrame             The frame received
+ *     \param  *Machine           The state machine
+ *     \param  *MsgType           the message type for the state machine
+ *     \return TRUE if the substitution is successful, FALSE otherwise
+ *     \pre
+ *     \post
 
-/*
-    ========================================================================
-
-    Routine Description:
-        Set Cipher Key, Cipher algorithm, IV/EIV to Asic
+ IRQL = DISPATCH_LEVEL
 
-    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.
+ */
+BOOLEAN MsgTypeSubst(struct rt_rtmp_adapter *pAd,
+                    struct rt_frame_802_11 * pFrame,
+                    int * Machine, int * MsgType)
+{
+       u16 Seq, Alg;
+       u8 EAPType;
+       u8 *pData;
+
+       /* Pointer to start of data frames including SNAP header */
+       pData = (u8 *)pFrame + LENGTH_802_11;
+
+       /* The only data type will pass to this function is EAPOL frame */
+       if (pFrame->Hdr.FC.Type == BTYPE_DATA) {
+               {
+                       *Machine = WPA_STATE_MACHINE;
+                       EAPType =
+                           *((u8 *) pFrame + LENGTH_802_11 +
+                             LENGTH_802_1_H + 1);
+                       return (WpaMsgTypeSubst(EAPType, (int *) MsgType));
+               }
+       }
+
+       switch (pFrame->Hdr.FC.SubType) {
+       case SUBTYPE_ASSOC_REQ:
+               *Machine = ASSOC_STATE_MACHINE;
+               *MsgType = MT2_PEER_ASSOC_REQ;
+               break;
+       case SUBTYPE_ASSOC_RSP:
+               *Machine = ASSOC_STATE_MACHINE;
+               *MsgType = MT2_PEER_ASSOC_RSP;
+               break;
+       case SUBTYPE_REASSOC_REQ:
+               *Machine = ASSOC_STATE_MACHINE;
+               *MsgType = MT2_PEER_REASSOC_REQ;
+               break;
+       case SUBTYPE_REASSOC_RSP:
+               *Machine = ASSOC_STATE_MACHINE;
+               *MsgType = MT2_PEER_REASSOC_RSP;
+               break;
+       case SUBTYPE_PROBE_REQ:
+               *Machine = SYNC_STATE_MACHINE;
+               *MsgType = MT2_PEER_PROBE_REQ;
+               break;
+       case SUBTYPE_PROBE_RSP:
+               *Machine = SYNC_STATE_MACHINE;
+               *MsgType = MT2_PEER_PROBE_RSP;
+               break;
+       case SUBTYPE_BEACON:
+               *Machine = SYNC_STATE_MACHINE;
+               *MsgType = MT2_PEER_BEACON;
+               break;
+       case SUBTYPE_ATIM:
+               *Machine = SYNC_STATE_MACHINE;
+               *MsgType = MT2_PEER_ATIM;
+               break;
+       case SUBTYPE_DISASSOC:
+               *Machine = ASSOC_STATE_MACHINE;
+               *MsgType = MT2_PEER_DISASSOC_REQ;
+               break;
+       case SUBTYPE_AUTH:
+               /* get the sequence number from payload 24 Mac Header + 2 bytes algorithm */
+               NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(u16));
+               NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(u16));
+               if (Seq == 1 || Seq == 3) {
+                       *Machine = AUTH_RSP_STATE_MACHINE;
+                       *MsgType = MT2_PEER_AUTH_ODD;
+               } else if (Seq == 2 || Seq == 4) {
+                       if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY) {
+                               *Machine = AUTH_STATE_MACHINE;
+                               *MsgType = MT2_PEER_AUTH_EVEN;
+                       }
+               } else {
+                       return FALSE;
+               }
+               break;
+       case SUBTYPE_DEAUTH:
+               *Machine = AUTH_RSP_STATE_MACHINE;
+               *MsgType = MT2_PEER_DEAUTH;
+               break;
+       case SUBTYPE_ACTION:
+               *Machine = ACTION_STATE_MACHINE;
+               /*  Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support */
+               if ((pFrame->Octet[0] & 0x7F) > MAX_PEER_CATE_MSG) {
+                       *MsgType = MT2_ACT_INVALID;
+               } else {
+                       *MsgType = (pFrame->Octet[0] & 0x7F);
+               }
+               break;
+       default:
+               return FALSE;
+               break;
+       }
 
-    Return Value:
-        None
+       return TRUE;
+}
 
-    Note:
-        This routine will set the relative key stuff to Asic including WCID attribute,
-        Cipher Key, Cipher algorithm and IV/EIV.
+/* =========================================================================================== */
+/* state_machine.c */
+/* =========================================================================================== */
 
-        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.
+/*! \brief Initialize the state machine.
+ *     \param *S                       pointer to the state machine
+ *     \param  Trans           State machine transition function
+ *     \param  StNr            number of states
+ *     \param  MsgNr           number of messages
+ *     \param  DefFunc         default function, when there is invalid state/message combination
+ *     \param  InitState       initial state of the state machine
+ *     \param  Base            StateMachine base, internal use only
+ *     \pre p_sm should be a legal pointer
+ *     \post
 
-        If bTxKey sets to FALSE, this is not the TX key, but it could be
-        RX key
+ IRQL = PASSIVE_LEVEL
 
-       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)
+ */
+void StateMachineInit(struct rt_state_machine *S,
+                     IN STATE_MACHINE_FUNC Trans[],
+                     unsigned long StNr,
+                     unsigned long MsgNr,
+                     IN STATE_MACHINE_FUNC DefFunc,
+                     unsigned long InitState, unsigned long Base)
 {
-       ULONG   offset;
-       UCHAR   IV4 = 0;
-       PUCHAR          pKey = pCipherKey->Key;
-       PUCHAR          pTxMic = pCipherKey->TxMic;
-       PUCHAR          pRxMic = pCipherKey->RxMic;
-       PUCHAR          pTxtsc = pCipherKey->TxTsc;
-       UCHAR           CipherAlg = pCipherKey->CipherAlg;
-       SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
-       UCHAR           i;
-#endif
-
-       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 RT2860
-       for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
-       {
-               RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-       }
-#endif
-#ifdef RT2870
-       RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
-#endif
-       offset += MAX_LEN_OF_PEER_KEY;
-
-       //
-       // 3.) Set MIC key if available
-       //
-       if (pTxMic)
-       {
-#ifdef RT2860
-               for (i = 0; i < 8; i++)
-               {
-                       RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
-               }
-#endif
-#ifdef RT2870
-               RTUSBMultiWrite(pAd, offset, pTxMic, 8);
-#endif
-       }
-       offset += LEN_TKIP_TXMICK;
-
-       if (pRxMic)
-       {
-#ifdef RT2860
-               for (i = 0; i < 8; i++)
-               {
-                       RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
-               }
-#endif
-#ifdef RT2870
-               RTUSBMultiWrite(pAd, offset, pRxMic, 8);
-#endif
-       }
+       unsigned long i, j;
 
+       /* set number of states and messages */
+       S->NrState = StNr;
+       S->NrMsg = MsgNr;
+       S->Base = Base;
 
-       //
-       // 4.) Modify IV/EIV if needs
-       //     This will force Asic to use this key ID by setting IV.
-       //
-       if (bTxKey)
-       {
-#ifdef RT2860
-               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
-#ifdef RT2870
-               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 // RT2870 //
-               AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
-       }
+       S->TransFunc = Trans;
 
-       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;
+       /* init all state transition to default function */
+       for (i = 0; i < StNr; i++) {
+               for (j = 0; j < MsgNr; j++) {
+                       S->TransFunc[i * MsgNr + j] = DefFunc;
                }
-               RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
        }
 
-       DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
+       /* set the starting state */
+       S->CurrState = InitState;
 }
 
+/*! \brief This function fills in the function pointer into the cell in the state machine
+ *     \param *S       pointer to the state machine
+ *     \param St       state
+ *     \param Msg      incoming message
+ *     \param f        the function to be executed when (state, message) combination occurs at the state machine
+ *     \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
+ *     \post
 
-/*
-       ========================================================================
-       Description:
-               Add Pair-wise key material into ASIC.
-               Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
+ IRQL = PASSIVE_LEVEL
 
-    Return:
-       ========================================================================
-*/
-VOID AsicAddPairwiseKeyEntry(
-       IN PRTMP_ADAPTER pAd,
-       IN PUCHAR        pAddr,
-       IN UCHAR                WCID,
-       IN CIPHER_KEY            *pCipherKey)
+ */
+void StateMachineSetAction(struct rt_state_machine *S,
+                          unsigned long St,
+                          unsigned long Msg, IN STATE_MACHINE_FUNC Func)
 {
-       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 RT2860
-       for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
-       {
-               RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-       }
-#endif
-#ifdef RT2870
-       RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
-#endif // RT2870 //
-       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;
+       unsigned long MsgIdx;
 
-       //  MIC KEY
-       if (pTxMic)
-       {
-#ifdef RT2860
-               for (i=0; i<8; i++)
-               {
-                       RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
-               }
-#endif
-#ifdef RT2870
-               RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
-#endif // RT2870 //
-       }
-       offset += 8;
-       if (pRxMic)
-       {
-#ifdef RT2860
-               for (i=0; i<8; i++)
-               {
-                       RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
-               }
-#endif
-#ifdef RT2870
-               RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
-#endif // RT2870 //
-       }
+       MsgIdx = Msg - S->Base;
 
-       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]));
+       if (St < S->NrState && MsgIdx < S->NrMsg) {
+               /* boundary checking before setting the action */
+               S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
        }
 }
-/*
-       ========================================================================
-       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;
+/*! \brief      This function does the state transition
+ *     \param   *Adapter the NIC adapter pointer
+ *     \param   *S       the state machine
+ *     \param   *Elem    the message to be executed
+ *     \return   None
 
-       // 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);
-}
+ IRQL = DISPATCH_LEVEL
 
-BOOLEAN AsicSendCommandToMcu(
-       IN PRTMP_ADAPTER pAd,
-       IN UCHAR                 Command,
-       IN UCHAR                 Token,
-       IN UCHAR                 Arg0,
-       IN UCHAR                 Arg1)
+ */
+void StateMachinePerformAction(struct rt_rtmp_adapter *pAd,
+                              struct rt_state_machine *S, struct rt_mlme_queue_elem *Elem)
 {
-       HOST_CMD_CSR_STRUC      H2MCmd;
-       H2M_MAILBOX_STRUC       H2MMailbox;
-       ULONG                           i = 0;
-
-       do
-       {
-               RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
-               if (H2MMailbox.field.Owner == 0)
-                       break;
-
-               RTMPusecDelay(2);
-       } while(i++ < 100);
+       (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))
+           (pAd, Elem);
+}
 
-       if (i > 100)
-       {
-               {
-#ifdef RT2860
-                       UINT32 Data;
-
-                       // Reset DMA
-                       RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-                       Data |= 0x2;
-                       RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-                       // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
-                       // Reset DMA/CPU ring index
-                       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);
-
-                       // Clear Reset
-                       RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-                       Data &= 0xfffffffd;
-                       RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-#endif /* RT2860 */
-               DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
-               }
-               //return FALSE;
-#ifdef RT2870
-               return FALSE;
-#endif
-       }
+/*
+       ==========================================================================
+       Description:
+               The drop function, when machine executes this, the message is simply
+               ignored. This function does nothing, the message is freed in
+               StateMachinePerformAction()
+       ==========================================================================
+ */
+void Drop(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
 
-       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);
+/* =========================================================================================== */
+/* lfsr.c */
+/* =========================================================================================== */
 
-       H2MCmd.word                       = 0;
-       H2MCmd.field.HostCommand  = Command;
-       RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+/*
+       ==========================================================================
+       Description:
 
-       if (Command != 0x80)
-       {
-       }
+       IRQL = PASSIVE_LEVEL
 
-       return TRUE;
+       ==========================================================================
+ */
+void LfsrInit(struct rt_rtmp_adapter *pAd, unsigned long Seed)
+{
+       if (Seed == 0)
+               pAd->Mlme.ShiftReg = 1;
+       else
+               pAd->Mlme.ShiftReg = Seed;
 }
 
-#ifdef RT2860
-BOOLEAN AsicCheckCommanOk(
-       IN PRTMP_ADAPTER pAd,
-       IN UCHAR                 Command)
+/*
+       ==========================================================================
+       Description:
+       ==========================================================================
+ */
+u8 RandomByte(struct rt_rtmp_adapter *pAd)
 {
-       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;
-               }
+       unsigned long i;
+       u8 R, Result;
 
-               RTMPusecDelay(100);
-               i++;
-       }while (i < 200);
+       R = 0;
 
-       // Get CommandStatus Value
-       RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
+       if (pAd->Mlme.ShiftReg == 0)
+               NdisGetSystemUpTime((unsigned long *) & pAd->Mlme.ShiftReg);
 
-       // 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;
+       for (i = 0; i < 8; i++) {
+               if (pAd->Mlme.ShiftReg & 0x00000001) {
+                       pAd->Mlme.ShiftReg =
+                           ((pAd->Mlme.
+                             ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
+                       Result = 1;
+               } else {
+                       pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
+                       Result = 0;
                }
-               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));
+               R = (R << 1) | Result;
        }
-       // Clear Command and Status.
-       RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-       RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
 
-       return FALSE;
+       return R;
 }
-#endif /* RT8260 */
 
 /*
        ========================================================================
@@ -7662,13 +5244,11 @@ BOOLEAN AsicCheckCommanOk(
 
        ========================================================================
 */
-VOID   RTMPCheckRates(
-       IN              PRTMP_ADAPTER   pAd,
-       IN OUT  UCHAR                   SupRate[],
-       IN OUT  UCHAR                   *SupRateLen)
+void RTMPCheckRates(struct rt_rtmp_adapter *pAd,
+                   IN u8 SupRate[], IN u8 * SupRateLen)
 {
-       UCHAR   RateIdx, i, j;
-       UCHAR   NewRate[12], NewRateLen;
+       u8 RateIdx, i, j;
+       u8 NewRate[12], NewRateLen;
 
        NewRateLen = 0;
 
@@ -7677,7 +5257,7 @@ VOID      RTMPCheckRates(
        else
                RateIdx = 12;
 
-       // Check for support rates exclude basic rate bit
+       /* Check for support rates exclude basic rate bit */
        for (i = 0; i < *SupRateLen; i++)
                for (j = 0; j < RateIdx; j++)
                        if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
@@ -7687,43 +5267,37 @@ VOID    RTMPCheckRates(
        NdisMoveMemory(SupRate, NewRate, NewRateLen);
 }
 
-BOOLEAN RTMPCheckChannel(
-       IN PRTMP_ADAPTER pAd,
-       IN UCHAR                CentralChannel,
-       IN UCHAR                Channel)
+BOOLEAN RTMPCheckChannel(struct rt_rtmp_adapter *pAd,
+                        u8 CentralChannel, u8 Channel)
 {
-       UCHAR           k;
-       UCHAR           UpperChannel = 0, LowerChannel = 0;
-       UCHAR           NoEffectChannelinList = 0;
+       u8 k;
+       u8 UpperChannel = 0, LowerChannel = 0;
+       u8 NoEffectChannelinList = 0;
 
-       // Find upper and lower channel according to 40MHz current operation.
-       if (CentralChannel < Channel)
-       {
+       /* Find upper and lower channel according to 40MHz current operation. */
+       if (CentralChannel < Channel) {
                UpperChannel = Channel;
                if (CentralChannel > 2)
                        LowerChannel = CentralChannel - 2;
                else
                        return FALSE;
-       }
-       else if (CentralChannel > Channel)
-       {
+       } else if (CentralChannel > Channel) {
                UpperChannel = CentralChannel + 2;
                LowerChannel = Channel;
        }
 
-       for (k = 0;k < pAd->ChannelListNum;k++)
-       {
-               if (pAd->ChannelList[k].Channel == UpperChannel)
-               {
-                       NoEffectChannelinList ++;
+       for (k = 0; k < pAd->ChannelListNum; k++) {
+               if (pAd->ChannelList[k].Channel == UpperChannel) {
+                       NoEffectChannelinList++;
                }
-               if (pAd->ChannelList[k].Channel == LowerChannel)
-               {
-                       NoEffectChannelinList ++;
+               if (pAd->ChannelList[k].Channel == LowerChannel) {
+                       NoEffectChannelinList++;
                }
        }
 
-       DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("Total Channel in Channel List = [%d]\n",
+                 NoEffectChannelinList));
        if (NoEffectChannelinList == 2)
                return TRUE;
        else
@@ -7746,88 +5320,114 @@ BOOLEAN RTMPCheckChannel(
 
        ========================================================================
 */
-BOOLEAN        RTMPCheckHt(
-       IN      PRTMP_ADAPTER                   pAd,
-       IN      UCHAR                                   Wcid,
-       IN      HT_CAPABILITY_IE                *pHtCapability,
-       IN      ADD_HT_INFO_IE                  *pAddHtInfo)
+BOOLEAN RTMPCheckHt(struct rt_rtmp_adapter *pAd,
+                   u8 Wcid,
+                   struct rt_ht_capability_ie * pHtCapability,
+                   struct rt_add_ht_info_ie * pAddHtInfo)
 {
        if (Wcid >= MAX_LEN_OF_MAC_TABLE)
                return FALSE;
 
-       // If use AMSDU, set flag.
+       /* If use AMSDU, set flag. */
        if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
-               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
-       // Save Peer Capability
+               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+                                      fCLIENT_STATUS_AMSDU_INUSED);
+       /* Save Peer Capability */
        if (pHtCapability->HtCapInfo.ShortGIfor20)
-               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
+               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+                                      fCLIENT_STATUS_SGI20_CAPABLE);
        if (pHtCapability->HtCapInfo.ShortGIfor40)
-               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
+               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+                                      fCLIENT_STATUS_SGI40_CAPABLE);
        if (pHtCapability->HtCapInfo.TxSTBC)
-               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
+               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+                                      fCLIENT_STATUS_TxSTBC_CAPABLE);
        if (pHtCapability->HtCapInfo.RxSTBC)
-               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
-       if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
-       {
-               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
+               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+                                      fCLIENT_STATUS_RxSTBC_CAPABLE);
+       if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport) {
+               CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
+                                      fCLIENT_STATUS_RDG_CAPABLE);
        }
 
-       if (Wcid < MAX_LEN_OF_MAC_TABLE)
-       {
-               pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+       if (Wcid < MAX_LEN_OF_MAC_TABLE) {
+               pAd->MacTab.Content[Wcid].MpduDensity =
+                   pHtCapability->HtCapParm.MpduDensity;
        }
-
-       // Will check ChannelWidth for MCSSet[4] below
+       /* Will check ChannelWidth for MCSSet[4] below */
        pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
-    switch (pAd->CommonCfg.RxStream)
-       {
-               case 1:
-                       pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-                       pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
-            pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
-            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-                       break;
-               case 2:
-                       pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-                       pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
-            pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
-            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-                       break;
-               case 3:
-                       pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-                       pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
-            pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
-            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-                       break;
-       }
-
-       pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
-
-    DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
-               pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
-               pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
-
-       pAd->MlmeAux.HtCapability.HtCapInfo.GF =  pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
-
-       // Send Assoc Req with my HT capability.
-       pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize =  pAd->CommonCfg.DesiredHtPhy.AmsduSize;
-       pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs =  pAd->CommonCfg.DesiredHtPhy.MimoPs;
-       pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
-       pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
-       pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC =  (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
-       pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC =  (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
-       pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
-    pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
-       pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
-       pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
-       if (pAd->CommonCfg.bRdg)
-       {
-               pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
-        pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
-       }
-
-    if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
-        pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0;  // BW20 can't transmit MCS32
+       switch (pAd->CommonCfg.RxStream) {
+       case 1:
+               pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+               pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
+               pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+               pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+               break;
+       case 2:
+               pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+               pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+               pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+               pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+               break;
+       case 3:
+               pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+               pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+               pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
+               pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+               break;
+       }
+
+       pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth =
+           pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.
+           ChannelWidth;
+
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
+                 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth,
+                 pAddHtInfo->AddHtInfo.RecomWidth,
+                 pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
+                 pAd->NicConfig2.field.BW40MAvailForA,
+                 pAd->NicConfig2.field.BW40MAvailForG,
+                 pAd->CommonCfg.PhyMode));
+
+       pAd->MlmeAux.HtCapability.HtCapInfo.GF =
+           pHtCapability->HtCapInfo.GF & pAd->CommonCfg.DesiredHtPhy.GF;
+
+       /* Send Assoc Req with my HT capability. */
+       pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize =
+           pAd->CommonCfg.DesiredHtPhy.AmsduSize;
+       pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs =
+           pAd->CommonCfg.DesiredHtPhy.MimoPs;
+       pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 =
+           (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->
+                                                         HtCapInfo.
+                                                         ShortGIfor20);
+       pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 =
+           (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->
+                                                         HtCapInfo.
+                                                         ShortGIfor40);
+       pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC =
+           (pAd->CommonCfg.DesiredHtPhy.TxSTBC) & (pHtCapability->HtCapInfo.
+                                                   RxSTBC);
+       pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC =
+           (pAd->CommonCfg.DesiredHtPhy.RxSTBC) & (pHtCapability->HtCapInfo.
+                                                   TxSTBC);
+       pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor =
+           pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
+       pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity =
+           pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
+       pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC =
+           pHtCapability->ExtHtCapInfo.PlusHTC;
+       pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC =
+           pHtCapability->ExtHtCapInfo.PlusHTC;
+       if (pAd->CommonCfg.bRdg) {
+               pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport =
+                   pHtCapability->ExtHtCapInfo.RDGSupport;
+               pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
+       }
+
+       if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
+               pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0;      /* BW20 can't transmit MCS32 */
 
        COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
        return TRUE;
@@ -7845,69 +5445,64 @@ BOOLEAN         RTMPCheckHt(
        Return Value:
                None
 
-       IRQL = PASSIVE_LEVEL
-
-       ========================================================================
-*/
-VOID RTMPUpdateMlmeRate(
-       IN PRTMP_ADAPTER        pAd)
-{
-       UCHAR   MinimumRate;
-       UCHAR   ProperMlmeRate; //= RATE_54;
-       UCHAR   i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
-       BOOLEAN bMatch = FALSE;
-
-       switch (pAd->CommonCfg.PhyMode)
-       {
-               case PHY_11B:
-                       ProperMlmeRate = RATE_11;
-                       MinimumRate = RATE_1;
-                       break;
-               case PHY_11BG_MIXED:
-               case PHY_11ABGN_MIXED:
-               case PHY_11BGN_MIXED:
-                       if ((pAd->MlmeAux.SupRateLen == 4) &&
-                               (pAd->MlmeAux.ExtRateLen == 0))
-                               // B only AP
-                               ProperMlmeRate = RATE_11;
-                       else
-                               ProperMlmeRate = RATE_24;
+       IRQL = PASSIVE_LEVEL
 
-                       if (pAd->MlmeAux.Channel <= 14)
-                               MinimumRate = RATE_1;
-                       else
-                               MinimumRate = RATE_6;
-                       break;
-               case PHY_11A:
-               case PHY_11N_2_4G:      // rt2860 need to check mlmerate for 802.11n
-               case PHY_11GN_MIXED:
-               case PHY_11AGN_MIXED:
-               case PHY_11AN_MIXED:
-               case PHY_11N_5G:
+       ========================================================================
+*/
+void RTMPUpdateMlmeRate(struct rt_rtmp_adapter *pAd)
+{
+       u8 MinimumRate;
+       u8 ProperMlmeRate;      /*= RATE_54; */
+       u8 i, j, RateIdx = 12;  /*1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
+       BOOLEAN bMatch = FALSE;
+
+       switch (pAd->CommonCfg.PhyMode) {
+       case PHY_11B:
+               ProperMlmeRate = RATE_11;
+               MinimumRate = RATE_1;
+               break;
+       case PHY_11BG_MIXED:
+       case PHY_11ABGN_MIXED:
+       case PHY_11BGN_MIXED:
+               if ((pAd->MlmeAux.SupRateLen == 4) &&
+                   (pAd->MlmeAux.ExtRateLen == 0))
+                       /* B only AP */
+                       ProperMlmeRate = RATE_11;
+               else
                        ProperMlmeRate = RATE_24;
+
+               if (pAd->MlmeAux.Channel <= 14)
+                       MinimumRate = RATE_1;
+               else
                        MinimumRate = RATE_6;
-                       break;
-               case PHY_11ABG_MIXED:
-                       ProperMlmeRate = RATE_24;
-                       if (pAd->MlmeAux.Channel <= 14)
-                          MinimumRate = RATE_1;
-                       else
-                               MinimumRate = RATE_6;
-                       break;
-               default: // error
-                       ProperMlmeRate = RATE_1;
+               break;
+       case PHY_11A:
+       case PHY_11N_2_4G:      /* rt2860 need to check mlmerate for 802.11n */
+       case PHY_11GN_MIXED:
+       case PHY_11AGN_MIXED:
+       case PHY_11AN_MIXED:
+       case PHY_11N_5G:
+               ProperMlmeRate = RATE_24;
+               MinimumRate = RATE_6;
+               break;
+       case PHY_11ABG_MIXED:
+               ProperMlmeRate = RATE_24;
+               if (pAd->MlmeAux.Channel <= 14)
                        MinimumRate = RATE_1;
-                       break;
-       }
-
-       for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
-       {
-               for (j = 0; j < RateIdx; j++)
-               {
-                       if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
-                       {
-                               if (j == ProperMlmeRate)
-                               {
+               else
+                       MinimumRate = RATE_6;
+               break;
+       default:                /* error */
+               ProperMlmeRate = RATE_1;
+               MinimumRate = RATE_1;
+               break;
+       }
+
+       for (i = 0; i < pAd->MlmeAux.SupRateLen; i++) {
+               for (j = 0; j < RateIdx; j++) {
+                       if ((pAd->MlmeAux.SupRate[i] & 0x7f) ==
+                           RateIdTo500Kbps[j]) {
+                               if (j == ProperMlmeRate) {
                                        bMatch = TRUE;
                                        break;
                                }
@@ -7918,16 +5513,12 @@ VOID RTMPUpdateMlmeRate(
                        break;
        }
 
-       if (bMatch == FALSE)
-       {
-               for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
-               {
-                       for (j = 0; j < RateIdx; j++)
-                       {
-                               if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
-                               {
-                                       if (j == ProperMlmeRate)
-                                       {
+       if (bMatch == FALSE) {
+               for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++) {
+                       for (j = 0; j < RateIdx; j++) {
+                               if ((pAd->MlmeAux.ExtRate[i] & 0x7f) ==
+                                   RateIdTo500Kbps[j]) {
+                                       if (j == ProperMlmeRate) {
                                                bMatch = TRUE;
                                                break;
                                        }
@@ -7939,51 +5530,48 @@ VOID RTMPUpdateMlmeRate(
                }
        }
 
-       if (bMatch == FALSE)
-       {
+       if (bMatch == FALSE) {
                ProperMlmeRate = MinimumRate;
        }
 
        pAd->CommonCfg.MlmeRate = MinimumRate;
        pAd->CommonCfg.RtsRate = ProperMlmeRate;
-       if (pAd->CommonCfg.MlmeRate >= RATE_6)
-       {
+       if (pAd->CommonCfg.MlmeRate >= RATE_6) {
                pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-               pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-               pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
-               pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-       }
-       else
-       {
+               pAd->CommonCfg.MlmeTransmit.field.MCS =
+                   OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+               pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
+                   MODE_OFDM;
+               pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
+                   OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+       } else {
                pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
                pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
-               pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
-               pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
+               pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
+                   MODE_CCK;
+               pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
+                   pAd->CommonCfg.MlmeRate;
        }
 
-       DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==>   MlmeTransmit = 0x%x  \n" , pAd->CommonCfg.MlmeTransmit.word));
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("RTMPUpdateMlmeRate ==>   MlmeTransmit = 0x%x  \n",
+                 pAd->CommonCfg.MlmeTransmit.word));
 }
 
-CHAR RTMPMaxRssi(
-       IN PRTMP_ADAPTER        pAd,
-       IN CHAR                         Rssi0,
-       IN CHAR                         Rssi1,
-       IN CHAR                         Rssi2)
+char RTMPMaxRssi(struct rt_rtmp_adapter *pAd,
+                char Rssi0, char Rssi1, char Rssi2)
 {
-       CHAR    larger = -127;
+       char larger = -127;
 
-       if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
-       {
+       if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0)) {
                larger = Rssi0;
        }
 
-       if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
-       {
+       if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0)) {
                larger = max(Rssi0, Rssi1);
        }
 
-       if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
-       {
+       if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0)) {
                larger = max(larger, Rssi2);
        }
 
@@ -7993,56 +5581,6 @@ CHAR RTMPMaxRssi(
        return larger;
 }
 
-#ifdef RT2870
-// 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
-VOID AsicSetRxAnt(
-       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
-               RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-               x |= (EESK);
-               RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-               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
-               RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-               x &= ~(EESK);
-               RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-               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"));
-       }
-}
-#endif
-
 /*
     ========================================================================
     Routine Description:
@@ -8056,91 +5594,70 @@ VOID AsicSetRxAnt(
 
     ========================================================================
 */
-VOID AsicEvaluateRxAnt(
-       IN PRTMP_ADAPTER        pAd)
+void AsicEvaluateRxAnt(struct rt_rtmp_adapter *pAd)
 {
-       UCHAR   BBPR3 = 0;
+       u8 BBPR3 = 0;
 
        if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
-                               fRTMP_ADAPTER_HALT_IN_PROGRESS |
-                               fRTMP_ADAPTER_RADIO_OFF |
-                               fRTMP_ADAPTER_NIC_NOT_EXIST |
-                               fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)
-                               || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT2870
-                               || (pAd->EepromAccess)
-#endif
-                               )
-                       return;
-
+                          fRTMP_ADAPTER_HALT_IN_PROGRESS |
+                          fRTMP_ADAPTER_RADIO_OFF |
+                          fRTMP_ADAPTER_NIC_NOT_EXIST |
+                          fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
+           OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
 #ifdef RT30xx
-       // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
-       // one is antenna diversity:there is only one antenna can rx and tx
-       // the other is failed antenna remove:two physical antenna can rx and tx
-       if (pAd->NicConfig2.field.AntDiversity)
-       {
-               DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
-                       pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
-
-               AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
-
-               pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
-               pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
-               pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
+           || (pAd->EepromAccess)
+#endif /* RT30xx // */
+#ifdef RT3090
+           || (pAd->bPCIclkOff == TRUE)
+#endif /* RT3090 // */
+           )
+               return;
 
-               // a one-shot timer to end the evalution
-               // dynamic adjust antenna evaluation period according to the traffic
-               if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-                       RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
-               else
-                       RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
-       }
-       else
-#endif
        {
-               if (pAd->StaCfg.Psm == PWR_SAVE)
-                       return;
+               /*if (pAd->StaCfg.Psm == PWR_SAVE) */
+               /*      return; */
 
-               RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
-               BBPR3 &= (~0x18);
-               if(pAd->Antenna.field.RxPath == 3)
-               {
-                       BBPR3 |= (0x10);
-               }
-               else if(pAd->Antenna.field.RxPath == 2)
-               {
-                       BBPR3 |= (0x8);
-               }
-               else if(pAd->Antenna.field.RxPath == 1)
                {
-                       BBPR3 |= (0x0);
-               }
-               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-
-#ifdef RT2860
-               pAd->StaCfg.BBPR3 = BBPR3;
-#endif
-       }
 
-       if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-               )
-       {
-               ULONG   TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-                                                               pAd->RalinkCounters.OneSecTxRetryOkCount +
-                                                               pAd->RalinkCounters.OneSecTxFailCount;
+                       if (pAd->StaCfg.Psm == PWR_SAVE)
+                               return;
 
-                       // dynamic adjust antenna evaluation period according to the traffic
-               if (TxTotalCnt > 50)
-               {
-                       RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
-                       pAd->Mlme.bLowThroughput = FALSE;
-               }
-               else
-               {
-                       RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
-                       pAd->Mlme.bLowThroughput = TRUE;
+                       RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+                       BBPR3 &= (~0x18);
+                       if (pAd->Antenna.field.RxPath == 3) {
+                               BBPR3 |= (0x10);
+                       } else if (pAd->Antenna.field.RxPath == 2) {
+                               BBPR3 |= (0x8);
+                       } else if (pAd->Antenna.field.RxPath == 1) {
+                               BBPR3 |= (0x0);
+                       }
+                       RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+#ifdef RTMP_MAC_PCI
+                       pAd->StaCfg.BBPR3 = BBPR3;
+#endif /* RTMP_MAC_PCI // */
+                       if (OPSTATUS_TEST_FLAG
+                           (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+                           ) {
+                               unsigned long TxTotalCnt =
+                                   pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+                                   pAd->RalinkCounters.OneSecTxRetryOkCount +
+                                   pAd->RalinkCounters.OneSecTxFailCount;
+
+                               /* dynamic adjust antenna evaluation period according to the traffic */
+                               if (TxTotalCnt > 50) {
+                                       RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer,
+                                                    20);
+                                       pAd->Mlme.bLowThroughput = FALSE;
+                               } else {
+                                       RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer,
+                                                    300);
+                                       pAd->Mlme.bLowThroughput = TRUE;
+                               }
+                       }
                }
+
        }
+
 }
 
 /*
@@ -8156,90 +5673,54 @@ VOID AsicEvaluateRxAnt(
 
     ========================================================================
 */
-VOID AsicRxAntEvalTimeout(
-       IN PVOID SystemSpecific1,
-       IN PVOID FunctionContext,
-       IN PVOID SystemSpecific2,
-       IN PVOID SystemSpecific3)
+void AsicRxAntEvalTimeout(void *SystemSpecific1,
+                         void *FunctionContext,
+                         void *SystemSpecific2, void *SystemSpecific3)
 {
-       RTMP_ADAPTER    *pAd = (RTMP_ADAPTER *)FunctionContext;
-       UCHAR                   BBPR3 = 0;
-       CHAR                    larger = -127, rssi0, rssi1, rssi2;
-
-       if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
-                                                       fRTMP_ADAPTER_HALT_IN_PROGRESS  |
-                                                       fRTMP_ADAPTER_RADIO_OFF                 |
-                                                       fRTMP_ADAPTER_NIC_NOT_EXIST)
-                                                       || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT2870
-                                                       || (pAd->EepromAccess)
-#endif
-                                                       )
-               return;
+       struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
+       u8 BBPR3 = 0;
+       char larger = -127, rssi0, rssi1, rssi2;
 
-       {
+       if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
+                          fRTMP_ADAPTER_HALT_IN_PROGRESS |
+                          fRTMP_ADAPTER_RADIO_OFF |
+                          fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+           OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
 #ifdef RT30xx
-               if (pAd->NicConfig2.field.AntDiversity)
-               {
-                       if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
-                       {
-                               UCHAR                   temp;
-
-                               //
-                               // select PrimaryRxAntPair
-                               //    Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
-                               //    Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
-                               //
-                               temp = pAd->RxAnt.Pair1PrimaryRxAnt;
-                               pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
-                               pAd->RxAnt.Pair1SecondaryRxAnt = temp;
-
-                               pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
-                               pAd->RxAnt.EvaluateStableCnt = 0;
-                       }
-                       else
-                       {
-                               // if the evaluated antenna is not better than original, switch back to original antenna
-                               AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-                               pAd->RxAnt.EvaluateStableCnt ++;
-                       }
-
-                       pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
+           || (pAd->EepromAccess)
+#endif /* RT30xx // */
+#ifdef RT3090
+           || (pAd->bPCIclkOff == TRUE)
+#endif /* RT3090 // */
+           )
+               return;
 
-                       DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
-                                       pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
-               }
-               else
-#endif
+       {
+               /*if (pAd->StaCfg.Psm == PWR_SAVE) */
+               /*      return; */
                {
                        if (pAd->StaCfg.Psm == PWR_SAVE)
                                return;
 
-                       // if the traffic is low, use average rssi as the criteria
-                       if (pAd->Mlme.bLowThroughput == TRUE)
-                       {
+                       /* if the traffic is low, use average rssi as the criteria */
+                       if (pAd->Mlme.bLowThroughput == TRUE) {
                                rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
                                rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
                                rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
-                       }
-                       else
-                       {
+                       } else {
                                rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
                                rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
                                rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
                        }
 
-                       if(pAd->Antenna.field.RxPath == 3)
-                       {
+                       if (pAd->Antenna.field.RxPath == 3) {
                                larger = max(rssi0, rssi1);
 
                                if (larger > (rssi2 + 20))
                                        pAd->Mlme.RealRxPath = 2;
                                else
                                        pAd->Mlme.RealRxPath = 3;
-                       }
-                       else if(pAd->Antenna.field.RxPath == 2)
-                       {
+                       } else if (pAd->Antenna.field.RxPath == 2) {
                                if (rssi0 > (rssi1 + 20))
                                        pAd->Mlme.RealRxPath = 1;
                                else
@@ -8248,39 +5729,45 @@ VOID AsicRxAntEvalTimeout(
 
                        RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
                        BBPR3 &= (~0x18);
-                       if(pAd->Mlme.RealRxPath == 3)
-                       {
+                       if (pAd->Mlme.RealRxPath == 3) {
                                BBPR3 |= (0x10);
-                       }
-                       else if(pAd->Mlme.RealRxPath == 2)
-                       {
+                       } else if (pAd->Mlme.RealRxPath == 2) {
                                BBPR3 |= (0x8);
-                       }
-                       else if(pAd->Mlme.RealRxPath == 1)
-                       {
+                       } else if (pAd->Mlme.RealRxPath == 1) {
                                BBPR3 |= (0x0);
                        }
                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RT2860
+#ifdef RTMP_MAC_PCI
                        pAd->StaCfg.BBPR3 = BBPR3;
-#endif
+#endif /* RTMP_MAC_PCI // */
                }
        }
+
 }
 
-VOID APSDPeriodicExec(
-       IN PVOID SystemSpecific1,
-       IN PVOID FunctionContext,
-       IN PVOID SystemSpecific2,
-       IN PVOID SystemSpecific3)
+void APSDPeriodicExec(void *SystemSpecific1,
+                     void *FunctionContext,
+                     void *SystemSpecific2, void *SystemSpecific3)
 {
-       RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+       struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
 
        if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
                return;
 
        pAd->CommonCfg.TriggerTimerCount++;
 
+/* Driver should not send trigger frame, it should be send by application layer */
+/*
+       if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
+               && (pAd->CommonCfg.bNeedSendTriggerFrame ||
+               (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
+       {
+               DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
+               RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+               pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
+               pAd->CommonCfg.TriggerTimerCount = 0;
+               pAd->CommonCfg.bInServicePeriod = TRUE;
+       }*/
 }
 
 /*
@@ -8297,11 +5784,9 @@ VOID APSDPeriodicExec(
 
     ========================================================================
 */
-VOID RTMPSetPiggyBack(
-    IN PRTMP_ADAPTER    pAd,
-    IN BOOLEAN          bPiggyBack)
+void RTMPSetPiggyBack(struct rt_rtmp_adapter *pAd, IN BOOLEAN bPiggyBack)
 {
-       TX_LINK_CFG_STRUC  TxLinkCfg;
+       TX_LINK_CFG_STRUC TxLinkCfg;
 
        RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
 
@@ -8324,36 +5809,32 @@ VOID RTMPSetPiggyBack(
 
     ========================================================================
 */
-BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
-       IN PRTMP_ADAPTER    pAd,
-       IN PMAC_TABLE_ENTRY     pEntry)
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(struct rt_rtmp_adapter *pAd,
+                                          struct rt_mac_table_entry *pEntry)
 {
-       BOOLEAN         result = TRUE;
+       BOOLEAN result = TRUE;
 
        {
-               // only associated STA counts
-               if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
-               {
+               /* only associated STA counts */
+               if (pEntry && (pEntry->ValidAsCLI)
+                   && (pEntry->Sst == SST_ASSOC)) {
                        result = pAd->StaCfg.bAutoTxRateSwitch;
-               }
-               else
+               } else
                        result = FALSE;
        }
 
        return result;
 }
 
-
-BOOLEAN RTMPAutoRateSwitchCheck(
-       IN PRTMP_ADAPTER    pAd)
+BOOLEAN RTMPAutoRateSwitchCheck(struct rt_rtmp_adapter *pAd)
 {
-       if (pAd->StaCfg.bAutoTxRateSwitch)
-               return TRUE;
-
+       {
+               if (pAd->StaCfg.bAutoTxRateSwitch)
+                       return TRUE;
+       }
        return FALSE;
 }
 
-
 /*
     ========================================================================
     Routine Description:
@@ -8369,13 +5850,15 @@ BOOLEAN RTMPAutoRateSwitchCheck(
 
     ========================================================================
 */
-UCHAR RTMPStaFixedTxMode(
-       IN PRTMP_ADAPTER    pAd,
-       IN PMAC_TABLE_ENTRY     pEntry)
+u8 RTMPStaFixedTxMode(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
 {
-       UCHAR   tx_mode = FIXED_TXMODE_HT;
+       u8 tx_mode = FIXED_TXMODE_HT;
 
-       tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
+       {
+               tx_mode =
+                   (u8)pAd->StaCfg.DesiredTransmitSetting.field.
+                   FixedTxMode;
+       }
 
        return tx_mode;
 }
@@ -8395,9 +5878,7 @@ UCHAR RTMPStaFixedTxMode(
 
     ========================================================================
 */
-VOID RTMPUpdateLegacyTxSetting(
-               UCHAR                           fixed_tx_mode,
-               PMAC_TABLE_ENTRY        pEntry)
+void RTMPUpdateLegacyTxSetting(u8 fixed_tx_mode, struct rt_mac_table_entry *pEntry)
 {
        HTTRANSMIT_SETTING TransmitSetting;
 
@@ -8409,26 +5890,24 @@ VOID RTMPUpdateLegacyTxSetting(
        TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
        TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
 
-       if (fixed_tx_mode == FIXED_TXMODE_CCK)
-       {
+       if (fixed_tx_mode == FIXED_TXMODE_CCK) {
                TransmitSetting.field.MODE = MODE_CCK;
-               // CCK mode allow MCS 0~3
+               /* CCK mode allow MCS 0~3 */
                if (TransmitSetting.field.MCS > MCS_3)
                        TransmitSetting.field.MCS = MCS_3;
-       }
-       else
-       {
+       } else {
                TransmitSetting.field.MODE = MODE_OFDM;
-               // OFDM mode allow MCS 0~7
+               /* OFDM mode allow MCS 0~7 */
                if (TransmitSetting.field.MCS > MCS_7)
                        TransmitSetting.field.MCS = MCS_7;
        }
 
-       if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
-       {
+       if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE) {
                pEntry->HTPhyMode.word = TransmitSetting.word;
-               DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
-                               pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
+                         pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE),
+                         pEntry->HTPhyMode.field.MCS));
        }
 }
 
@@ -8442,381 +5921,150 @@ VOID RTMPUpdateLegacyTxSetting(
 
        ==========================================================================
  */
-VOID AsicStaBbpTuning(
-       IN PRTMP_ADAPTER pAd)
+void AsicStaBbpTuning(struct rt_rtmp_adapter *pAd)
 {
-       UCHAR   OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
-       CHAR    Rssi;
+       u8 OrigR66Value = 0, R66;       /*, R66UpperBound = 0x30, R66LowerBound = 0x30; */
+       char Rssi;
 
-       // 2860C did not support Fase CCA, therefore can't tune
+       /* 2860C did not support Fase CCA, therefore can't tune */
        if (pAd->MACVersion == 0x28600100)
                return;
 
-       //
-       // work as a STA
-       //
-       if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)  // no R66 tuning when SCANNING
+       /* */
+       /* work as a STA */
+       /* */
+       if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)       /* no R66 tuning when SCANNING */
                return;
 
        if ((pAd->OpMode == OPMODE_STA)
-               && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-                       )
-               && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
-               && (pAd->bPCIclkOff == FALSE))
-#endif
-#ifdef RT2870
-               )
-#endif
-       {
+           && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+           )
+           && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+#ifdef RTMP_MAC_PCI
+           && (pAd->bPCIclkOff == FALSE)
+#endif /* RTMP_MAC_PCI // */
+           ) {
                RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
                R66 = OrigR66Value;
 
                if (pAd->Antenna.field.RxPath > 1)
-                       Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
+                       Rssi =
+                           (pAd->StaCfg.RssiSample.AvgRssi0 +
+                            pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
                else
                        Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
 
-               if (pAd->LatchRfRegs.Channel <= 14)
-               {       //BG band
-#ifdef RT2870
-                       // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
-                       // Otherwise, it will have some throughput side effect when low RSSI
-                       if (IS_RT30xx(pAd))
-                       {
-                               if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-                               {
-                                       R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
-                                       if (OrigR66Value != R66)
-                                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-                               }
-                               else
-                               {
-                                       R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
-                                       if (OrigR66Value != R66)
-                                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+               if (pAd->LatchRfRegs.Channel <= 14) {   /*BG band */
+#ifdef RT30xx
+                       /* RT3070 is a no LNA solution, it should have different control regarding to AGC gain control */
+                       /* Otherwise, it will have some throughput side effect when low RSSI */
+
+                       if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd)
+                           || IS_RT3390(pAd)) {
+                               if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
+                                       R66 =
+                                           0x1C + 2 * GET_LNA_GAIN(pAd) + 0x20;
+                                       if (OrigR66Value != R66) {
+                                               RTMP_BBP_IO_WRITE8_BY_REG_ID
+                                                   (pAd, BBP_R66, R66);
+                                       }
+                               } else {
+                                       R66 = 0x1C + 2 * GET_LNA_GAIN(pAd);
+                                       if (OrigR66Value != R66) {
+                                               RTMP_BBP_IO_WRITE8_BY_REG_ID
+                                                   (pAd, BBP_R66, R66);
+                                       }
                                }
-                       }
-                       else
-#endif // RT2870 //
+                       } else
+#endif /* RT30xx // */
                        {
-                               if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-                               {
+                               if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
                                        R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
-                                       if (OrigR66Value != R66)
-                                       {
-                                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+                                       if (OrigR66Value != R66) {
+                                               RTMP_BBP_IO_WRITE8_BY_REG_ID
+                                                   (pAd, BBP_R66, R66);
                                        }
-                               }
-                               else
-                               {
+                               } else {
                                        R66 = 0x2E + GET_LNA_GAIN(pAd);
-                                       if (OrigR66Value != R66)
-                                       {
-                                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+                                       if (OrigR66Value != R66) {
+                                               RTMP_BBP_IO_WRITE8_BY_REG_ID
+                                                   (pAd, BBP_R66, R66);
                                        }
                                }
                        }
-               }
-               else
-               {       //A band
-                       if (pAd->CommonCfg.BBPCurrentBW == BW_20)
-                       {
-                               if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-                               {
-                                       R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
-                                       if (OrigR66Value != R66)
-                                       {
-                                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+               } else {        /*A band */
+                       if (pAd->CommonCfg.BBPCurrentBW == BW_20) {
+                               if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
+                                       R66 =
+                                           0x32 + (GET_LNA_GAIN(pAd) * 5) / 3 +
+                                           0x10;
+                                       if (OrigR66Value != R66) {
+                                               RTMP_BBP_IO_WRITE8_BY_REG_ID
+                                                   (pAd, BBP_R66, R66);
                                        }
-                               }
-                               else
-                               {
-                                       R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
-                                       if (OrigR66Value != R66)
-                                       {
-                                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+                               } else {
+                                       R66 =
+                                           0x32 + (GET_LNA_GAIN(pAd) * 5) / 3;
+                                       if (OrigR66Value != R66) {
+                                               RTMP_BBP_IO_WRITE8_BY_REG_ID
+                                                   (pAd, BBP_R66, R66);
                                        }
                                }
-                       }
-                       else
-                       {
-                               if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
-                               {
-                                       R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
-                                       if (OrigR66Value != R66)
-                                       {
-                                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+                       } else {
+                               if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
+                                       R66 =
+                                           0x3A + (GET_LNA_GAIN(pAd) * 5) / 3 +
+                                           0x10;
+                                       if (OrigR66Value != R66) {
+                                               RTMP_BBP_IO_WRITE8_BY_REG_ID
+                                                   (pAd, BBP_R66, R66);
                                        }
-                               }
-                               else
-                               {
-                                       R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
-                                       if (OrigR66Value != R66)
-                                       {
-                                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+                               } else {
+                                       R66 =
+                                           0x3A + (GET_LNA_GAIN(pAd) * 5) / 3;
+                                       if (OrigR66Value != R66) {
+                                               RTMP_BBP_IO_WRITE8_BY_REG_ID
+                                                   (pAd, BBP_R66, R66);
                                        }
                                }
                        }
                }
 
-
-       }
-}
-
-#ifdef RT2860
-VOID AsicResetFromDMABusy(
-       IN PRTMP_ADAPTER pAd)
-{
-       UINT32          Data;
-       BOOLEAN         bCtrl = FALSE;
-
-       DBGPRINT(RT_DEBUG_TRACE, ("--->  AsicResetFromDMABusy  !!!!!!!!!!!!!!!!!!!!!!! \n"));
-
-       // Be sure restore link control value so we can write register.
-       RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-       if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
-       {
-               DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n"));
-               RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
-               RTMPusecDelay(6000);
-               pAd->bPCIclkOff = FALSE;
-               bCtrl = TRUE;
        }
-       // Reset DMA
-       RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-       Data |= 0x2;
-       RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-       // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
-       // Reset DMA/CPU ring index
-       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);
-
-       // Clear Reset
-       RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-       Data &= 0xfffffffd;
-       RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-       // If in Radio off, should call RTMPPCIePowerLinkCtrl again.
-       if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE))
-               RTMPPCIeLinkCtrlSetting(pAd, 3);
-
-       RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-       RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
-       DBGPRINT(RT_DEBUG_TRACE, ("<---  AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!!  \n"));
-}
-
-VOID AsicResetBBP(
-       IN PRTMP_ADAPTER pAd)
-{
-       DBGPRINT(RT_DEBUG_TRACE, ("--->  Asic HardReset BBP  !!!!!!!!!!!!!!!!!!!!!!! \n"));
-
-       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
-       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2);
-       RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
-
-       // After hard-reset BBP, initialize all BBP values.
-       NICRestoreBBPValue(pAd);
-       DBGPRINT(RT_DEBUG_TRACE, ("<---  Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!!  \n"));
-}
-
-VOID AsicResetMAC(
-       IN PRTMP_ADAPTER pAd)
-{
-       ULONG           Data;
-
-       DBGPRINT(RT_DEBUG_TRACE, ("--->  AsicResetMAC   !!!! \n"));
-       RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-       Data |= 0x4;
-       RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-       Data &= 0xfffffffb;
-       RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-       DBGPRINT(RT_DEBUG_TRACE, ("<---  AsicResetMAC   !!!! \n"));
 }
 
-VOID AsicResetPBF(
-       IN PRTMP_ADAPTER pAd)
+void RTMPSetAGCInitValue(struct rt_rtmp_adapter *pAd, u8 BandWidth)
 {
-       ULONG           Value1, Value2;
-       ULONG           Data;
+       u8 R66 = 0x30;
 
-       RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1);
-       RTMP_IO_READ32(pAd, PBF_DBG, &Value2);
-
-       Value2 &= 0xff;
-       // sum should be equals to 0xff, which is the total buffer size.
-       if ((Value1 + Value2) < 0xff)
-       {
-               DBGPRINT(RT_DEBUG_TRACE, ("--->  Asic HardReset PBF !!!! \n"));
-               RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
-               Data |= 0x8;
-               RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-               Data &= 0xfffffff7;
-               RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
-
-               DBGPRINT(RT_DEBUG_TRACE, ("<---  Asic HardReset PBF !!!! \n"));
-       }
-}
-#endif /* RT2860 */
-
-VOID RTMPSetAGCInitValue(
-       IN PRTMP_ADAPTER        pAd,
-       IN UCHAR                        BandWidth)
-{
-       UCHAR   R66 = 0x30;
+       if (pAd->LatchRfRegs.Channel <= 14) {   /* BG band */
+#ifdef RT30xx
+               /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */
 
-       if (pAd->LatchRfRegs.Channel <= 14)
-       {       // BG band
-               R66 = 0x2E + GET_LNA_GAIN(pAd);
-               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-       }
-       else
-       {       //A band
-               if (BandWidth == BW_20)
-               {
-                       R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
+               if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd)
+                   || IS_RT3390(pAd)) {
+                       R66 = 0x1C + 2 * GET_LNA_GAIN(pAd);
                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-               }
-               else
+               } else
+#endif /* RT30xx // */
                {
-                       R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
+                       R66 = 0x2E + GET_LNA_GAIN(pAd);
                        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
                }
-       }
-
-}
-
-VOID AsicTurnOffRFClk(
-       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;
-
-       // The RF programming sequence is difference between 3xxx and 2xxx
-       if (IS_RT3090(pAd))
-       {
-               RT30xxLoadRFSleepModeSetup(pAd);  // add by johnli,  RF power sequence setup, load RF sleep-mode setup
-               return;
-       }
-
-       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;
-                               }
+       } else {                /*A band */
+               {
+                       if (BandWidth == BW_20) {
+                               R66 =
+                                   (u8)(0x32 +
+                                            (GET_LNA_GAIN(pAd) * 5) / 3);
+                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+                       } else {
+                               R66 =
+                                   (u8)(0x3A +
+                                            (GET_LNA_GAIN(pAd) * 5) / 3);
+                               RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
                        }
-                       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;
-
-       // The RF programming sequence is difference between 3xxx and 2xxx
-       if (IS_RT3090(pAd))
-               return;
-
-       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));
 }
-
This page took 0.193727 seconds and 5 git commands to generate.