Staging: rt2860: Hoist assign from if
[safe/jmp/linux-2.6] / drivers / staging / rt2860 / common / cmm_wpa.c
index 8f29d31..c16f376 100644 (file)
        Paul Lin        03-11-28                Modify for supplicant
 */
 #include "../rt_config.h"
-// WPA OUI
-UCHAR          OUI_WPA_NONE_AKM[4]             = {0x00, 0x50, 0xF2, 0x00};
-UCHAR       OUI_WPA_VERSION[4]      = {0x00, 0x50, 0xF2, 0x01};
-UCHAR       OUI_WPA_WEP40[4]      = {0x00, 0x50, 0xF2, 0x01};
-UCHAR       OUI_WPA_TKIP[4]     = {0x00, 0x50, 0xF2, 0x02};
-UCHAR       OUI_WPA_CCMP[4]     = {0x00, 0x50, 0xF2, 0x04};
-UCHAR       OUI_WPA_WEP104[4]      = {0x00, 0x50, 0xF2, 0x05};
-UCHAR       OUI_WPA_8021X_AKM[4]       = {0x00, 0x50, 0xF2, 0x01};
-UCHAR       OUI_WPA_PSK_AKM[4]      = {0x00, 0x50, 0xF2, 0x02};
-// WPA2 OUI
-UCHAR       OUI_WPA2_WEP40[4]   = {0x00, 0x0F, 0xAC, 0x01};
-UCHAR       OUI_WPA2_TKIP[4]        = {0x00, 0x0F, 0xAC, 0x02};
-UCHAR       OUI_WPA2_CCMP[4]        = {0x00, 0x0F, 0xAC, 0x04};
-UCHAR       OUI_WPA2_8021X_AKM[4]   = {0x00, 0x0F, 0xAC, 0x01};
-UCHAR       OUI_WPA2_PSK_AKM[4]        = {0x00, 0x0F, 0xAC, 0x02};
-UCHAR       OUI_WPA2_WEP104[4]   = {0x00, 0x0F, 0xAC, 0x05};
-// MSA OUI
-UCHAR          OUI_MSA_8021X_AKM[4]    = {0x00, 0x0F, 0xAC, 0x05};             // Not yet final - IEEE 802.11s-D1.06
-UCHAR          OUI_MSA_PSK_AKM[4]      = {0x00, 0x0F, 0xAC, 0x06};             // Not yet final - IEEE 802.11s-D1.06
+/* WPA OUI */
+u8 OUI_WPA_NONE_AKM[4] = { 0x00, 0x50, 0xF2, 0x00 };
+u8 OUI_WPA_VERSION[4] = { 0x00, 0x50, 0xF2, 0x01 };
+u8 OUI_WPA_WEP40[4] = { 0x00, 0x50, 0xF2, 0x01 };
+u8 OUI_WPA_TKIP[4] = { 0x00, 0x50, 0xF2, 0x02 };
+u8 OUI_WPA_CCMP[4] = { 0x00, 0x50, 0xF2, 0x04 };
+u8 OUI_WPA_WEP104[4] = { 0x00, 0x50, 0xF2, 0x05 };
+u8 OUI_WPA_8021X_AKM[4] = { 0x00, 0x50, 0xF2, 0x01 };
+u8 OUI_WPA_PSK_AKM[4] = { 0x00, 0x50, 0xF2, 0x02 };
+
+/* WPA2 OUI */
+u8 OUI_WPA2_WEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 };
+u8 OUI_WPA2_TKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 };
+u8 OUI_WPA2_CCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 };
+u8 OUI_WPA2_8021X_AKM[4] = { 0x00, 0x0F, 0xAC, 0x01 };
+u8 OUI_WPA2_PSK_AKM[4] = { 0x00, 0x0F, 0xAC, 0x02 };
+u8 OUI_WPA2_WEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 };
+
+static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
+                                 u8 GroupKeyWepStatus,
+                                 u8 keyDescVer,
+                                 u8 MsgType,
+                                 u8 DefaultKeyIdx,
+                                 u8 * GTK,
+                                 u8 * RSNIE,
+                                 u8 RSNIE_LEN, struct rt_eapol_packet * pMsg);
+
+static void CalculateMIC(u8 KeyDescVer,
+                        u8 * PTK, struct rt_eapol_packet * pMsg);
+
+static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
+
+static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd,
+                                  struct rt_mlme_queue_elem *Elem);
+
+static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd,
+                                struct rt_mlme_queue_elem *Elem);
+
+static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd,
+                               struct rt_mlme_queue_elem *Elem);
+
+static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
+
+/*
+    ==========================================================================
+    Description:
+        association state machine init, including state transition and timer init
+    Parameters:
+        S - pointer to the association state machine
+    ==========================================================================
+ */
+void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
+                        struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
+{
+       StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_WPA_PTK_STATE,
+                        MAX_WPA_MSG, (STATE_MACHINE_FUNC) Drop, WPA_PTK,
+                        WPA_MACHINE_BASE);
+
+       StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket,
+                             (STATE_MACHINE_FUNC) WpaEAPPacketAction);
+       StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart,
+                             (STATE_MACHINE_FUNC) WpaEAPOLStartAction);
+       StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff,
+                             (STATE_MACHINE_FUNC) WpaEAPOLLogoffAction);
+       StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey,
+                             (STATE_MACHINE_FUNC) WpaEAPOLKeyAction);
+       StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert,
+                             (STATE_MACHINE_FUNC) WpaEAPOLASFAlertAction);
+}
+
+/*
+    ==========================================================================
+    Description:
+        this is state machine function.
+        When receiving EAP packets which is  for 802.1x authentication use.
+        Not use in PSK case
+    Return:
+    ==========================================================================
+*/
+void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
+
+void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
+
+void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+}
+
+/*
+    ==========================================================================
+    Description:
+       Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
+    Return:
+    ==========================================================================
+*/
+void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+       struct rt_mac_table_entry *pEntry;
+       struct rt_header_802_11 * pHeader;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
+
+       pHeader = (struct rt_header_802_11 *) Elem->Msg;
+
+       /*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. */
+       if (Elem->MsgLen == 6)
+               pEntry = MacTableLookup(pAd, Elem->Msg);
+       else {
+               pEntry = MacTableLookup(pAd, pHeader->Addr2);
+       }
+
+       if (pEntry) {
+               DBGPRINT(RT_DEBUG_TRACE,
+                        (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n",
+                         pEntry->PortSecured, pEntry->WpaState,
+                         pEntry->AuthMode, pEntry->PMKID_CacheIdx));
+
+               if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
+                   && (pEntry->WpaState < AS_PTKSTART)
+                   && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
+                       || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
+                       || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
+                           && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) {
+                       pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+                       pEntry->WpaState = AS_INITPSK;
+                       pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+                       NdisZeroMemory(pEntry->R_Counter,
+                                      sizeof(pEntry->R_Counter));
+                       pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
+
+                       WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
+               }
+       }
+}
+
+/*
+    ==========================================================================
+    Description:
+        This is state machine function.
+        When receiving EAPOL packets which is  for 802.1x key management.
+        Use both in WPA, and WPAPSK case.
+        In this function, further dispatch to different functions according to the received packet.  3 categories are :
+          1.  normal 4-way pairwisekey and 2-way groupkey handshake
+          2.  MIC error (Countermeasures attack)  report packet from STA.
+          3.  Request for pairwise/group key update from STA
+    Return:
+    ==========================================================================
+*/
+void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
+{
+       struct rt_mac_table_entry *pEntry;
+       struct rt_header_802_11 * pHeader;
+       struct rt_eapol_packet * pEapol_packet;
+       struct rt_key_info peerKeyInfo;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
+
+       pHeader = (struct rt_header_802_11 *) Elem->Msg;
+       pEapol_packet =
+           (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+       NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo));
+       NdisMoveMemory((u8 *)& peerKeyInfo,
+                      (u8 *)& pEapol_packet->KeyDesc.KeyInfo,
+                      sizeof(struct rt_key_info));
+
+       hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet,
+                (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
+
+       *((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo));
+
+       do {
+               pEntry = MacTableLookup(pAd, pHeader->Addr2);
+
+               if (!pEntry
+                   || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+                       break;
+
+               if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
+                       break;
+
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("Receive EAPoL-Key frame from STA %02X-%02X-%02X-%02X-%02X-%02X\n",
+                         PRINT_MAC(pEntry->Addr)));
+
+               if (((pEapol_packet->ProVer != EAPOL_VER)
+                    && (pEapol_packet->ProVer != EAPOL_VER2))
+                   || ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC)
+                       && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) {
+                       DBGPRINT(RT_DEBUG_ERROR,
+                                ("Key descripter does not match with WPA rule\n"));
+                       break;
+               }
+               /* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */
+               /* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. */
+               if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+                   && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) {
+                       DBGPRINT(RT_DEBUG_ERROR,
+                                ("Key descripter version not match(TKIP) \n"));
+                       break;
+               }
+               /* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */
+               /* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. */
+               else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+                        && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) {
+                       DBGPRINT(RT_DEBUG_ERROR,
+                                ("Key descripter version not match(AES) \n"));
+                       break;
+               }
+               /* Check if this STA is in class 3 state and the WPA state is started */
+               if ((pEntry->Sst == SST_ASSOC)
+                   && (pEntry->WpaState >= AS_INITPSK)) {
+                       /* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */
+                       /* or not. */
+                       /* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- */
+                       /* Key frame from the Authenticator must not have the Ack bit set. */
+                       if (peerKeyInfo.KeyAck == 1) {
+                               /* The frame is snet by Authenticator. */
+                               /* So the Supplicant side shall handle this. */
+
+                               if ((peerKeyInfo.Secure == 0)
+                                   && (peerKeyInfo.Request == 0)
+                                   && (peerKeyInfo.Error == 0)
+                                   && (peerKeyInfo.KeyType == PAIRWISEKEY)) {
+                                       /* Process 1. the message 1 of 4-way HS in WPA or WPA2 */
+                                       /*                        EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
+                                       /*                 2. the message 3 of 4-way HS in WPA */
+                                       /*                        EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
+                                       if (peerKeyInfo.KeyMic == 0)
+                                               PeerPairMsg1Action(pAd, pEntry,
+                                                                  Elem);
+                                       else
+                                               PeerPairMsg3Action(pAd, pEntry,
+                                                                  Elem);
+                               } else if ((peerKeyInfo.Secure == 1)
+                                          && (peerKeyInfo.KeyMic == 1)
+                                          && (peerKeyInfo.Request == 0)
+                                          && (peerKeyInfo.Error == 0)) {
+                                       /* Process 1. the message 3 of 4-way HS in WPA2 */
+                                       /*                        EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
+                                       /*                 2. the message 1 of group KS in WPA or WPA2 */
+                                       /*                        EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) */
+                                       if (peerKeyInfo.KeyType == PAIRWISEKEY)
+                                               PeerPairMsg3Action(pAd, pEntry,
+                                                                  Elem);
+                                       else
+                                               PeerGroupMsg1Action(pAd, pEntry,
+                                                                   Elem);
+                               }
+                       } else {
+                               /* The frame is snet by Supplicant. */
+                               /* So the Authenticator side shall handle this. */
+                               if ((peerKeyInfo.Request == 0) &&
+                                   (peerKeyInfo.Error == 0) &&
+                                   (peerKeyInfo.KeyMic == 1)) {
+                                       if (peerKeyInfo.Secure == 0
+                                           && peerKeyInfo.KeyType ==
+                                           PAIRWISEKEY) {
+                                               /* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) */
+                                               /* Process 1. message 2 of 4-way HS in WPA or WPA2 */
+                                               /*                 2. message 4 of 4-way HS in WPA */
+                                               if (CONV_ARRARY_TO_u16
+                                                   (pEapol_packet->KeyDesc.
+                                                    KeyDataLen) == 0) {
+                                                       PeerPairMsg4Action(pAd,
+                                                                          pEntry,
+                                                                          Elem);
+                                               } else {
+                                                       PeerPairMsg2Action(pAd,
+                                                                          pEntry,
+                                                                          Elem);
+                                               }
+                                       } else if (peerKeyInfo.Secure == 1
+                                                  && peerKeyInfo.KeyType ==
+                                                  PAIRWISEKEY) {
+                                               /* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */
+                                               /* Process message 4 of 4-way HS in WPA2 */
+                                               PeerPairMsg4Action(pAd, pEntry,
+                                                                  Elem);
+                                       } else if (peerKeyInfo.Secure == 1
+                                                  && peerKeyInfo.KeyType ==
+                                                  GROUPKEY) {
+                                               /* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) */
+                                               /* Process message 2 of Group key HS in WPA or WPA2 */
+                                               PeerGroupMsg2Action(pAd, pEntry,
+                                                                   &Elem->
+                                                                   Msg
+                                                                   [LENGTH_802_11],
+                                                                   (Elem->
+                                                                    MsgLen -
+                                                                    LENGTH_802_11));
+                                       }
+                               }
+                       }
+               }
+       } while (FALSE);
+}
+
+/*
+       ========================================================================
+
+       Routine Description:
+               Copy frame from waiting queue into relative ring buffer and set
+       appropriate ASIC register to kick hardware encryption before really
+       sent out to air.
+
+       Arguments:
+               pAd             Pointer to our adapter
+               void *  Pointer to outgoing Ndis frame
+               NumberOfFrag    Number of fragment required
+
+       Return Value:
+               None
+
+       Note:
+
+       ========================================================================
+*/
+void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
+                      struct rt_mac_table_entry *pEntry,
+                      u8 *pHeader802_3,
+                      u32 HdrLen,
+                      u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame)
+{
+       void *pPacket;
+       int Status;
+
+       if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+               return;
+
+       do {
+               /* build a NDIS packet */
+               Status =
+                   RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen,
+                                          pData, DataLen);
+               if (Status != NDIS_STATUS_SUCCESS)
+                       break;
+
+               if (bClearFrame)
+                       RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
+               else
+                       RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
+               {
+                       RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+
+                       RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID);        /* set a default value */
+                       if (pEntry->apidx != 0)
+                               RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket,
+                                                                 pEntry->
+                                                                 apidx);
+
+                       RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
+                       RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
+               }
+
+               {
+                       /* send out the packet */
+                       Status = STASendPacket(pAd, pPacket);
+                       if (Status == NDIS_STATUS_SUCCESS) {
+                               u8 Index;
+
+                               /* Dequeue one frame from TxSwQueue0..3 queue and process it */
+                               /* There are three place calling dequeue for TX ring. */
+                               /* 1. Here, right after queueing the frame. */
+                               /* 2. At the end of TxRingTxDone service routine. */
+                               /* 3. Upon NDIS call RTMPSendPackets */
+                               if ((!RTMP_TEST_FLAG
+                                    (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+                                   &&
+                                   (!RTMP_TEST_FLAG
+                                    (pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) {
+                                       for (Index = 0; Index < 5; Index++)
+                                               if (pAd->TxSwQueue[Index].
+                                                   Number > 0)
+                                                       RTMPDeQueuePacket(pAd,
+                                                                         FALSE,
+                                                                         Index,
+                                                                         MAX_TX_PROCESS);
+                               }
+                       }
+               }
+
+       } while (FALSE);
+}
+
+/*
+    ==========================================================================
+    Description:
+        This is a function to initilize 4-way handshake
+
+    Return:
+
+    ==========================================================================
+*/
+void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
+                   struct rt_mac_table_entry *pEntry, unsigned long TimeInterval)
+{
+       u8 Header802_3[14];
+       struct rt_eapol_packet EAPOLPKT;
+       u8 *pBssid = NULL;
+       u8 group_cipher = Ndis802_11WEPDisabled;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
+
+       if (RTMP_TEST_FLAG
+           (pAd,
+            fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
+       {
+               DBGPRINT(RT_DEBUG_ERROR,
+                        ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
+               return;
+       }
+
+       if (pBssid == NULL) {
+               DBGPRINT(RT_DEBUG_ERROR,
+                        ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
+               return;
+       }
+       /* Check the status */
+       if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) {
+               DBGPRINT(RT_DEBUG_ERROR,
+                        ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
+               return;
+       }
+
+       /* Increment replay counter by 1 */
+       ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
+
+       /* Randomly generate ANonce */
+       GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce);
+
+       /* Construct EAPoL message - Pairwise Msg 1 */
+       /* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
+       NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+       ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_1, 0,    /* Default key index */
+                         pEntry->ANonce, NULL, /* TxRSC */
+                         NULL, /* GTK */
+                         NULL, /* RSNIE */
+                         0,    /* RSNIE length */
+                         &EAPOLPKT);
+
+       /* Make outgoing frame */
+       MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
+       RTMPToWirelessSta(pAd, pEntry, Header802_3,
+                         LENGTH_802_3, (u8 *)& EAPOLPKT,
+                         CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
+                         (pEntry->PortSecured ==
+                          WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
+
+       /* Trigger Retry Timer */
+       RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
+
+       /* Update State */
+       pEntry->WpaState = AS_PTKSTART;
+
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
+
+}
+
+/*
+       ========================================================================
+
+       Routine Description:
+               Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
+
+       Arguments:
+               pAd                     Pointer to our adapter
+               Elem            Message body
+
+       Return Value:
+               None
+
+       Note:
+
+       ========================================================================
+*/
+void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
+                       struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+       u8 PTK[80];
+       u8 Header802_3[14];
+       struct rt_eapol_packet * pMsg1;
+       u32 MsgLen;
+       struct rt_eapol_packet EAPOLPKT;
+       u8 *pCurrentAddr = NULL;
+       u8 *pmk_ptr = NULL;
+       u8 group_cipher = Ndis802_11WEPDisabled;
+       u8 *rsnie_ptr = NULL;
+       u8 rsnie_len = 0;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
+
+       if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+               return;
+
+       if (Elem->MsgLen <
+           (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
+            sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
+               return;
+
+       {
+               pCurrentAddr = pAd->CurrentAddress;
+               pmk_ptr = pAd->StaCfg.PMK;
+               group_cipher = pAd->StaCfg.GroupCipher;
+               rsnie_ptr = pAd->StaCfg.RSN_IE;
+               rsnie_len = pAd->StaCfg.RSNIE_Len;
+       }
+
+       /* Store the received frame */
+       pMsg1 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+       MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+       /* Sanity Check peer Pairwise message 1 - Replay Counter */
+       if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry)
+           == FALSE)
+               return;
+
+       /* Store Replay counter, it will use to verify message 3 and construct message 2 */
+       NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter,
+                      LEN_KEY_DESC_REPLAY);
+
+       /* Store ANonce */
+       NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce,
+                      LEN_KEY_DESC_NONCE);
+
+       /* Generate random SNonce */
+       GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce);
+
+       {
+               /* Calculate PTK(ANonce, SNonce) */
+               WpaDerivePTK(pAd,
+                            pmk_ptr,
+                            pEntry->ANonce,
+                            pEntry->Addr,
+                            pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK);
+
+               /* Save key to PTK entry */
+               NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
+       }
+
+       /* Update WpaState */
+       pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
+
+       /* Construct EAPoL message - Pairwise Msg 2 */
+       /*  EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) */
+       NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+       ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_2, 0,    /* DefaultKeyIdx */
+                         pEntry->SNonce, NULL, /* TxRsc */
+                         NULL, /* GTK */
+                         (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
+
+       /* Make outgoing frame */
+       MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
+
+       RTMPToWirelessSta(pAd, pEntry,
+                         Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT,
+                         CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
+
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
+}
+
+/*
+    ==========================================================================
+    Description:
+        When receiving the second packet of 4-way pairwisekey handshake.
+    Return:
+    ==========================================================================
+*/
+void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
+                       struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+       u8 PTK[80];
+       BOOLEAN Cancelled;
+       struct rt_header_802_11 * pHeader;
+       struct rt_eapol_packet EAPOLPKT;
+       struct rt_eapol_packet * pMsg2;
+       u32 MsgLen;
+       u8 Header802_3[LENGTH_802_3];
+       u8 TxTsc[6];
+       u8 *pBssid = NULL;
+       u8 *pmk_ptr = NULL;
+       u8 *gtk_ptr = NULL;
+       u8 default_key = 0;
+       u8 group_cipher = Ndis802_11WEPDisabled;
+       u8 *rsnie_ptr = NULL;
+       u8 rsnie_len = 0;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
+
+       if ((!pEntry) || (!pEntry->ValidAsCLI))
+               return;
+
+       if (Elem->MsgLen <
+           (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
+            sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
+               return;
+
+       /* check Entry in valid State */
+       if (pEntry->WpaState < AS_PTKSTART)
+               return;
+
+       /* pointer to 802.11 header */
+       pHeader = (struct rt_header_802_11 *) Elem->Msg;
+
+       /* skip 802.11_header(24-byte) and LLC_header(8) */
+       pMsg2 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+       MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+       /* Store SNonce */
+       NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce,
+                      LEN_KEY_DESC_NONCE);
+
+       {
+               /* Derive PTK */
+               WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce,       /* ANONCE */
+                            (u8 *) pBssid, pEntry->SNonce,     /* SNONCE */
+                            pEntry->Addr, PTK, LEN_PTK);
+
+               NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
+       }
+
+       /* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */
+       if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry)
+           == FALSE)
+               return;
+
+       do {
+               /* delete retry timer */
+               RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+               /* Change state */
+               pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
+
+               /* Increment replay counter by 1 */
+               ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
+
+               /* Construct EAPoL message - Pairwise Msg 3 */
+               NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+               ConstructEapolMsg(pEntry,
+                                 group_cipher,
+                                 EAPOL_PAIR_MSG_3,
+                                 default_key,
+                                 pEntry->ANonce,
+                                 TxTsc,
+                                 (u8 *) gtk_ptr,
+                                 (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
+
+               /* Make outgoing frame */
+               MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
+               RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
+                                 (u8 *)& EAPOLPKT,
+                                 CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
+                                 (pEntry->PortSecured ==
+                                  WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
+
+               pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
+               RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
+
+               /* Update State */
+               pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
+       } while (FALSE);
+
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
+}
+
+/*
+       ========================================================================
+
+       Routine Description:
+               Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
+
+       Arguments:
+               pAd     Pointer to our adapter
+               Elem            Message body
+
+       Return Value:
+               None
+
+       Note:
+
+       ========================================================================
+*/
+void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
+                       struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+       struct rt_header_802_11 * pHeader;
+       u8 Header802_3[14];
+       struct rt_eapol_packet EAPOLPKT;
+       struct rt_eapol_packet * pMsg3;
+       u32 MsgLen;
+       u8 *pCurrentAddr = NULL;
+       u8 group_cipher = Ndis802_11WEPDisabled;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
+
+       if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+               return;
+
+       if (Elem->MsgLen <
+           (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
+            sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
+               return;
+
+       {
+               pCurrentAddr = pAd->CurrentAddress;
+               group_cipher = pAd->StaCfg.GroupCipher;
+
+       }
+
+       /* Record 802.11 header & the received EAPOL packet Msg3 */
+       pHeader = (struct rt_header_802_11 *) Elem->Msg;
+       pMsg3 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+       MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+       /* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */
+       if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry)
+           == FALSE)
+               return;
+
+       /* Save Replay counter, it will use construct message 4 */
+       NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter,
+                      LEN_KEY_DESC_REPLAY);
+
+       /* Double check ANonce */
+       if (!NdisEqualMemory
+           (pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) {
+               return;
+       }
+       /* Construct EAPoL message - Pairwise Msg 4 */
+       NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+       ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_4, 0,    /* group key index not used in message 4 */
+                         NULL, /* Nonce not used in message 4 */
+                         NULL, /* TxRSC not used in message 4 */
+                         NULL, /* GTK not used in message 4 */
+                         NULL, /* RSN IE not used in message 4 */
+                         0, &EAPOLPKT);
+
+       /* Update WpaState */
+       pEntry->WpaState = AS_PTKINITDONE;
+
+       /* Update pairwise key */
+       {
+               struct rt_cipher_key *pSharedKey;
+
+               pSharedKey = &pAd->SharedKey[BSS0][0];
+
+               NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
+
+               /* Prepare pair-wise key information into shared key table */
+               NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
+               pSharedKey->KeyLen = LEN_TKIP_EK;
+               NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32],
+                              LEN_TKIP_EK);
+               NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
+                              LEN_TKIP_RXMICK);
+               NdisMoveMemory(pSharedKey->TxMic,
+                              &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
+                              LEN_TKIP_TXMICK);
+
+               /* Decide its ChiperAlg */
+               if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+                       pSharedKey->CipherAlg = CIPHER_TKIP;
+               else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+                       pSharedKey->CipherAlg = CIPHER_AES;
+               else
+                       pSharedKey->CipherAlg = CIPHER_NONE;
+
+               /* Update these related information to struct rt_mac_table_entry */
+               pEntry = &pAd->MacTab.Content[BSSID_WCID];
+               NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32],
+                              LEN_TKIP_EK);
+               NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
+                              LEN_TKIP_RXMICK);
+               NdisMoveMemory(pEntry->PairwiseKey.TxMic,
+                              &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
+                              LEN_TKIP_TXMICK);
+               pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
+
+               /* Update pairwise key information to ASIC Shared Key Table */
+               AsicAddSharedKeyEntry(pAd,
+                                     BSS0,
+                                     0,
+                                     pSharedKey->CipherAlg,
+                                     pSharedKey->Key,
+                                     pSharedKey->TxMic, pSharedKey->RxMic);
+
+               /* Update ASIC WCID attribute table and IVEIV table */
+               RTMPAddWcidAttributeEntry(pAd,
+                                         BSS0,
+                                         0, pSharedKey->CipherAlg, pEntry);
+
+       }
+
+       /* open 802.1x port control and privacy filter */
+       if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
+           pEntry->AuthMode == Ndis802_11AuthModeWPA2) {
+               pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+               pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+
+               STA_PORT_SECURED(pAd);
+               /* Indicate Connected for GUI */
+               pAd->IndicateMediaState = NdisMediaStateConnected;
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
+                         GetAuthMode(pEntry->AuthMode),
+                         GetEncryptType(pEntry->WepStatus),
+                         GetEncryptType(group_cipher)));
+       } else {
+       }
+
+       /* Init 802.3 header and send out */
+       MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
+       RTMPToWirelessSta(pAd, pEntry,
+                         Header802_3, sizeof(Header802_3),
+                         (u8 *)& EAPOLPKT,
+                         CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
+
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
+}
+
+/*
+    ==========================================================================
+    Description:
+        When receiving the last packet of 4-way pairwisekey handshake.
+        Initilize 2-way groupkey handshake following.
+    Return:
+    ==========================================================================
+*/
+void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
+                       struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+       struct rt_eapol_packet * pMsg4;
+       struct rt_header_802_11 * pHeader;
+       u32 MsgLen;
+       BOOLEAN Cancelled;
+       u8 group_cipher = Ndis802_11WEPDisabled;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
+
+       do {
+               if ((!pEntry) || (!pEntry->ValidAsCLI))
+                       break;
+
+               if (Elem->MsgLen <
+                   (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
+                    sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
+                       break;
+
+               if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
+                       break;
+
+               /* pointer to 802.11 header */
+               pHeader = (struct rt_header_802_11 *) Elem->Msg;
+
+               /* skip 802.11_header(24-byte) and LLC_header(8) */
+               pMsg4 =
+                   (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+               MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+               /* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */
+               if (PeerWpaMessageSanity
+                   (pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
+                       break;
+
+               /* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */
+               NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key));
+
+               /* reset IVEIV in Asic */
+               AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
+
+               pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
+               NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32],
+                              LEN_TKIP_EK);
+               NdisMoveMemory(pEntry->PairwiseKey.RxMic,
+                              &pEntry->PTK[TKIP_AP_RXMICK_OFFSET],
+                              LEN_TKIP_RXMICK);
+               NdisMoveMemory(pEntry->PairwiseKey.TxMic,
+                              &pEntry->PTK[TKIP_AP_TXMICK_OFFSET],
+                              LEN_TKIP_TXMICK);
+
+               /* Set pairwise key to Asic */
+               {
+                       pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+                       if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+                               pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
+                       else if (pEntry->WepStatus ==
+                                Ndis802_11Encryption3Enabled)
+                               pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
+
+                       /* Add Pair-wise key to Asic */
+                       AsicAddPairwiseKeyEntry(pAd,
+                                               pEntry->Addr,
+                                               (u8)pEntry->Aid,
+                                               &pEntry->PairwiseKey);
+
+                       /* update WCID attribute table and IVEIV table for this entry */
+                       RTMPAddWcidAttributeEntry(pAd,
+                                                 pEntry->apidx,
+                                                 0,
+                                                 pEntry->PairwiseKey.CipherAlg,
+                                                 pEntry);
+               }
+
+               /* 4. upgrade state */
+               pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+               pEntry->WpaState = AS_PTKINITDONE;
+               pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+
+               if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
+                   pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) {
+                       pEntry->GTKState = REKEY_ESTABLISHED;
+                       RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+                       /* send wireless event - for set key done WPA2 */
+                       if (pAd->CommonCfg.bWirelessEvent)
+                               RTMPSendWirelessEvent(pAd,
+                                                     IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
+                                                     pEntry->Addr,
+                                                     pEntry->apidx, 0);
+
+                       DBGPRINT(RT_DEBUG_OFF,
+                                ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
+                                 pEntry->AuthMode,
+                                 GetAuthMode(pEntry->AuthMode),
+                                 pEntry->WepStatus,
+                                 GetEncryptType(pEntry->WepStatus),
+                                 group_cipher, GetEncryptType(group_cipher)));
+               } else {
+                       /* 5. init Group 2-way handshake if necessary. */
+                       WPAStart2WayGroupHS(pAd, pEntry);
+
+                       pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
+                       RTMPModTimer(&pEntry->RetryTimer,
+                                    PEER_MSG3_RETRY_EXEC_INTV);
+               }
+       } while (FALSE);
+
+}
+
+/*
+    ==========================================================================
+    Description:
+        This is a function to send the first packet of 2-way groupkey handshake
+    Return:
+
+    ==========================================================================
+*/
+void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
+{
+       u8 Header802_3[14];
+       u8 TxTsc[6];
+       struct rt_eapol_packet EAPOLPKT;
+       u8 group_cipher = Ndis802_11WEPDisabled;
+       u8 default_key = 0;
+       u8 *gnonce_ptr = NULL;
+       u8 *gtk_ptr = NULL;
+       u8 *pBssid = NULL;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
+
+       if ((!pEntry) || (!pEntry->ValidAsCLI))
+               return;
+
+       do {
+               /* Increment replay counter by 1 */
+               ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
+
+               /* Construct EAPoL message - Group Msg 1 */
+               NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+               ConstructEapolMsg(pEntry,
+                                 group_cipher,
+                                 EAPOL_GROUP_MSG_1,
+                                 default_key,
+                                 (u8 *) gnonce_ptr,
+                                 TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT);
+
+               /* Make outgoing frame */
+               MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
+               RTMPToWirelessSta(pAd, pEntry,
+                                 Header802_3, LENGTH_802_3,
+                                 (u8 *)& EAPOLPKT,
+                                 CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
+                                 FALSE);
+
+       } while (FALSE);
+
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
+
+       return;
+}
+
+/*
+       ========================================================================
+
+       Routine Description:
+               Process Group key 2-way handshaking
+
+       Arguments:
+               pAd     Pointer to our adapter
+               Elem            Message body
+
+       Return Value:
+               None
+
+       Note:
+
+       ========================================================================
+*/
+void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
+                        struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
+{
+       u8 Header802_3[14];
+       struct rt_eapol_packet EAPOLPKT;
+       struct rt_eapol_packet * pGroup;
+       u32 MsgLen;
+       BOOLEAN Cancelled;
+       u8 default_key = 0;
+       u8 group_cipher = Ndis802_11WEPDisabled;
+       u8 *pCurrentAddr = NULL;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
+
+       if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+               return;
+
+       {
+               pCurrentAddr = pAd->CurrentAddress;
+               group_cipher = pAd->StaCfg.GroupCipher;
+               default_key = pAd->StaCfg.DefaultKeyId;
+       }
+
+       /* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) */
+       pGroup = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+       MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+       /* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */
+       if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry)
+           == FALSE)
+               return;
+
+       /* delete retry timer */
+       RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+       /* Save Replay counter, it will use to construct message 2 */
+       NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter,
+                      LEN_KEY_DESC_REPLAY);
+
+       /* Construct EAPoL message - Group Msg 2 */
+       NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
+       ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_2, default_key, NULL,   /* Nonce not used */
+                         NULL, /* TxRSC not used */
+                         NULL, /* GTK not used */
+                         NULL, /* RSN IE not used */
+                         0, &EAPOLPKT);
+
+       /* open 802.1x port control and privacy filter */
+       pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+       pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+
+       STA_PORT_SECURED(pAd);
+       /* Indicate Connected for GUI */
+       pAd->IndicateMediaState = NdisMediaStateConnected;
+
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
+                 GetAuthMode(pEntry->AuthMode),
+                 GetEncryptType(pEntry->WepStatus),
+                 GetEncryptType(group_cipher)));
+
+       /* init header and Fill Packet and send Msg 2 to authenticator */
+       MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
+       RTMPToWirelessSta(pAd, pEntry,
+                         Header802_3, sizeof(Header802_3),
+                         (u8 *)& EAPOLPKT,
+                         CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE);
+
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("<=== PeerGroupMsg1Action: sned group message 2\n"));
+}
+
+/*
+    ==========================================================================
+    Description:
+        When receiving the last packet of 2-way groupkey handshake.
+    Return:
+    ==========================================================================
+*/
+void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
+                        struct rt_mac_table_entry *pEntry,
+                        void * Msg, u32 MsgLen)
+{
+       u32 Len;
+       u8 *pData;
+       BOOLEAN Cancelled;
+       struct rt_eapol_packet * pMsg2;
+       u8 group_cipher = Ndis802_11WEPDisabled;
+
+       DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
+
+       do {
+               if ((!pEntry) || (!pEntry->ValidAsCLI))
+                       break;
+
+               if (MsgLen <
+                   (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) -
+                    MAX_LEN_OF_RSNIE - 2))
+                       break;
+
+               if (pEntry->WpaState != AS_PTKINITDONE)
+                       break;
+
+               pData = (u8 *)Msg;
+               pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H);
+               Len = MsgLen - LENGTH_802_1_H;
+
+               /* Sanity Check peer group message 2 - Replay Counter, MIC */
+               if (PeerWpaMessageSanity
+                   (pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
+                       break;
+
+               /* 3.  upgrade state */
+
+               RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+               pEntry->GTKState = REKEY_ESTABLISHED;
+
+               if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
+                   || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) {
+                       /* send wireless event - for set key done WPA2 */
+                       if (pAd->CommonCfg.bWirelessEvent)
+                               RTMPSendWirelessEvent(pAd,
+                                                     IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
+                                                     pEntry->Addr,
+                                                     pEntry->apidx, 0);
+
+                       DBGPRINT(RT_DEBUG_OFF,
+                                ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
+                                 pEntry->AuthMode,
+                                 GetAuthMode(pEntry->AuthMode),
+                                 pEntry->WepStatus,
+                                 GetEncryptType(pEntry->WepStatus),
+                                 group_cipher, GetEncryptType(group_cipher)));
+               } else {
+                       /* send wireless event - for set key done WPA */
+                       if (pAd->CommonCfg.bWirelessEvent)
+                               RTMPSendWirelessEvent(pAd,
+                                                     IW_SET_KEY_DONE_WPA1_EVENT_FLAG,
+                                                     pEntry->Addr,
+                                                     pEntry->apidx, 0);
+
+                       DBGPRINT(RT_DEBUG_OFF,
+                                ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
+                                 pEntry->AuthMode,
+                                 GetAuthMode(pEntry->AuthMode),
+                                 pEntry->WepStatus,
+                                 GetEncryptType(pEntry->WepStatus),
+                                 group_cipher, GetEncryptType(group_cipher)));
+               }
+       } while (FALSE);
+}
+
+/*
+       ========================================================================
+
+       Routine Description:
+               Classify WPA EAP message type
+
+       Arguments:
+               EAPType         Value of EAP message type
+               MsgType         Internal Message definition for MLME state machine
+
+       Return Value:
+               TRUE            Found appropriate message type
+               FALSE           No appropriate message type
+
+       IRQL = DISPATCH_LEVEL
+
+       Note:
+               All these constants are defined in wpa.h
+               For supplicant, there is only EAPOL Key message avaliable
+
+       ========================================================================
+*/
+BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType)
+{
+       switch (EAPType) {
+       case EAPPacket:
+               *MsgType = MT2_EAPPacket;
+               break;
+       case EAPOLStart:
+               *MsgType = MT2_EAPOLStart;
+               break;
+       case EAPOLLogoff:
+               *MsgType = MT2_EAPOLLogoff;
+               break;
+       case EAPOLKey:
+               *MsgType = MT2_EAPOLKey;
+               break;
+       case EAPOLASFAlert:
+               *MsgType = MT2_EAPOLASFAlert;
+               break;
+       default:
+               return FALSE;
+       }
+       return TRUE;
+}
 
 /*
        ========================================================================
@@ -67,72 +1261,118 @@ UCHAR    OUI_MSA_PSK_AKM[4]      = {0x00, 0x0F, 0xAC, 0x06};             // Not yet final - I
                It is used to generate PTK, GTK or some specific random value.
 
        Arguments:
-               UCHAR   *key,           -       the key material for HMAC_SHA1 use
-               INT             key_len         -       the length of key
-               UCHAR   *prefix         -       a prefix label
-               INT             prefix_len      -       the length of the label
-               UCHAR   *data           -       a specific data with variable length
-               INT             data_len        -       the length of a specific data
-               INT             len                     -       the output lenght
+               u8      *key,           -       the key material for HMAC_SHA1 use
+               int             key_len         -       the length of key
+               u8      *prefix         -       a prefix label
+               int             prefix_len      -       the length of the label
+               u8      *data           -       a specific data with variable length
+               int             data_len        -       the length of a specific data
+               int             len                     -       the output lenght
 
        Return Value:
-               UCHAR   *output         -       the calculated result
+               u8      *output         -       the calculated result
 
        Note:
                802.11i-2004    Annex H.3
 
        ========================================================================
 */
-VOID   PRF(
-       IN      UCHAR   *key,
-       IN      INT             key_len,
-       IN      UCHAR   *prefix,
-       IN      INT             prefix_len,
-       IN      UCHAR   *data,
-       IN      INT             data_len,
-       OUT     UCHAR   *output,
-       IN      INT             len)
+void PRF(u8 * key,
+        int key_len,
+        u8 * prefix,
+        int prefix_len,
+        u8 * data, int data_len, u8 * output, int len)
 {
-       INT             i;
-    UCHAR   *input;
-       INT             currentindex = 0;
-       INT             total_len;
-
-       // Allocate memory for input
-       os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
+       int i;
+       u8 *input;
+       int currentindex = 0;
+       int total_len;
 
-    if (input == NULL)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
-        return;
-    }
+       /* Allocate memory for input */
+       os_alloc_mem(NULL, (u8 **) & input, 1024);
 
-       // Generate concatenation input
+       if (input == NULL) {
+               DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n"));
+               return;
+       }
+       /* Generate concatenation input */
        NdisMoveMemory(input, prefix, prefix_len);
 
-       // Concatenate a single octet containing 0
-       input[prefix_len] =     0;
+       /* Concatenate a single octet containing 0 */
+       input[prefix_len] = 0;
 
-       // Concatenate specific data
+       /* Concatenate specific data */
        NdisMoveMemory(&input[prefix_len + 1], data, data_len);
-       total_len =     prefix_len + 1 + data_len;
+       total_len = prefix_len + 1 + data_len;
 
-       // Concatenate a single octet containing 0
-       // This octet shall be update later
+       /* Concatenate a single octet containing 0 */
+       /* This octet shall be update later */
        input[total_len] = 0;
        total_len++;
 
-       // Iterate to calculate the result by hmac-sha-1
-       // Then concatenate to last result
-       for     (i = 0; i <     (len + 19) / 20; i++)
-       {
-               HMAC_SHA1(input, total_len,     key, key_len, &output[currentindex]);
-               currentindex += 20;
+       /* Iterate to calculate the result by hmac-sha-1 */
+       /* Then concatenate to last result */
+       for (i = 0; i < (len + 19) / 20; i++) {
+               HMAC_SHA1(key, key_len, input, total_len, &output[currentindex],
+                         SHA1_DIGEST_SIZE);
+               currentindex += 20;
 
-               // update the last octet
+               /* update the last octet */
                input[total_len - 1]++;
        }
-    os_free_mem(NULL, input);
+       os_free_mem(NULL, input);
+}
+
+/*
+* F(P, S, c, i) = U1 xor U2 xor ... Uc
+* U1 = PRF(P, S || Int(i))
+* U2 = PRF(P, U1)
+* Uc = PRF(P, Uc-1)
+*/
+
+static void F(char *password, unsigned char *ssid, int ssidlength,
+             int iterations, int count, unsigned char *output)
+{
+       unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
+       int i, j;
+
+       /* U1 = PRF(P, S || int(i)) */
+       memcpy(digest, ssid, ssidlength);
+       digest[ssidlength] = (unsigned char)((count >> 24) & 0xff);
+       digest[ssidlength + 1] = (unsigned char)((count >> 16) & 0xff);
+       digest[ssidlength + 2] = (unsigned char)((count >> 8) & 0xff);
+       digest[ssidlength + 3] = (unsigned char)(count & 0xff);
+       HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest, ssidlength + 4, digest1, SHA1_DIGEST_SIZE); /* for WPA update */
+
+       /* output = U1 */
+       memcpy(output, digest1, SHA1_DIGEST_SIZE);
+
+       for (i = 1; i < iterations; i++) {
+               /* Un = PRF(P, Un-1) */
+               HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE);       /* for WPA update */
+               memcpy(digest1, digest, SHA1_DIGEST_SIZE);
+
+               /* output = output xor Un */
+               for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
+                       output[j] ^= digest[j];
+               }
+       }
+}
+
+/*
+* password - ascii string up to 63 characters in length
+* ssid - octet string up to 32 octets
+* ssidlength - length of ssid in octets
+* output must be 40 octets in length and outputs 256 bits of key
+*/
+int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output)
+{
+       if ((strlen(password) > 63) || (ssidlength > 32))
+               return 0;
+
+       F(password, ssid, ssidlength, 4096, 1, output);
+       F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
+       return 1;
 }
 
 /*
@@ -143,7 +1383,7 @@ VOID       PRF(
                It shall be called by 4-way handshake processing.
 
        Arguments:
-               pAd     -       pointer to our pAdapter context
+               pAd     -       pointer to our pAdapter context
                PMK             -       pointer to PMK
                ANonce  -       pointer to ANonce
                AA              -       pointer to Authenticator Address
@@ -159,56 +1399,55 @@ VOID     PRF(
 
        ========================================================================
 */
-VOID WpaCountPTK(
-       IN      PRTMP_ADAPTER   pAd,
-       IN      UCHAR   *PMK,
-       IN      UCHAR   *ANonce,
-       IN      UCHAR   *AA,
-       IN      UCHAR   *SNonce,
-       IN      UCHAR   *SA,
-       OUT     UCHAR   *output,
-       IN      UINT    len)
+void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
+                 u8 * PMK,
+                 u8 * ANonce,
+                 u8 * AA,
+                 u8 * SNonce,
+                 u8 * SA, u8 * output, u32 len)
 {
-       UCHAR   concatenation[76];
-       UINT    CurrPos = 0;
-       UCHAR   temp[32];
-       UCHAR   Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
-                                               'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
-
-       // initiate the concatenation input
+       u8 concatenation[76];
+       u32 CurrPos = 0;
+       u8 temp[32];
+       u8 Prefix[] =
+           { 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
+               'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'
+       };
+
+       /* initiate the concatenation input */
        NdisZeroMemory(temp, sizeof(temp));
        NdisZeroMemory(concatenation, 76);
 
-       // Get smaller address
+       /* Get smaller address */
        if (RTMPCompareMemory(SA, AA, 6) == 1)
                NdisMoveMemory(concatenation, AA, 6);
        else
                NdisMoveMemory(concatenation, SA, 6);
        CurrPos += 6;
 
-       // Get larger address
+       /* Get larger address */
        if (RTMPCompareMemory(SA, AA, 6) == 1)
                NdisMoveMemory(&concatenation[CurrPos], SA, 6);
        else
                NdisMoveMemory(&concatenation[CurrPos], AA, 6);
 
-       // store the larger mac address for backward compatible of
-       // ralink proprietary STA-key issue
+       /* store the larger mac address for backward compatible of */
+       /* ralink proprietary STA-key issue */
        NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
        CurrPos += 6;
 
-       // Get smaller Nonce
+       /* Get smaller Nonce */
        if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
-               NdisMoveMemory(&concatenation[CurrPos], temp, 32);      // patch for ralink proprietary STA-key issue
+               NdisMoveMemory(&concatenation[CurrPos], temp, 32);      /* patch for ralink proprietary STA-key issue */
        else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
                NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
        else
                NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
        CurrPos += 32;
 
-       // Get larger Nonce
+       /* Get larger Nonce */
        if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
-               NdisMoveMemory(&concatenation[CurrPos], temp, 32);      // patch for ralink proprietary STA-key issue
+               NdisMoveMemory(&concatenation[CurrPos], temp, 32);      /* patch for ralink proprietary STA-key issue */
        else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
                NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
        else
@@ -217,7 +1456,7 @@ VOID WpaCountPTK(
 
        hex_dump("concatenation=", concatenation, 76);
 
-       // Use PRF to generate PTK
+       /* Use PRF to generate PTK */
        PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
 
 }
@@ -239,46 +1478,43 @@ VOID WpaCountPTK(
 
        ========================================================================
 */
-VOID   GenRandom(
-       IN      PRTMP_ADAPTER   pAd,
-       IN      UCHAR                   *macAddr,
-       OUT     UCHAR                   *random)
+void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random)
 {
-       INT             i, curr;
-       UCHAR   local[80], KeyCounter[32];
-       UCHAR   result[80];
-       ULONG   CurrentTime;
-       UCHAR   prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
-
-       // Zero the related information
+       int i, curr;
+       u8 local[80], KeyCounter[32];
+       u8 result[80];
+       unsigned long CurrentTime;
+       u8 prefix[] =
+           { 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' };
+
+       /* Zero the related information */
        NdisZeroMemory(result, 80);
        NdisZeroMemory(local, 80);
        NdisZeroMemory(KeyCounter, 32);
 
-       for     (i = 0; i <     32;     i++)
-       {
-               // copy the local MAC address
+       for (i = 0; i < 32; i++) {
+               /* copy the local MAC address */
                COPY_MAC_ADDR(local, macAddr);
-               curr =  MAC_ADDR_LEN;
+               curr = MAC_ADDR_LEN;
 
-               // concatenate the current time
+               /* concatenate the current time */
                NdisGetSystemUpTime(&CurrentTime);
-               NdisMoveMemory(&local[curr],  &CurrentTime,     sizeof(CurrentTime));
-               curr += sizeof(CurrentTime);
+               NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
+               curr += sizeof(CurrentTime);
 
-               // concatenate the last result
-               NdisMoveMemory(&local[curr],  result, 32);
-               curr += 32;
+               /* concatenate the last result */
+               NdisMoveMemory(&local[curr], result, 32);
+               curr += 32;
 
-               // concatenate a variable
-               NdisMoveMemory(&local[curr],  &i,  2);
-               curr += 2;
+               /* concatenate a variable */
+               NdisMoveMemory(&local[curr], &i, 2);
+               curr += 2;
 
-               // calculate the result
-               PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
+               /* calculate the result */
+               PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32);
        }
 
-       NdisMoveMemory(random, result,  32);
+       NdisMoveMemory(random, result, 32);
 }
 
 /*
@@ -290,8 +1526,8 @@ VOID       GenRandom(
 
        Arguments:
                pAd                     -       pointer to our pAdapter context
-       ElementID       -       indicate the WPA1 or WPA2
-       WepStatus       -       indicate the encryption type
+       ElementID       -       indicate the WPA1 or WPA2
+       WepStatus       -       indicate the encryption type
                bMixCipher      -       a boolean to indicate the pairwise cipher and group
                                                cipher are the same or not
 
@@ -301,170 +1537,169 @@ VOID   GenRandom(
 
        ========================================================================
 */
-static VOID RTMPInsertRsnIeCipher(
-       IN  PRTMP_ADAPTER   pAd,
-       IN      UCHAR                   ElementID,
-       IN      UINT                    WepStatus,
-       IN      BOOLEAN                 bMixCipher,
-       IN      UCHAR                   FlexibleCipher,
-       OUT     PUCHAR                  pRsnIe,
-       OUT     UCHAR                   *rsn_len)
+static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd,
+                               u8 ElementID,
+                               u32 WepStatus,
+                               IN BOOLEAN bMixCipher,
+                               u8 FlexibleCipher,
+                               u8 *pRsnIe, u8 * rsn_len)
 {
-       UCHAR   PairwiseCnt;
+       u8 PairwiseCnt;
 
        *rsn_len = 0;
 
-       // decide WPA2 or WPA1
-       if (ElementID == Wpa2Ie)
-       {
-               RSNIE2  *pRsnie_cipher = (RSNIE2*)pRsnIe;
+       /* decide WPA2 or WPA1 */
+       if (ElementID == Wpa2Ie) {
+               struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe;
 
-               // Assign the verson as 1
+               /* Assign the verson as 1 */
                pRsnie_cipher->version = 1;
 
-        switch (WepStatus)
-        {
-               // TKIP mode
-            case Ndis802_11Encryption2Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
-                *rsn_len = sizeof(RSNIE2);
-                break;
-
-                       // AES mode
-            case Ndis802_11Encryption3Enabled:
-                               if (bMixCipher)
-                                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-                               else
-                                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
-                *rsn_len = sizeof(RSNIE2);
-                break;
-
-                       // TKIP-AES mix mode
-            case Ndis802_11Encryption4Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-
-                               PairwiseCnt = 1;
-                               // Insert WPA2 TKIP as the first pairwise cipher
-                               if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
-                               {
-                       NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
-                                       // Insert WPA2 AES as the secondary pairwise cipher
-                                       if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
-                                       {
-                               NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
-                                               PairwiseCnt = 2;
-                                       }
-                               }
-                               else
-                               {
-                                       // Insert WPA2 AES as the first pairwise cipher
-                                       NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
+               switch (WepStatus) {
+                       /* TKIP mode */
+               case Ndis802_11Encryption2Enabled:
+                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+                       pRsnie_cipher->ucount = 1;
+                       NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+                                      OUI_WPA2_TKIP, 4);
+                       *rsn_len = sizeof(struct rt_rsnie2);
+                       break;
+
+                       /* AES mode */
+               case Ndis802_11Encryption3Enabled:
+                       if (bMixCipher)
+                               NdisMoveMemory(pRsnie_cipher->mcast,
+                                              OUI_WPA2_TKIP, 4);
+                       else
+                               NdisMoveMemory(pRsnie_cipher->mcast,
+                                              OUI_WPA2_CCMP, 4);
+                       pRsnie_cipher->ucount = 1;
+                       NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+                                      OUI_WPA2_CCMP, 4);
+                       *rsn_len = sizeof(struct rt_rsnie2);
+                       break;
+
+                       /* TKIP-AES mix mode */
+               case Ndis802_11Encryption4Enabled:
+                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+
+                       PairwiseCnt = 1;
+                       /* Insert WPA2 TKIP as the first pairwise cipher */
+                       if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) {
+                               NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+                                              OUI_WPA2_TKIP, 4);
+                               /* Insert WPA2 AES as the secondary pairwise cipher */
+                               if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) {
+                                       NdisMoveMemory(pRsnie_cipher->ucast[0].
+                                                      oui + 4, OUI_WPA2_CCMP,
+                                                      4);
+                                       PairwiseCnt = 2;
                                }
+                       } else {
+                               /* Insert WPA2 AES as the first pairwise cipher */
+                               NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+                                              OUI_WPA2_CCMP, 4);
+                       }
 
-                pRsnie_cipher->ucount = PairwiseCnt;
-                *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
-                break;
-        }
+                       pRsnie_cipher->ucount = PairwiseCnt;
+                       *rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1));
+                       break;
+               }
 
                if ((pAd->OpMode == OPMODE_STA) &&
-                       (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
-                       (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
-               {
-                       UINT GroupCipher = pAd->StaCfg.GroupCipher;
-                       switch(GroupCipher)
-                       {
-                               case Ndis802_11GroupWEP40Enabled:
-                                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4);
-                                       break;
-                               case Ndis802_11GroupWEP104Enabled:
-                                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4);
-                                       break;
+                   (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+                   (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
+                       u32 GroupCipher = pAd->StaCfg.GroupCipher;
+                       switch (GroupCipher) {
+                       case Ndis802_11GroupWEP40Enabled:
+                               NdisMoveMemory(pRsnie_cipher->mcast,
+                                              OUI_WPA2_WEP40, 4);
+                               break;
+                       case Ndis802_11GroupWEP104Enabled:
+                               NdisMoveMemory(pRsnie_cipher->mcast,
+                                              OUI_WPA2_WEP104, 4);
+                               break;
                        }
                }
-
-               // swap for big-endian platform
+               /* swap for big-endian platform */
                pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
-           pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
-       }
-       else
-       {
-               RSNIE   *pRsnie_cipher = (RSNIE*)pRsnIe;
+               pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+       } else {
+               struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe;
 
-               // Assign OUI and version
+               /* Assign OUI and version */
                NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
-        pRsnie_cipher->version = 1;
+               pRsnie_cipher->version = 1;
 
-               switch (WepStatus)
-               {
-                       // TKIP mode
-            case Ndis802_11Encryption2Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
-                *rsn_len = sizeof(RSNIE);
-                break;
-
-                       // AES mode
-            case Ndis802_11Encryption3Enabled:
-                               if (bMixCipher)
-                                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-                               else
-                                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
-                pRsnie_cipher->ucount = 1;
-                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
-                *rsn_len = sizeof(RSNIE);
-                break;
-
-                       // TKIP-AES mix mode
-            case Ndis802_11Encryption4Enabled:
-                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-
-                               PairwiseCnt = 1;
-                               // Insert WPA TKIP as the first pairwise cipher
-                               if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
-                               {
-                       NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
-                                       // Insert WPA AES as the secondary pairwise cipher
-                                       if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
-                                       {
-                               NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
-                                               PairwiseCnt = 2;
-                                       }
-                               }
-                               else
-                               {
-                                       // Insert WPA AES as the first pairwise cipher
-                                       NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
+               switch (WepStatus) {
+                       /* TKIP mode */
+               case Ndis802_11Encryption2Enabled:
+                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+                       pRsnie_cipher->ucount = 1;
+                       NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+                                      OUI_WPA_TKIP, 4);
+                       *rsn_len = sizeof(struct rt_rsnie);
+                       break;
+
+                       /* AES mode */
+               case Ndis802_11Encryption3Enabled:
+                       if (bMixCipher)
+                               NdisMoveMemory(pRsnie_cipher->mcast,
+                                              OUI_WPA_TKIP, 4);
+                       else
+                               NdisMoveMemory(pRsnie_cipher->mcast,
+                                              OUI_WPA_CCMP, 4);
+                       pRsnie_cipher->ucount = 1;
+                       NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+                                      OUI_WPA_CCMP, 4);
+                       *rsn_len = sizeof(struct rt_rsnie);
+                       break;
+
+                       /* TKIP-AES mix mode */
+               case Ndis802_11Encryption4Enabled:
+                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+
+                       PairwiseCnt = 1;
+                       /* Insert WPA TKIP as the first pairwise cipher */
+                       if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) {
+                               NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+                                              OUI_WPA_TKIP, 4);
+                               /* Insert WPA AES as the secondary pairwise cipher */
+                               if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) {
+                                       NdisMoveMemory(pRsnie_cipher->ucast[0].
+                                                      oui + 4, OUI_WPA_CCMP,
+                                                      4);
+                                       PairwiseCnt = 2;
                                }
+                       } else {
+                               /* Insert WPA AES as the first pairwise cipher */
+                               NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
+                                              OUI_WPA_CCMP, 4);
+                       }
 
-                pRsnie_cipher->ucount = PairwiseCnt;
-                *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
-                break;
-        }
+                       pRsnie_cipher->ucount = PairwiseCnt;
+                       *rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1));
+                       break;
+               }
 
                if ((pAd->OpMode == OPMODE_STA) &&
-                       (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
-                       (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
-               {
-                       UINT GroupCipher = pAd->StaCfg.GroupCipher;
-                       switch(GroupCipher)
-                       {
-                               case Ndis802_11GroupWEP40Enabled:
-                                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4);
-                                       break;
-                               case Ndis802_11GroupWEP104Enabled:
-                                       NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4);
-                                       break;
+                   (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+                   (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
+                       u32 GroupCipher = pAd->StaCfg.GroupCipher;
+                       switch (GroupCipher) {
+                       case Ndis802_11GroupWEP40Enabled:
+                               NdisMoveMemory(pRsnie_cipher->mcast,
+                                              OUI_WPA_WEP40, 4);
+                               break;
+                       case Ndis802_11GroupWEP104Enabled:
+                               NdisMoveMemory(pRsnie_cipher->mcast,
+                                              OUI_WPA_WEP104, 4);
+                               break;
                        }
                }
-
-               // swap for big-endian platform
+               /* swap for big-endian platform */
                pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
-           pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+               pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
        }
 }
 
@@ -477,8 +1712,8 @@ static VOID RTMPInsertRsnIeCipher(
 
        Arguments:
                pAd                     -       pointer to our pAdapter context
-       ElementID       -       indicate the WPA1 or WPA2
-       AuthMode        -       indicate the authentication mode
+       ElementID       -       indicate the WPA1 or WPA2
+       AuthMode        -       indicate the authentication mode
                apidx           -       indicate the interface index
 
        Return Value:
@@ -487,62 +1722,66 @@ static VOID RTMPInsertRsnIeCipher(
 
        ========================================================================
 */
-static VOID RTMPInsertRsnIeAKM(
-       IN  PRTMP_ADAPTER   pAd,
-       IN      UCHAR                   ElementID,
-       IN      UINT                    AuthMode,
-       IN      UCHAR                   apidx,
-       OUT     PUCHAR                  pRsnIe,
-       OUT     UCHAR                   *rsn_len)
+static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd,
+                            u8 ElementID,
+                            u32 AuthMode,
+                            u8 apidx,
+                            u8 *pRsnIe, u8 * rsn_len)
 {
-       RSNIE_AUTH              *pRsnie_auth;
+       struct rt_rsnie_auth *pRsnie_auth;
+       u8 AkmCnt = 1;  /* default as 1 */
 
-       pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
+       pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len));
 
-       // decide WPA2 or WPA1
-       if (ElementID == Wpa2Ie)
-       {
-               switch (AuthMode)
-        {
-            case Ndis802_11AuthModeWPA2:
-            case Ndis802_11AuthModeWPA1WPA2:
-                pRsnie_auth->acount = 1;
-                       NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
-                break;
-
-            case Ndis802_11AuthModeWPA2PSK:
-            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-                pRsnie_auth->acount = 1;
-                       NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
-                break;
-        }
-       }
-       else
-       {
-               switch (AuthMode)
-        {
-            case Ndis802_11AuthModeWPA:
-            case Ndis802_11AuthModeWPA1WPA2:
-                pRsnie_auth->acount = 1;
-                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
-                break;
-
-            case Ndis802_11AuthModeWPAPSK:
-            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-                pRsnie_auth->acount = 1;
-                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
-                break;
-
-                       case Ndis802_11AuthModeWPANone:
-                pRsnie_auth->acount = 1;
-                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
-                break;
-        }
+       /* decide WPA2 or WPA1 */
+       if (ElementID == Wpa2Ie) {
+
+               switch (AuthMode) {
+               case Ndis802_11AuthModeWPA2:
+               case Ndis802_11AuthModeWPA1WPA2:
+                       NdisMoveMemory(pRsnie_auth->auth[0].oui,
+                                      OUI_WPA2_8021X_AKM, 4);
+                       break;
+
+               case Ndis802_11AuthModeWPA2PSK:
+               case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+                       NdisMoveMemory(pRsnie_auth->auth[0].oui,
+                                      OUI_WPA2_PSK_AKM, 4);
+                       break;
+               default:
+                       AkmCnt = 0;
+                       break;
+
+               }
+       } else {
+               switch (AuthMode) {
+               case Ndis802_11AuthModeWPA:
+               case Ndis802_11AuthModeWPA1WPA2:
+                       NdisMoveMemory(pRsnie_auth->auth[0].oui,
+                                      OUI_WPA_8021X_AKM, 4);
+                       break;
+
+               case Ndis802_11AuthModeWPAPSK:
+               case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+                       NdisMoveMemory(pRsnie_auth->auth[0].oui,
+                                      OUI_WPA_PSK_AKM, 4);
+                       break;
+
+               case Ndis802_11AuthModeWPANone:
+                       NdisMoveMemory(pRsnie_auth->auth[0].oui,
+                                      OUI_WPA_NONE_AKM, 4);
+                       break;
+               default:
+                       AkmCnt = 0;
+                       break;
+               }
        }
 
+       pRsnie_auth->acount = AkmCnt;
        pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
 
-       (*rsn_len) += sizeof(RSNIE_AUTH);       // update current RSNIE length
+       /* update current RSNIE length */
+       (*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1)));
 
 }
 
@@ -555,7 +1794,7 @@ static VOID RTMPInsertRsnIeAKM(
 
        Arguments:
                pAd                     -       pointer to our pAdapter context
-       ElementID       -       indicate the WPA1 or WPA2
+       ElementID       -       indicate the WPA1 or WPA2
                apidx           -       indicate the interface index
 
        Return Value:
@@ -564,29 +1803,25 @@ static VOID RTMPInsertRsnIeAKM(
 
        ========================================================================
 */
-static VOID RTMPInsertRsnIeCap(
-       IN  PRTMP_ADAPTER   pAd,
-       IN      UCHAR                   ElementID,
-       IN      UCHAR                   apidx,
-       OUT     PUCHAR                  pRsnIe,
-       OUT     UCHAR                   *rsn_len)
+static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd,
+                            u8 ElementID,
+                            u8 apidx,
+                            u8 *pRsnIe, u8 * rsn_len)
 {
-       RSN_CAPABILITIES    *pRSN_Cap;
+       RSN_CAPABILITIES *pRSN_Cap;
 
-       // it could be ignored in WPA1 mode
+       /* it could be ignored in WPA1 mode */
        if (ElementID == WpaIe)
                return;
 
-       pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
-
+       pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len));
 
        pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
 
-       (*rsn_len) += sizeof(RSN_CAPABILITIES); // update current RSNIE length
+       (*rsn_len) += sizeof(RSN_CAPABILITIES); /* update current RSNIE length */
 
 }
 
-
 /*
        ========================================================================
 
@@ -595,8 +1830,8 @@ static VOID RTMPInsertRsnIeCap(
 
        Arguments:
                pAd                     -       pointer to our pAdapter context
-       AuthMode        -       indicate the authentication mode
-       WepStatus       -       indicate the encryption type
+       AuthMode        -       indicate the authentication mode
+       WepStatus       -       indicate the encryption type
                apidx           -       indicate the interface index
 
        Return Value:
@@ -605,51 +1840,43 @@ static VOID RTMPInsertRsnIeCap(
 
        ========================================================================
 */
-VOID RTMPMakeRSNIE(
-    IN  PRTMP_ADAPTER   pAd,
-    IN  UINT            AuthMode,
-    IN  UINT            WepStatus,
-       IN      UCHAR                   apidx)
+void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
+                  u32 AuthMode, u32 WepStatus, u8 apidx)
 {
-       PUCHAR          pRsnIe = NULL;                  // primary RSNIE
-       UCHAR           *rsnielen_cur_p = 0;    // the length of the primary RSNIE
-       UCHAR           *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE
-       UCHAR           PrimaryRsnie;
-       BOOLEAN         bMixCipher = FALSE;     // indicate the pairwise and group cipher are different
-       UCHAR           p_offset;
-       WPA_MIX_PAIR_CIPHER             FlexibleCipher = MIX_CIPHER_NOTUSE;     // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
+       u8 *pRsnIe = NULL;      /* primary RSNIE */
+       u8 *rsnielen_cur_p = 0; /* the length of the primary RSNIE */
+       u8 *rsnielen_ex_cur_p = 0;      /* the length of the secondary RSNIE */
+       u8 PrimaryRsnie;
+       BOOLEAN bMixCipher = FALSE;     /* indicate the pairwise and group cipher are different */
+       u8 p_offset;
+       WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES;  /* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */
 
        rsnielen_cur_p = NULL;
        rsnielen_ex_cur_p = NULL;
 
        {
-               IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
                {
-#ifdef WPA_SUPPLICANT_SUPPORT
-                       if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
-                       {
+                       if (pAd->StaCfg.WpaSupplicantUP !=
+                           WPA_SUPPLICANT_DISABLE) {
                                if (AuthMode < Ndis802_11AuthModeWPA)
                                        return;
-                       }
-                       else
-#endif // WPA_SUPPLICANT_SUPPORT //
-                       {
-                               // Support WPAPSK or WPA2PSK in STA-Infra mode
-                               // Support WPANone in STA-Adhoc mode
+                       } else {
+                               /* Support WPAPSK or WPA2PSK in STA-Infra mode */
+                               /* Support WPANone in STA-Adhoc mode */
                                if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
-                                       (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-                                       (AuthMode != Ndis802_11AuthModeWPANone)
-                                       )
+                                   (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+                                   (AuthMode != Ndis802_11AuthModeWPANone)
+                                   )
                                        return;
                        }
 
-                       DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
+                       DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n"));
 
-                       // Zero RSNIE context
+                       /* Zero RSNIE context */
                        pAd->StaCfg.RSNIE_Len = 0;
                        NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
 
-                       // Pointer to RSNIE
+                       /* Pointer to RSNIE */
                        rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
                        pRsnIe = pAd->StaCfg.RSN_IE;
 
@@ -657,34 +1884,35 @@ VOID RTMPMakeRSNIE(
                }
        }
 
-       // indicate primary RSNIE as WPA or WPA2
+       /* indicate primary RSNIE as WPA or WPA2 */
        if ((AuthMode == Ndis802_11AuthModeWPA) ||
-               (AuthMode == Ndis802_11AuthModeWPAPSK) ||
-               (AuthMode == Ndis802_11AuthModeWPANone) ||
-               (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
-               (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+           (AuthMode == Ndis802_11AuthModeWPAPSK) ||
+           (AuthMode == Ndis802_11AuthModeWPANone) ||
+           (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+           (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
                PrimaryRsnie = WpaIe;
        else
                PrimaryRsnie = Wpa2Ie;
 
        {
-               // Build the primary RSNIE
-               // 1. insert cipher suite
-               RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
+               /* Build the primary RSNIE */
+               /* 1. insert cipher suite */
+               RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher,
+                                   FlexibleCipher, pRsnIe, &p_offset);
 
-               // 2. insert AKM
-               RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
+               /* 2. insert AKM */
+               RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe,
+                                &p_offset);
 
-               // 3. insert capability
-               RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
+               /* 3. insert capability */
+               RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
        }
 
-       // 4. update the RSNIE length
+       /* 4. update the RSNIE length */
        *rsnielen_cur_p = p_offset;
 
        hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
 
-
 }
 
 /*
@@ -696,210 +1924,76 @@ VOID RTMPMakeRSNIE(
                pAd                             -       pointer to our pAdapter context
                pEntry                  -       pointer to active entry
                pData                   -       the received frame
-               DataByteCount   -       the received frame's length
+               DataByteCount   -       the received frame's length
                FromWhichBSSID  -       indicate the interface index
 
     Return:
-         TRUE                  -       This frame is EAP frame
-         FALSE                         -       otherwise
+         TRUE                  -       This frame is EAP frame
+         FALSE                 -       otherwise
     ==========================================================================
 */
-BOOLEAN RTMPCheckWPAframe(
-    IN PRTMP_ADAPTER    pAd,
-    IN PMAC_TABLE_ENTRY        pEntry,
-    IN PUCHAR           pData,
-    IN ULONG            DataByteCount,
-       IN UCHAR                        FromWhichBSSID)
+BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
+                         struct rt_mac_table_entry *pEntry,
+                         u8 *pData,
+                         unsigned long DataByteCount, u8 FromWhichBSSID)
 {
-       ULONG   Body_len;
+       unsigned long Body_len;
        BOOLEAN Cancelled;
 
+       if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
+               return FALSE;
 
-    if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
-        return FALSE;
-
-
-       // Skip LLC header
-    if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
-        // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
-        NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
-    {
-        pData += 6;
-    }
-       // Skip 2-bytes EAPoL type
-    if (NdisEqualMemory(EAPOL, pData, 2))
-    {
-        pData += 2;
-    }
-    else
-        return FALSE;
-
-    switch (*(pData+1))
-    {
-        case EAPPacket:
-                       Body_len = (*(pData+2)<<8) | (*(pData+3));
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
-            break;
-        case EAPOLStart:
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
-                       if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
-            {
-               DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
-                RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
-                pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
-            }
-            break;
-        case EAPOLLogoff:
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
-            break;
-        case EAPOLKey:
-                       Body_len = (*(pData+2)<<8) | (*(pData+3));
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
-            break;
-        case EAPOLASFAlert:
-            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
-            break;
-        default:
-            return FALSE;
-
-    }
-    return TRUE;
-}
-
-
-/*
-    ==========================================================================
-    Description:
-        ENCRYPT AES GTK before sending in EAPOL frame.
-        AES GTK length = 128 bit,  so fix blocks for aes-key-wrap as 2 in this function.
-        This function references to RFC 3394 for aes key wrap algorithm.
-    Return:
-    ==========================================================================
-*/
-VOID AES_GTK_KEY_WRAP(
-    IN UCHAR    *key,
-    IN UCHAR    *plaintext,
-    IN UCHAR    p_len,
-    OUT UCHAR   *ciphertext)
-{
-    UCHAR       A[8], BIN[16], BOUT[16];
-    UCHAR       R[512];
-    INT         num_blocks = p_len/8;   // unit:64bits
-    INT         i, j;
-    aes_context aesctx;
-    UCHAR       xor;
-
-    rtmp_aes_set_key(&aesctx, key, 128);
-
-    // Init IA
-    for (i = 0; i < 8; i++)
-        A[i] = 0xa6;
-
-    //Input plaintext
-    for (i = 0; i < num_blocks; i++)
-    {
-        for (j = 0 ; j < 8; j++)
-            R[8 * (i + 1) + j] = plaintext[8 * i + j];
-    }
-
-    // Key Mix
-    for (j = 0; j < 6; j++)
-    {
-        for(i = 1; i <= num_blocks; i++)
-        {
-            //phase 1
-            NdisMoveMemory(BIN, A, 8);
-            NdisMoveMemory(&BIN[8], &R[8 * i], 8);
-            rtmp_aes_encrypt(&aesctx, BIN, BOUT);
-
-            NdisMoveMemory(A, &BOUT[0], 8);
-            xor = num_blocks * j + i;
-            A[7] = BOUT[7] ^ xor;
-            NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
-        }
-    }
-
-    // Output ciphertext
-    NdisMoveMemory(ciphertext, A, 8);
-
-    for (i = 1; i <= num_blocks; i++)
-    {
-        for (j = 0 ; j < 8; j++)
-            ciphertext[8 * i + j] = R[8 * i + j];
-    }
-}
-
-
-/*
-       ========================================================================
-
-       Routine Description:
-               Misc function to decrypt AES body
-
-       Arguments:
-
-       Return Value:
-
-       Note:
-               This function references to     RFC     3394 for aes key unwrap algorithm.
-
-       ========================================================================
-*/
-VOID   AES_GTK_KEY_UNWRAP(
-       IN      UCHAR   *key,
-       OUT     UCHAR   *plaintext,
-       IN      UCHAR    c_len,
-       IN      UCHAR   *ciphertext)
-
-{
-       UCHAR       A[8], BIN[16], BOUT[16];
-       UCHAR       xor;
-       INT         i, j;
-       aes_context aesctx;
-       UCHAR       *R;
-       INT         num_blocks = c_len/8;       // unit:64bits
-
-
-       os_alloc_mem(NULL, (PUCHAR *)&R, 512);
-
-       if (R == NULL)
-    {
-        DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
-        return;
-    } /* End of if */
-
-       // Initialize
-       NdisMoveMemory(A, ciphertext, 8);
-       //Input plaintext
-       for(i = 0; i < (c_len-8); i++)
-       {
-               R[ i] = ciphertext[i + 8];
+       /* Skip LLC header */
+       if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
+           /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL */
+           NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) {
+               pData += 6;
        }
-
-       rtmp_aes_set_key(&aesctx, key, 128);
-
-       for(j = 5; j >= 0; j--)
-       {
-               for(i = (num_blocks-1); i > 0; i--)
-               {
-                       xor = (num_blocks -1 )* j + i;
-                       NdisMoveMemory(BIN, A, 8);
-                       BIN[7] = A[7] ^ xor;
-                       NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
-                       rtmp_aes_decrypt(&aesctx, BIN, BOUT);
-                       NdisMoveMemory(A, &BOUT[0], 8);
-                       NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
+       /* Skip 2-bytes EAPoL type */
+       if (NdisEqualMemory(EAPOL, pData, 2)) {
+               pData += 2;
+       } else
+               return FALSE;
+
+       switch (*(pData + 1)) {
+       case EAPPacket:
+               Body_len = (*(pData + 2) << 8) | (*(pData + 3));
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n",
+                         Body_len));
+               break;
+       case EAPOLStart:
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("Receive EAPOL-Start frame, TYPE = 1 \n"));
+               if (pEntry->EnqueueEapolStartTimerRunning !=
+                   EAPOL_START_DISABLE) {
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("Cancel the EnqueueEapolStartTimerRunning \n"));
+                       RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer,
+                                       &Cancelled);
+                       pEntry->EnqueueEapolStartTimerRunning =
+                           EAPOL_START_DISABLE;
                }
-       }
+               break;
+       case EAPOLLogoff:
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
+               break;
+       case EAPOLKey:
+               Body_len = (*(pData + 2) << 8) | (*(pData + 3));
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n",
+                         Body_len));
+               break;
+       case EAPOLASFAlert:
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
+               break;
+       default:
+               return FALSE;
 
-       // OUTPUT
-       for(i = 0; i < c_len; i++)
-       {
-               plaintext[i] = R[i];
        }
-
-
-       os_free_mem(NULL, R);
+       return TRUE;
 }
 
 /*
@@ -920,216 +2014,265 @@ VOID   AES_GTK_KEY_UNWRAP(
 
     ==========================================================================
 */
-CHAR *GetEapolMsgType(CHAR msg)
+char *GetEapolMsgType(char msg)
 {
-    if(msg == EAPOL_PAIR_MSG_1)
-        return "Pairwise Message 1";
-    else if(msg == EAPOL_PAIR_MSG_2)
-        return "Pairwise Message 2";
-       else if(msg == EAPOL_PAIR_MSG_3)
-        return "Pairwise Message 3";
-       else if(msg == EAPOL_PAIR_MSG_4)
-        return "Pairwise Message 4";
-       else if(msg == EAPOL_GROUP_MSG_1)
-        return "Group Message 1";
-       else if(msg == EAPOL_GROUP_MSG_2)
-        return "Group Message 2";
-    else
-       return "Invalid Message";
+       if (msg == EAPOL_PAIR_MSG_1)
+               return "Pairwise Message 1";
+       else if (msg == EAPOL_PAIR_MSG_2)
+               return "Pairwise Message 2";
+       else if (msg == EAPOL_PAIR_MSG_3)
+               return "Pairwise Message 3";
+       else if (msg == EAPOL_PAIR_MSG_4)
+               return "Pairwise Message 4";
+       else if (msg == EAPOL_GROUP_MSG_1)
+               return "Group Message 1";
+       else if (msg == EAPOL_GROUP_MSG_2)
+               return "Group Message 2";
+       else
+               return "Invalid Message";
 }
 
-
 /*
-    ========================================================================
+       ========================================================================
 
-    Routine Description:
+       Routine Description:
     Check Sanity RSN IE of EAPoL message
 
-    Arguments:
-
-    Return Value:
+       Arguments:
 
+       Return Value:
 
-    ========================================================================
+       ========================================================================
 */
-BOOLEAN RTMPCheckRSNIE(
-       IN  PRTMP_ADAPTER   pAd,
-       IN  PUCHAR          pData,
-       IN  UCHAR           DataLen,
-       IN  MAC_TABLE_ENTRY *pEntry,
-       OUT     UCHAR                   *Offset)
+BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd,
+                      u8 *pData,
+                      u8 DataLen,
+                      struct rt_mac_table_entry *pEntry, u8 * Offset)
 {
-       PUCHAR              pVIE;
-       UCHAR               len;
-       PEID_STRUCT         pEid;
-       BOOLEAN                         result = FALSE;
+       u8 *pVIE;
+       u8 len;
+       struct rt_eid * pEid;
+       BOOLEAN result = FALSE;
 
        pVIE = pData;
-       len      = DataLen;
+       len = DataLen;
        *Offset = 0;
 
-       while (len > sizeof(RSNIE2))
-       {
-               pEid = (PEID_STRUCT) pVIE;
-               // WPA RSN IE
-               if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
-               {
-                       if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
-                               (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
-                               (pEntry->RSNIE_Len == (pEid->Len + 2)))
-                       {
-                                       result = TRUE;
+       while (len > sizeof(struct rt_rsnie2)) {
+               pEid = (struct rt_eid *) pVIE;
+               /* WPA RSN IE */
+               if ((pEid->Eid == IE_WPA)
+                   && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) {
+                       if ((pEntry->AuthMode == Ndis802_11AuthModeWPA
+                            || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
+                           &&
+                           (NdisEqualMemory
+                            (pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len))
+                           && (pEntry->RSNIE_Len == (pEid->Len + 2))) {
+                               result = TRUE;
                        }
 
                        *Offset += (pEid->Len + 2);
                }
-               // WPA2 RSN IE
-               else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
-               {
-                       if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
-                               (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
-                               (pEntry->RSNIE_Len == (pEid->Len + 2))/* ToDo-AlbertY for mesh*/)
-                       {
-                                       result = TRUE;
+               /* WPA2 RSN IE */
+               else if ((pEid->Eid == IE_RSN)
+                        && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) {
+                       if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2
+                            || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
+                           && (pEid->Eid == pEntry->RSN_IE[0])
+                           && ((pEid->Len + 2) >= pEntry->RSNIE_Len)
+                           &&
+                           (NdisEqualMemory
+                            (pEid->Octet, &pEntry->RSN_IE[2],
+                             pEntry->RSNIE_Len - 2))) {
+
+                               result = TRUE;
                        }
 
                        *Offset += (pEid->Len + 2);
-               }
-               else
-               {
+               } else {
                        break;
                }
 
                pVIE += (pEid->Len + 2);
-               len  -= (pEid->Len + 2);
+               len -= (pEid->Len + 2);
        }
 
-
        return result;
 
 }
 
-
 /*
-    ========================================================================
+       ========================================================================
 
-    Routine Description:
+       Routine Description:
     Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
     GTK  is encaptulated in KDE format at  p.83 802.11i D10
 
-    Arguments:
+       Arguments:
 
-    Return Value:
+       Return Value:
 
-    Note:
+       Note:
         802.11i D10
 
-    ========================================================================
+       ========================================================================
 */
-BOOLEAN RTMPParseEapolKeyData(
-       IN  PRTMP_ADAPTER   pAd,
-       IN  PUCHAR          pKeyData,
-       IN  UCHAR           KeyDataLen,
-       IN      UCHAR                   GroupKeyIndex,
-       IN      UCHAR                   MsgType,
-       IN      BOOLEAN                 bWPA2,
-       IN  MAC_TABLE_ENTRY *pEntry)
+BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
+                             u8 *pKeyData,
+                             u8 KeyDataLen,
+                             u8 GroupKeyIndex,
+                             u8 MsgType,
+                             IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry)
 {
-    PKDE_ENCAP          pKDE = NULL;
-    PUCHAR              pMyKeyData = pKeyData;
-    UCHAR               KeyDataLength = KeyDataLen;
-    UCHAR               GTKLEN = 0;
-       UCHAR                           DefaultIdx = 0;
-       UCHAR                           skip_offset;
-
-       // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
-       if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
-    {
-               // Check RSN IE whether it is WPA2/WPA2PSK
-               if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
-               {
-                       // send wireless event - for RSN IE different
+       struct rt_kde_encap * pKDE = NULL;
+       u8 *pMyKeyData = pKeyData;
+       u8 KeyDataLength = KeyDataLen;
+       u8 GTKLEN = 0;
+       u8 DefaultIdx = 0;
+       u8 skip_offset;
+
+       /* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it */
+       if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) {
+               /* Check RSN IE whether it is WPA2/WPA2PSK */
+               if (!RTMPCheckRSNIE
+                   (pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) {
+                       /* send wireless event - for RSN IE different */
                        if (pAd->CommonCfg.bWirelessEvent)
-                               RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
-
-               DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
+                               RTMPSendWirelessEvent(pAd,
+                                                     IW_RSNIE_DIFF_EVENT_FLAG,
+                                                     pEntry->Addr,
+                                                     pEntry->apidx, 0);
+
+                       DBGPRINT(RT_DEBUG_ERROR,
+                                ("RSN_IE Different in msg %d of 4-way handshake!\n",
+                                 MsgType));
                        hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
-                       hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
+                       hex_dump("Desired RSN_IE ", pEntry->RSN_IE,
+                                pEntry->RSNIE_Len);
 
                        return FALSE;
-       }
-       else
-               {
-                       if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
-                       {
-                               // skip RSN IE
+               } else {
+                       if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) {
+                               WpaShowAllsuite(pMyKeyData, skip_offset);
+
+                               /* skip RSN IE */
                                pMyKeyData += skip_offset;
                                KeyDataLength -= skip_offset;
-                               DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
-                       }
-                       else
+                               DBGPRINT(RT_DEBUG_TRACE,
+                                        ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n",
+                                         skip_offset));
+                       } else
                                return TRUE;
                }
        }
 
-       DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
-
-       // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
-       if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
-       {
-               if (KeyDataLength >= 8) // KDE format exclude GTK length
-       {
-               pKDE = (PKDE_ENCAP) pMyKeyData;
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n",
+                 KeyDataLength));
+       /*hex_dump("remain data", pMyKeyData, KeyDataLength); */
 
+       /* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */
+       if (bWPA2
+           && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) {
+               if (KeyDataLength >= 8) /* KDE format exclude GTK length */
+               {
+                       pKDE = (struct rt_kde_encap *) pMyKeyData;
 
                        DefaultIdx = pKDE->GTKEncap.Kid;
 
-                       // Sanity check - KED length
-                       if (KeyDataLength < (pKDE->Len + 2))
-               {
-                       DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
-                       return FALSE;
-               }
-
-                       // Get GTK length - refer to IEEE 802.11i-2004 p.82
-                       GTKLEN = pKDE->Len -6;
-                       if (GTKLEN < LEN_AES_KEY)
-                       {
-                               DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
-                       return FALSE;
+                       /* Sanity check - KED length */
+                       if (KeyDataLength < (pKDE->Len + 2)) {
+                               DBGPRINT(RT_DEBUG_ERROR,
+                                        ("ERROR: The len from KDE is too short \n"));
+                               return FALSE;
+                       }
+                       /* Get GTK length - refer to IEEE 802.11i-2004 p.82 */
+                       GTKLEN = pKDE->Len - 6;
+                       if (GTKLEN < LEN_AES_KEY) {
+                               DBGPRINT(RT_DEBUG_ERROR,
+                                        ("ERROR: GTK Key length is too short (%d) \n",
+                                         GTKLEN));
+                               return FALSE;
                        }
 
-       }
-               else
-       {
-                       DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
-               return FALSE;
-       }
+               } else {
+                       DBGPRINT(RT_DEBUG_ERROR,
+                                ("ERROR: KDE format length is too short \n"));
+                       return FALSE;
+               }
 
-               DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
-               // skip it
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n",
+                         DefaultIdx, GTKLEN));
+               /* skip it */
                pMyKeyData += 8;
                KeyDataLength -= 8;
 
-       }
-       else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
-       {
+       } else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) {
                DefaultIdx = GroupKeyIndex;
-               DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
+               DBGPRINT(RT_DEBUG_TRACE,
+                        ("GTK DefaultKeyID=%d \n", DefaultIdx));
+       }
+       /* Sanity check - shared key index must be 1 ~ 3 */
+       if (DefaultIdx < 1 || DefaultIdx > 3) {
+               DBGPRINT(RT_DEBUG_ERROR,
+                        ("ERROR: GTK Key index(%d) is invalid in %s %s \n",
+                         DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"),
+                         GetEapolMsgType(MsgType)));
+               return FALSE;
        }
 
-       // Sanity check - shared key index must be 1 ~ 3
-       if (DefaultIdx < 1 || DefaultIdx > 3)
-    {
-       DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
-        return FALSE;
-    }
+       {
+               struct rt_cipher_key *pSharedKey;
+
+               /* set key material, TxMic and RxMic */
+               NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
+               pAd->StaCfg.DefaultKeyId = DefaultIdx;
+
+               pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
+
+               /* Prepare pair-wise key information into shared key table */
+               NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
+               pSharedKey->KeyLen = LEN_TKIP_EK;
+               NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
+               NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16],
+                              LEN_TKIP_RXMICK);
+               NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
+                              LEN_TKIP_TXMICK);
+
+               /* Update Shared Key CipherAlg */
+               pSharedKey->CipherAlg = CIPHER_NONE;
+               if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+                       pSharedKey->CipherAlg = CIPHER_TKIP;
+               else if (pAd->StaCfg.GroupCipher ==
+                        Ndis802_11Encryption3Enabled)
+                       pSharedKey->CipherAlg = CIPHER_AES;
+               else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+                       pSharedKey->CipherAlg = CIPHER_WEP64;
+               else if (pAd->StaCfg.GroupCipher ==
+                        Ndis802_11GroupWEP104Enabled)
+                       pSharedKey->CipherAlg = CIPHER_WEP128;
+
+               /* Update group key information to ASIC Shared Key Table */
+               AsicAddSharedKeyEntry(pAd,
+                                     BSS0,
+                                     pAd->StaCfg.DefaultKeyId,
+                                     pSharedKey->CipherAlg,
+                                     pSharedKey->Key,
+                                     pSharedKey->TxMic, pSharedKey->RxMic);
+
+               /* Update ASIC WCID attribute table and IVEIV table */
+               RTMPAddWcidAttributeEntry(pAd,
+                                         BSS0,
+                                         pAd->StaCfg.DefaultKeyId,
+                                         pSharedKey->CipherAlg, NULL);
+       }
 
        return TRUE;
 
 }
 
-
 /*
        ========================================================================
 
@@ -1167,7 +2310,6 @@ BOOLEAN RTMPParseEapolKeyData(
                | Key Data                       |      n octets
                +--------------------+
 
-
        Arguments:
                pAd                     Pointer to our adapter
 
@@ -1178,143 +2320,149 @@ BOOLEAN RTMPParseEapolKeyData(
 
        ========================================================================
 */
-VOID   ConstructEapolMsg(
-       IN      PRTMP_ADAPTER           pAd,
-    IN         UCHAR                           AuthMode,
-    IN         UCHAR                           WepStatus,
-    IN         UCHAR                           GroupKeyWepStatus,
-    IN         UCHAR                           MsgType,
-    IN UCHAR                           DefaultKeyIdx,
-    IN         UCHAR                           *ReplayCounter,
-       IN      UCHAR                           *KeyNonce,
-       IN      UCHAR                           *TxRSC,
-       IN      UCHAR                           *PTK,
-       IN      UCHAR                           *GTK,
-       IN      UCHAR                           *RSNIE,
-       IN      UCHAR                           RSNIE_Len,
-    OUT PEAPOL_PACKET       pMsg)
+void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
+                      u8 GroupKeyWepStatus,
+                      u8 MsgType,
+                      u8 DefaultKeyIdx,
+                      u8 * KeyNonce,
+                      u8 * TxRSC,
+                      u8 * GTK,
+                      u8 * RSNIE,
+                      u8 RSNIE_Len, struct rt_eapol_packet * pMsg)
 {
-       BOOLEAN bWPA2 = FALSE;
+       BOOLEAN bWPA2 = FALSE;
+       u8 KeyDescVer;
 
-       // Choose WPA2 or not
-       if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK))
+       /* Choose WPA2 or not */
+       if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+           (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
                bWPA2 = TRUE;
 
-    // Init Packet and Fill header
-    pMsg->ProVer = EAPOL_VER;
-    pMsg->ProType = EAPOLKey;
+       /* Init Packet and Fill header */
+       pMsg->ProVer = EAPOL_VER;
+       pMsg->ProType = EAPOLKey;
 
-       // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
-       pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG;
+       /* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */
+       SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
 
-       // Fill in EAPoL descriptor
+       /* Fill in EAPoL descriptor */
        if (bWPA2)
                pMsg->KeyDesc.Type = WPA2_KEY_DESC;
        else
                pMsg->KeyDesc.Type = WPA1_KEY_DESC;
 
-       // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
-       // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
-       pMsg->KeyDesc.KeyInfo.KeyDescVer =
-               (((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+       /* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */
+       {
+               /* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */
+               /* When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. */
+               KeyDescVer =
+                   (((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+                     || (GroupKeyWepStatus ==
+                         Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES)
+                    : (DESC_TYPE_TKIP));
+       }
+
+       pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
 
-       // Specify Key Type as Group(0) or Pairwise(1)
+       /* Specify Key Type as Group(0) or Pairwise(1) */
        if (MsgType >= EAPOL_GROUP_MSG_1)
                pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
        else
                pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
 
-       // Specify Key Index, only group_msg1_WPA1
+       /* Specify Key Index, only group_msg1_WPA1 */
        if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
                pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
 
        if (MsgType == EAPOL_PAIR_MSG_3)
                pMsg->KeyDesc.KeyInfo.Install = 1;
 
-       if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
+       if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3)
+           || (MsgType == EAPOL_GROUP_MSG_1))
                pMsg->KeyDesc.KeyInfo.KeyAck = 1;
 
        if (MsgType != EAPOL_PAIR_MSG_1)
                pMsg->KeyDesc.KeyInfo.KeyMic = 1;
 
-       if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
-    {
-               pMsg->KeyDesc.KeyInfo.Secure = 1;
-    }
-
-       if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
-    {
-        pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
-    }
+       if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
+           (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) {
+               pMsg->KeyDesc.KeyInfo.Secure = 1;
+       }
 
-       // key Information element has done.
-       *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
+       if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
+                     (MsgType == EAPOL_GROUP_MSG_1))) {
+               pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
+       }
+       /* key Information element has done. */
+       *(u16 *) (&pMsg->KeyDesc.KeyInfo) =
+           cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo));
 
-       // Fill in Key Length
+       /* Fill in Key Length */
        {
-               if (MsgType >= EAPOL_GROUP_MSG_1)
-               {
-                       // the length of group key cipher
-                       pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
-               }
-               else
-               {
-                       // the length of pairwise key cipher
-                       pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
+               if (MsgType >= EAPOL_GROUP_MSG_1) {
+                       /* the length of group key cipher */
+                       pMsg->KeyDesc.KeyLength[1] =
+                           ((GroupKeyWepStatus ==
+                             Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH :
+                            LEN_AES_KEY);
+               } else {
+                       /* the length of pairwise key cipher */
+                       pMsg->KeyDesc.KeyLength[1] =
+                           ((pEntry->WepStatus ==
+                             Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY :
+                            LEN_AES_KEY);
                }
        }
 
-       // Fill in replay counter
-    NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY);
-
-       // Fill Key Nonce field
-       // ANonce : pairwise_msg1 & pairwise_msg3
-       // SNonce : pairwise_msg2
-       // GNonce : group_msg1_wpa1
-       if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
-       NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
-
-       // Fill key IV - WPA2 as 0, WPA1 as random
-       if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
-       {
-               // Suggest IV be random number plus some number,
-               NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
-        pMsg->KeyDesc.KeyIv[15] += 2;
+       /* Fill in replay counter */
+       NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
+                      LEN_KEY_DESC_REPLAY);
+
+       /* Fill Key Nonce field */
+       /* ANonce : pairwise_msg1 & pairwise_msg3 */
+       /* SNonce : pairwise_msg2 */
+       /* GNonce : group_msg1_wpa1 */
+       if ((MsgType <= EAPOL_PAIR_MSG_3)
+           || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
+               NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce,
+                              LEN_KEY_DESC_NONCE);
+
+       /* Fill key IV - WPA2 as 0, WPA1 as random */
+       if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) {
+               /* Suggest IV be random number plus some number, */
+               NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16],
+                              LEN_KEY_DESC_IV);
+               pMsg->KeyDesc.KeyIv[15] += 2;
        }
-
-    // Fill Key RSC field
-    // It contains the RSC for the GTK being installed.
-       if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
-       {
-        NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
+       /* Fill Key RSC field */
+       /* It contains the RSC for the GTK being installed. */
+       if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
+           || (MsgType == EAPOL_GROUP_MSG_1)) {
+               NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
        }
-
-       // Clear Key MIC field for MIC calculation later
-    NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-
-       ConstructEapolKeyData(pAd,
-                                                 AuthMode,
-                                                 WepStatus,
-                                                 GroupKeyWepStatus,
-                                                 MsgType,
-                                                 DefaultKeyIdx,
-                                                 bWPA2,
-                                                 PTK,
-                                                 GTK,
-                                                 RSNIE,
-                                                 RSNIE_Len,
-                                                 pMsg);
-
-       // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
-       if (MsgType != EAPOL_PAIR_MSG_1)
-       {
-               CalculateMIC(pAd, WepStatus, PTK, pMsg);
+       /* Clear Key MIC field for MIC calculation later */
+       NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+       ConstructEapolKeyData(pEntry,
+                             GroupKeyWepStatus,
+                             KeyDescVer,
+                             MsgType,
+                             DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg);
+
+       /* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. */
+       if (MsgType != EAPOL_PAIR_MSG_1) {
+               CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
        }
 
-       DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
-       DBGPRINT(RT_DEBUG_TRACE, ("          Body length = %d \n", pMsg->Body_Len[1]));
-       DBGPRINT(RT_DEBUG_TRACE, ("          Key length  = %d \n", pMsg->KeyDesc.KeyLength[1]));
-
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("===> ConstructEapolMsg for %s %s\n",
+                 ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("          Body length = %d \n",
+                 CONV_ARRARY_TO_u16(pMsg->Body_Len)));
+       DBGPRINT(RT_DEBUG_TRACE,
+                ("          Key length  = %d \n",
+                 CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyLength)));
 
 }
 
@@ -1335,155 +2483,164 @@ VOID  ConstructEapolMsg(
 
        ========================================================================
 */
-VOID   ConstructEapolKeyData(
-       IN      PRTMP_ADAPTER   pAd,
-       IN      UCHAR                   AuthMode,
-       IN      UCHAR                   WepStatus,
-       IN      UCHAR                   GroupKeyWepStatus,
-       IN      UCHAR                   MsgType,
-       IN      UCHAR                   DefaultKeyIdx,
-       IN      BOOLEAN                 bWPA2Capable,
-       IN      UCHAR                   *PTK,
-       IN      UCHAR                   *GTK,
-       IN      UCHAR                   *RSNIE,
-       IN      UCHAR                   RSNIE_LEN,
-       OUT PEAPOL_PACKET   pMsg)
+void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
+                          u8 GroupKeyWepStatus,
+                          u8 keyDescVer,
+                          u8 MsgType,
+                          u8 DefaultKeyIdx,
+                          u8 * GTK,
+                          u8 * RSNIE,
+                          u8 RSNIE_LEN, struct rt_eapol_packet * pMsg)
 {
-       UCHAR           *mpool, *Key_Data, *Rc4GTK;
-       UCHAR       ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
-       UCHAR           data_offset;
-
-
-       if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
+       u8 *mpool, *Key_Data, *Rc4GTK;
+       u8 ekey[(LEN_KEY_DESC_IV + LEN_EAP_EK)];
+       unsigned long data_offset;
+       BOOLEAN bWPA2Capable = FALSE;
+       struct rt_rtmp_adapter *pAd = pEntry->pAd;
+       BOOLEAN GTK_Included = FALSE;
+
+       /* Choose WPA2 or not */
+       if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+           (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+               bWPA2Capable = TRUE;
+
+       if (MsgType == EAPOL_PAIR_MSG_1 ||
+           MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
                return;
 
-       // allocate memory pool
-       os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500);
+       /* allocate memory pool */
+       os_alloc_mem(NULL, (u8 **) & mpool, 1500);
 
-    if (mpool == NULL)
+       if (mpool == NULL)
                return;
 
        /* Rc4GTK Len = 512 */
-       Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
+       Rc4GTK = (u8 *) ROUND_UP(mpool, 4);
        /* Key_Data Len = 512 */
-       Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
+       Key_Data = (u8 *) ROUND_UP(Rc4GTK + 512, 4);
 
        NdisZeroMemory(Key_Data, 512);
-       pMsg->KeyDesc.KeyDataLen[1] = 0;
+       SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
        data_offset = 0;
 
-       // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
-       if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
-       {
-               if (bWPA2Capable)
-                       Key_Data[data_offset + 0] = IE_WPA2;
-               else
-                       Key_Data[data_offset + 0] = IE_WPA;
+       /* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */
+       if (RSNIE_LEN
+           && ((MsgType == EAPOL_PAIR_MSG_2)
+               || (MsgType == EAPOL_PAIR_MSG_3))) {
+               u8 *pmkid_ptr = NULL;
+               u8 pmkid_len = 0;
 
-        Key_Data[data_offset + 1] = RSNIE_LEN;
-               NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN);
-               data_offset += (2 + RSNIE_LEN);
+               RTMPInsertRSNIE(&Key_Data[data_offset],
+                               &data_offset,
+                               RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len);
        }
 
-       // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
-       if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
-       {
-               // Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h
-        Key_Data[data_offset + 0] = 0xDD;
-
-               if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
-               {
-                       Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
-               }
-               else
-               {
-                       Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
+       /* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */
+       if (bWPA2Capable
+           && ((MsgType == EAPOL_PAIR_MSG_3)
+               || (MsgType == EAPOL_GROUP_MSG_1))) {
+               /* Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h */
+               Key_Data[data_offset + 0] = 0xDD;
+
+               if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
+                       Key_Data[data_offset + 1] = 0x16;       /* 4+2+16(OUI+DataType+DataField) */
+               } else {
+                       Key_Data[data_offset + 1] = 0x26;       /* 4+2+32(OUI+DataType+DataField) */
                }
 
-        Key_Data[data_offset + 2] = 0x00;
-        Key_Data[data_offset + 3] = 0x0F;
-        Key_Data[data_offset + 4] = 0xAC;
-        Key_Data[data_offset + 5] = 0x01;
+               Key_Data[data_offset + 2] = 0x00;
+               Key_Data[data_offset + 3] = 0x0F;
+               Key_Data[data_offset + 4] = 0xAC;
+               Key_Data[data_offset + 5] = 0x01;
 
-               // GTK KDE format - 802.11i-2004  Figure-43x
-        Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
-        Key_Data[data_offset + 7] = 0x00;      // Reserved Byte
+               /* GTK KDE format - 802.11i-2004  Figure-43x */
+               Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
+               Key_Data[data_offset + 7] = 0x00;       /* Reserved Byte */
 
                data_offset += 8;
        }
 
-
-       // Encapsulate GTK and encrypt the key-data field with KEK.
-       // Only for pairwise_msg3_WPA2 and group_msg1
-       if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
-       {
-               // Fill in GTK
-               if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
-               {
-                       NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
+       /* Encapsulate GTK */
+       /* Only for pairwise_msg3_WPA2 and group_msg1 */
+       if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
+           || (MsgType == EAPOL_GROUP_MSG_1)) {
+               /* Fill in GTK */
+               if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
+                       NdisMoveMemory(&Key_Data[data_offset], GTK,
+                                      LEN_AES_KEY);
                        data_offset += LEN_AES_KEY;
-               }
-               else
-               {
-                       NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
+               } else {
+                       NdisMoveMemory(&Key_Data[data_offset], GTK,
+                                      TKIP_GTK_LENGTH);
                        data_offset += TKIP_GTK_LENGTH;
                }
 
-               // Still dont know why, but if not append will occur "GTK not include in MSG3"
-               // Patch for compatibility between zero config and funk
-               if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
-               {
-                       if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
-                       {
-                               Key_Data[data_offset + 0] = 0xDD;
-                               Key_Data[data_offset + 1] = 0;
-                               data_offset += 2;
-                       }
-                       else
-                       {
-                               Key_Data[data_offset + 0] = 0xDD;
-                               Key_Data[data_offset + 1] = 0;
-                               Key_Data[data_offset + 2] = 0;
-                               Key_Data[data_offset + 3] = 0;
-                               Key_Data[data_offset + 4] = 0;
-                               Key_Data[data_offset + 5] = 0;
-                               data_offset += 6;
+               GTK_Included = TRUE;
+       }
+
+       /* This whole key-data field shall be encrypted if a GTK is included. */
+       /* Encrypt the data material in key data field with KEK */
+       if (GTK_Included) {
+               /*hex_dump("GTK_Included", Key_Data, data_offset); */
+
+               if ((keyDescVer == DESC_TYPE_AES)) {
+                       u8 remainder = 0;
+                       u8 pad_len = 0;
+
+                       /* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */
+                       /* shall be used to encrypt the Key Data field using the KEK field from */
+                       /* the derived PTK. */
+
+                       /* If the Key Data field uses the NIST AES key wrap, then the Key Data field */
+                       /* shall be padded before encrypting if the key data length is less than 16 */
+                       /* octets or if it is not a multiple of 8. The padding consists of appending */
+                       /* a single octet 0xdd followed by zero or more 0x00 octets. */
+                       if ((remainder = data_offset & 0x07) != 0) {
+                               int i;
+
+                               pad_len = (8 - remainder);
+                               Key_Data[data_offset] = 0xDD;
+                               for (i = 1; i < pad_len; i++)
+                                       Key_Data[data_offset + i] = 0;
+
+                               data_offset += pad_len;
                        }
-               }
 
-               // Encrypt the data material in key data field
-               if (WepStatus == Ndis802_11Encryption3Enabled)
-               {
-                       AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK);
-            // AES wrap function will grow 8 bytes in length
-            data_offset += 8;
-               }
-               else
-               {
-                       // PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
-                       // put TxTsc in Key RSC field
-                       pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.
-
-                       // ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
-                       NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
-                       NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK);
-                       ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey));  //INIT SBOX, KEYLEN+3(IV)
-                       pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
-                       WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
+                       AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data,
+                                        data_offset, Rc4GTK);
+                       /* AES wrap function will grow 8 bytes in length */
+                       data_offset += 8;
+               } else {
+                       /*      Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
+                          using the KEK field from the derived PTK. */
+
+                       /* PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) */
+                       /* put TxTsc in Key RSC field */
+                       pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;       /*Init crc32. */
+
+                       /* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */
+                       NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv,
+                                      LEN_KEY_DESC_IV);
+                       NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16],
+                                      LEN_EAP_EK);
+                       ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); /*INIT SBOX, KEYLEN+3(IV) */
+                       pAd->PrivateInfo.FCSCRC32 =
+                           RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data,
+                                           data_offset);
+                       WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK,
+                                          Key_Data, data_offset);
                }
 
                NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
-       }
-       else
-       {
+       } else {
                NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
        }
 
-       // set key data length field and total length
-       pMsg->KeyDesc.KeyDataLen[1] = data_offset;
-    pMsg->Body_Len[1] += data_offset;
+       /* Update key data length field and total body length */
+       SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
+       INC_u16_TO_ARRARY(pMsg->Body_Len, data_offset);
 
-       os_free_mem(pAd, mpool);
+       os_free_mem(NULL, mpool);
 
 }
 
@@ -1494,8 +2651,8 @@ VOID      ConstructEapolKeyData(
                Calcaulate MIC. It is used during 4-ways handsharking.
 
        Arguments:
-               pAd                             -       pointer to our pAdapter context
-       PeerWepStatus   -       indicate the encryption type
+               pAd                     -       pointer to our pAdapter context
+       PeerWepStatus   -       indicate the encryption type
 
        Return Value:
 
@@ -1503,48 +2660,42 @@ VOID    ConstructEapolKeyData(
 
        ========================================================================
 */
-VOID   CalculateMIC(
-       IN      PRTMP_ADAPTER   pAd,
-       IN      UCHAR                   PeerWepStatus,
-       IN      UCHAR                   *PTK,
-       OUT PEAPOL_PACKET   pMsg)
+static void CalculateMIC(u8 KeyDescVer,
+                        u8 * PTK, struct rt_eapol_packet * pMsg)
 {
-    UCHAR   *OutBuffer;
-       ULONG   FrameLen = 0;
-       UCHAR   mic[LEN_KEY_DESC_MIC];
-       UCHAR   digest[80];
+       u8 *OutBuffer;
+       unsigned long FrameLen = 0;
+       u8 mic[LEN_KEY_DESC_MIC];
+       u8 digest[80];
 
-       // allocate memory for MIC calculation
-       os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512);
+       /* allocate memory for MIC calculation */
+       os_alloc_mem(NULL, (u8 **) & OutBuffer, 512);
 
-    if (OutBuffer == NULL)
-    {
-               DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
+       if (OutBuffer == NULL) {
+               DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n"));
                return;
-    }
-
-       // make a frame for calculating MIC.
-    MakeOutgoingFrame(OutBuffer,               &FrameLen,
-                      pMsg->Body_Len[1] + 4,   pMsg,
-                      END_OF_ARGS);
+       }
+       /* make a frame for calculating MIC. */
+       MakeOutgoingFrame(OutBuffer, &FrameLen,
+                         CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg,
+                         END_OF_ARGS);
 
        NdisZeroMemory(mic, sizeof(mic));
 
-       // Calculate MIC
-    if (PeerWepStatus == Ndis802_11Encryption3Enabled)
-       {
-               HMAC_SHA1(OutBuffer,  FrameLen, PTK, LEN_EAP_MICK, digest);
+       /* Calculate MIC */
+       if (KeyDescVer == DESC_TYPE_AES) {
+               HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest,
+                         SHA1_DIGEST_SIZE);
                NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
-       }
-       else
-       {
-               hmac_md5(PTK,  LEN_EAP_MICK, OutBuffer, FrameLen, mic);
+       } else {
+               HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic,
+                        MD5_DIGEST_SIZE);
        }
 
-       // store the calculated MIC
+       /* store the calculated MIC */
        NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
 
-       os_free_mem(pAd, OutBuffer);
+       os_free_mem(NULL, OutBuffer);
 }
 
 /*
@@ -1554,8 +2705,8 @@ VOID      CalculateMIC(
                Some received frames can't decrypt by Asic, so decrypt them by software.
 
        Arguments:
-               pAd                             -       pointer to our pAdapter context
-       PeerWepStatus   -       indicate the encryption type
+               pAd                     -       pointer to our pAdapter context
+       PeerWepStatus   -       indicate the encryption type
 
        Return Value:
                NDIS_STATUS_SUCCESS             -       decryption successful
@@ -1563,67 +2714,59 @@ VOID    CalculateMIC(
 
        ========================================================================
 */
-NDIS_STATUS    RTMPSoftDecryptBroadCastData(
-       IN      PRTMP_ADAPTER                                   pAd,
-       IN      RX_BLK                                                  *pRxBlk,
-       IN  NDIS_802_11_ENCRYPTION_STATUS       GroupCipher,
-       IN  PCIPHER_KEY                                         pShard_key)
+int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd,
+                                        struct rt_rx_blk *pRxBlk,
+                                        IN NDIS_802_11_ENCRYPTION_STATUS
+                                        GroupCipher, struct rt_cipher_key *pShard_key)
 {
-       PRXWI_STRUC                     pRxWI = pRxBlk->pRxWI;
-
+       struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
 
+       /* handle WEP decryption */
+       if (GroupCipher == Ndis802_11Encryption1Enabled) {
+               if (RTMPSoftDecryptWEP
+                   (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
+                    pShard_key)) {
 
-       // handle WEP decryption
-       if (GroupCipher == Ndis802_11Encryption1Enabled)
-    {
-               if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
-               {
-
-                       //Minus IV[4] & ICV[4]
+                       /*Minus IV[4] & ICV[4] */
                        pRxWI->MPDUtotalByteCount -= 8;
-               }
-               else
-               {
-                       DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
-                       // give up this frame
+               } else {
+                       DBGPRINT(RT_DEBUG_ERROR,
+                                ("ERROR : Software decrypt WEP data fails.\n"));
+                       /* give up this frame */
                        return NDIS_STATUS_FAILURE;
                }
        }
-       // handle TKIP decryption
-       else if (GroupCipher == Ndis802_11Encryption2Enabled)
-       {
-               if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
-               {
+       /* handle TKIP decryption */
+       else if (GroupCipher == Ndis802_11Encryption2Enabled) {
+               if (RTMPSoftDecryptTKIP
+                   (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0,
+                    pShard_key)) {
 
-                       //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
+                       /*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */
                        pRxWI->MPDUtotalByteCount -= 20;
-               }
-        else
-               {
-                       DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
-                       // give up this frame
+               } else {
+                       DBGPRINT(RT_DEBUG_ERROR,
+                                ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
+                       /* give up this frame */
                        return NDIS_STATUS_FAILURE;
-        }
+               }
        }
-       // handle AES decryption
-       else if (GroupCipher == Ndis802_11Encryption3Enabled)
-       {
-               if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
-               {
+       /* handle AES decryption */
+       else if (GroupCipher == Ndis802_11Encryption3Enabled) {
+               if (RTMPSoftDecryptAES
+                   (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
+                    pShard_key)) {
 
-                       //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
+                       /*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */
                        pRxWI->MPDUtotalByteCount -= 16;
-               }
-               else
-               {
-                       DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
-                       // give up this frame
+               } else {
+                       DBGPRINT(RT_DEBUG_ERROR,
+                                ("ERROR : RTMPSoftDecryptAES Failed\n"));
+                       /* give up this frame */
                        return NDIS_STATUS_FAILURE;
                }
-       }
-       else
-       {
-               // give up this frame
+       } else {
+               /* give up this frame */
                return NDIS_STATUS_FAILURE;
        }
 
@@ -1631,3 +2774,241 @@ NDIS_STATUS     RTMPSoftDecryptBroadCastData(
 
 }
 
+u8 *GetSuiteFromRSNIE(u8 *rsnie,
+                        u32 rsnie_len, u8 type, u8 * count)
+{
+       struct rt_eid * pEid;
+       int len;
+       u8 *pBuf;
+       int offset = 0;
+       struct rt_rsnie_auth *pAkm;
+       u16 acount;
+       BOOLEAN isWPA2 = FALSE;
+
+       pEid = (struct rt_eid *) rsnie;
+       len = rsnie_len - 2;    /* exclude IE and length */
+       pBuf = (u8 *)& pEid->Octet[0];
+
+       /* set default value */
+       *count = 0;
+
+       /* Check length */
+       if ((len <= 0) || (pEid->Len != len)) {
+               DBGPRINT_ERR(("%s : The length is invalid\n", __func__));
+               return NULL;
+       }
+       /* Check WPA or WPA2 */
+       if (pEid->Eid == IE_WPA) {
+               struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf;
+               u16 ucount;
+
+               if (len < sizeof(struct rt_rsnie)) {
+                       DBGPRINT_ERR(("%s : The length is too short for WPA\n",
+                                     __func__));
+                       return NULL;
+               }
+               /* Get the count of pairwise cipher */
+               ucount = cpu2le16(pRsnie->ucount);
+               if (ucount > 2) {
+                       DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount));
+                       return NULL;
+               }
+               /* Get the group cipher */
+               if (type == GROUP_SUITE) {
+                       *count = 1;
+                       return pRsnie->mcast;
+               }
+               /* Get the pairwise cipher suite */
+               else if (type == PAIRWISE_SUITE) {
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("%s : The count of pairwise cipher is %d\n",
+                                 __func__, ucount));
+                       *count = ucount;
+                       return pRsnie->ucast[0].oui;
+               }
+
+               offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1));
+
+       } else if (pEid->Eid == IE_RSN) {
+               struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf;
+               u16 ucount;
+
+               isWPA2 = TRUE;
+
+               if (len < sizeof(struct rt_rsnie2)) {
+                       DBGPRINT_ERR(("%s : The length is too short for WPA2\n",
+                                     __func__));
+                       return NULL;
+               }
+               /* Get the count of pairwise cipher */
+               ucount = cpu2le16(pRsnie->ucount);
+               if (ucount > 2) {
+                       DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount));
+                       return NULL;
+               }
+               /* Get the group cipher */
+               if (type == GROUP_SUITE) {
+                       *count = 1;
+                       return pRsnie->mcast;
+               }
+               /* Get the pairwise cipher suite */
+               else if (type == PAIRWISE_SUITE) {
+                       DBGPRINT(RT_DEBUG_TRACE,
+                                ("%s : The count of pairwise cipher is %d\n",
+                                 __func__, ucount));
+                       *count = ucount;
+                       return pRsnie->ucast[0].oui;
+               }
+
+               offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1));
+
+       } else {
+               DBGPRINT_ERR(("%s : Unknown IE (%d)\n", __func__, pEid->Eid));
+               return NULL;
+       }
+
+       /* skip group cipher and pairwise cipher suite */
+       pBuf += offset;
+       len -= offset;
+
+       if (len < sizeof(struct rt_rsnie_auth)) {
+               DBGPRINT_ERR(("%s : The length of RSNIE is too short\n",
+                             __func__));
+               return NULL;
+       }
+       /* pointer to AKM count */
+       pAkm = (struct rt_rsnie_auth *)pBuf;
+
+       /* Get the count of pairwise cipher */
+       acount = cpu2le16(pAkm->acount);
+       if (acount > 2) {
+               DBGPRINT_ERR(("%s : The count(%d) of AKM is invlaid\n",
+                             __func__, acount));
+               return NULL;
+       }
+       /* Get the AKM suite */
+       if (type == AKM_SUITE) {
+               DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
+                                         __func__, acount));
+               *count = acount;
+               return pAkm->auth[0].oui;
+       }
+       offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1));
+
+       pBuf += offset;
+       len -= offset;
+
+       /* The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) */
+       if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) {
+               /* Skip RSN capability and PMKID-Count */
+               pBuf += (sizeof(RSN_CAPABILITIES) + 2);
+               len -= (sizeof(RSN_CAPABILITIES) + 2);
+
+               /* Get PMKID */
+               if (type == PMKID_LIST) {
+                       *count = 1;
+                       return pBuf;
+               }
+       } else {
+               DBGPRINT_ERR(("%s : it can't get any more information beyond AKM \n", __func__));
+               return NULL;
+       }
+
+       *count = 0;
+       /*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */
+       return NULL;
+
+}
+
+void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len)
+{
+       u8 *pSuite = NULL;
+       u8 count;
+
+       hex_dump("RSNIE", rsnie, rsnie_len);
+
+       /* group cipher */
+       pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count);
+       if (pSuite != NULL) {
+               hex_dump("group cipher", pSuite, 4 * count);
+       }
+       /* pairwise cipher */
+       pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count);
+       if (pSuite != NULL) {
+               hex_dump("pairwise cipher", pSuite, 4 * count);
+       }
+       /* AKM */
+       pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count);
+       if (pSuite != NULL) {
+               hex_dump("AKM suite", pSuite, 4 * count);
+       }
+       /* PMKID */
+       pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count);
+       if (pSuite != NULL) {
+               hex_dump("PMKID", pSuite, LEN_PMKID);
+       }
+
+}
+
+void RTMPInsertRSNIE(u8 *pFrameBuf,
+                    unsigned long *pFrameLen,
+                    u8 *rsnie_ptr,
+                    u8 rsnie_len,
+                    u8 *pmkid_ptr, u8 pmkid_len)
+{
+       u8 *pTmpBuf;
+       unsigned long TempLen = 0;
+       u8 extra_len = 0;
+       u16 pmk_count = 0;
+       u8 ie_num;
+       u8 total_len = 0;
+       u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC };
+
+       pTmpBuf = pFrameBuf;
+
+       /* PMKID-List Must larger than 0 and the multiple of 16. */
+       if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) {
+               extra_len = sizeof(u16)+ pmkid_len;
+
+               pmk_count = (pmkid_len >> 4);
+               pmk_count = cpu2le16(pmk_count);
+       } else {
+               DBGPRINT(RT_DEBUG_WARN,
+                        ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
+                         __func__, pmkid_len));
+       }
+
+       if (rsnie_len != 0) {
+               ie_num = IE_WPA;
+               total_len = rsnie_len;
+
+               if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) {
+                       ie_num = IE_RSN;
+                       total_len += extra_len;
+               }
+
+               /* construct RSNIE body */
+               MakeOutgoingFrame(pTmpBuf, &TempLen,
+                                 1, &ie_num,
+                                 1, &total_len,
+                                 rsnie_len, rsnie_ptr, END_OF_ARGS);
+
+               pTmpBuf += TempLen;
+               *pFrameLen = *pFrameLen + TempLen;
+
+               if (ie_num == IE_RSN) {
+                       /* Insert PMKID-List field */
+                       if (extra_len > 0) {
+                               MakeOutgoingFrame(pTmpBuf, &TempLen,
+                                                 2, &pmk_count,
+                                                 pmkid_len, pmkid_ptr,
+                                                 END_OF_ARGS);
+
+                               pTmpBuf += TempLen;
+                               *pFrameLen = *pFrameLen + TempLen;
+                       }
+               }
+       }
+
+       return;
+}