VOID PeerP2pNoaAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { PP2P_ACTION_FRAME pFrame = (PP2P_ACTION_FRAME)Elem->Msg; PMAC_TABLE_ENTRY pClient; DBGPRINT(RT_DEBUG_TRACE,("PeerP2pNoaAction %s. \n", decodeP2PState(pAd->P2pCfg.P2PConnectState))); DBGPRINT(RT_DEBUG_TRACE,("Category = %d. Subtype = %d. Token = %d.\n", pFrame->Category, pFrame->Subtype, pFrame->Token)); if (!P2P_CLI_ON(pAd)) { DBGPRINT(RT_DEBUG_TRACE,("PeerP2pNoaAction return %s. \n", decodeP2PState(pAd->P2pCfg.P2PConnectState))); return; } if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) { DBGPRINT(RT_DEBUG_TRACE,("PeerP2pNoaAction Elem->Wcid %d. return.\n", Elem->Wcid)); return; } pClient = &pAd->MacTab.Content[Elem->Wcid]; pAd->P2pCfg.NoAIndex = Elem->Wcid; DBGPRINT(RT_DEBUG_TRACE,("PeerP2pNoaAction Current NoAToken = %d. \n", pClient->P2pInfo.NoAToken)); if (pFrame->Token != pClient->P2pInfo.NoAToken) { if ((RTMPEqualMemory(&pFrame->Octet[0], P2POUIBYTE, 4)) && (pFrame->Octet[4] == SUBID_P2P_NOA)) { DBGPRINT(RT_DEBUG_TRACE,("PeerP2pNoaAction CTWindow = %d. \n", pFrame->Octet[8])); pClient->P2pInfo.CTWindow = pFrame->Octet[8]; P2pHandleNoAAttri(pAd, pClient, &pFrame->Octet[0]); } } }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ USHORT TDLS_TPKMsg1Process( IN PRTMP_ADAPTER pAd, IN PRT_802_11_TDLS pTDLS, IN PUCHAR pRsnIe, IN UCHAR RsnLen, IN PUCHAR pFTIe, IN UCHAR FTLen, IN PUCHAR pTIIe, IN UCHAR TILen) { USHORT StatusCode = MLME_SUCCESS; UCHAR CipherTmp[64] = {0}; UCHAR CipherTmpLen = 0; FT_FTIE *ft = NULL; // Validate RsnIE // if (RsnLen == 0) // RSN not exist return MLME_INVALID_INFORMATION_ELEMENT; if (pRsnIe[2] < 1) // Smaller version return MLME_NOT_SUPPORT_RSN_VERSION; CipherTmpLen = CipherSuiteTDLSLen; if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) NdisMoveMemory(CipherTmp, CipherSuiteTDLSWpa2PskTkip, CipherTmpLen); else NdisMoveMemory(CipherTmp, CipherSuiteTDLSWpa2PskAes, CipherTmpLen); if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) CipherTmp[19] = TDLS_AKM_SUITE_1X; if ( RTMPEqualMemory(&pRsnIe[16], &CipherTmp[16], 4) == 0) // Invalid TDLS AKM return MLME_INVALID_AKMP; if ( RTMPEqualMemory(&pRsnIe[20], &CipherTmp[20], 2) == 0) // Invalid RSN capability return MLME_INVALID_RSN_CAPABILITIES; if ((RsnLen != 22) || (RTMPEqualMemory(pRsnIe, CipherTmp, RsnLen) == 0)) // Invalid Pairwise Cipher return REASON_UCIPHER_NOT_VALID; // Validate FTIE // ft = (PFT_FTIE)(pFTIe + 2); // point to the element of IE if ((FTLen != (sizeof(FT_FTIE) + 2)) || RTMPEqualMemory(&ft->MICCtr, TdlsZeroSsid, 2) == 0 || (RTMPEqualMemory(ft->MIC, TdlsZeroSsid, 16) == 0) || (RTMPEqualMemory(ft->ANonce, TdlsZeroSsid, 32) == 0)) return REASON_FT_INVALID_FTIE; // Validate TIIE // if ((TILen != 7) || (pTIIe[2] != 2) || ( le2cpu32(*((PULONG) (pTIIe + 3))) < TDLS_KEY_TIMEOUT)) return TDLS_STATUS_CODE_UNACCEPTABLE_LIFETIME; return StatusCode; }
/* ========================================================================== Description: Check invalidity of authentication method selection in RSN IE. Return: true if match false otherwise ========================================================================== */ bool RTMPCheckAKM(u8 *sta_akm, u8 *ap_rsn_ie, INT iswpa2) { u8 *pTmp; unsigned short Count; pTmp = ap_rsn_ie; if(iswpa2) /* skip Version(2),Multicast cipter(4) 2+4==6 */ pTmp +=6; else /*skip OUI(4),Vesrion(2),Multicast cipher(4) 4+2+4==10 */ pTmp += 10;/*point to number of unicast */ memmove(&Count, pTmp, sizeof(unsigned short)); Count = cpu2le16(Count); pTmp += sizeof(unsigned short);/*pointer to unicast cipher */ /* Skip all unicast cipher suite */ while (Count > 0) { /* Skip OUI */ pTmp += 4; Count--; } memmove(&Count, pTmp, sizeof(unsigned short)); Count = cpu2le16(Count); pTmp += sizeof(unsigned short);/*pointer to AKM cipher */ while (Count > 0) { /*rtmp_hexdump(RT_DEBUG_TRACE,"MBSS WPA_IE AKM ",pTmp,4); */ if(RTMPEqualMemory(sta_akm,pTmp,4)) return true; else { pTmp += 4; Count--; } } return false;/* do not match the AKM */ }
/* ========================================================================== Description: Check invalidity of authentication method selection in RSN IE. Return: TRUE if match FALSE otherwise ========================================================================== */ BOOLEAN RTMPCheckAKM(PUCHAR sta_akm, PUCHAR ap_rsn_ie, INT iswpa2) { PUCHAR pTmp; USHORT Count; pTmp = ap_rsn_ie; if(iswpa2) /* skip Version(2),Multicast cipter(4) 2+4==6 */ pTmp +=6; else /*skip OUI(4),Vesrion(2),Multicast cipher(4) 4+2+4==10 */ pTmp += 10;/*point to number of unicast */ NdisMoveMemory(&Count, pTmp, sizeof(USHORT)); Count = cpu2le16(Count); pTmp += sizeof(USHORT);/*pointer to unicast cipher */ /* Skip all unicast cipher suite */ while (Count > 0) { /* Skip OUI */ pTmp += 4; Count--; } NdisMoveMemory(&Count, pTmp, sizeof(USHORT)); Count = cpu2le16(Count); pTmp += sizeof(USHORT);/*pointer to AKM cipher */ while (Count > 0) { /*rtmp_hexdump(RT_DEBUG_TRACE,"MBSS WPA_IE AKM ",pTmp,4); */ if(RTMPEqualMemory(sta_akm,pTmp,4)) return TRUE; else { pTmp += 4; Count--; } } return FALSE;/* do not match the AKM */ }
INT rtmp_wdev_idx_find_by_p2p_ifaddr(RTMP_ADAPTER *pAd, UCHAR *ifAddr) { INT idx, type; ULONG flags; PNET_DEV if_dev = NULL; struct wifi_dev *wdev = NULL; if (!ifAddr) return -1; RTMP_INT_LOCK(&pAd->irq_lock, flags); for (idx = 0; idx < WDEV_NUM_MAX; idx++) { wdev = pAd->wdev_list[idx]; if (!wdev) continue; if_dev = wdev->if_dev; if (!if_dev) continue; if (!if_dev->ieee80211_ptr) continue; type = if_dev->ieee80211_ptr->iftype; if ( RTMPEqualMemory(wdev->if_addr, ifAddr, MAC_ADDR_LEN) && ( type == RT_CMD_80211_IFTYPE_P2P_CLIENT || type == RT_CMD_80211_IFTYPE_P2P_GO || type == RT_CMD_80211_IFTYPE_P2P_DEVICE )) { //MTWF_LOG(DBG_CAT_ALL, DBG_LVL_INFO, // ("find the wdev(type:%d, idx:%d) from wdev_list\n", // pAd->wdev_list[idx]->wdev_type, pAd->wdev_list[idx]->wdev_idx)); break; } } RTMP_INT_UNLOCK(&pAd->irq_lock, flags); return ((idx < WDEV_NUM_MAX) ? idx : -1); }
static PCFG80211_VIF_DEV RTMP_CFG80211_FindVifEntry_ByMac(void *pAdSrc, PNET_DEV pNewNetDev) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdSrc; PLIST_HEADER pCacheList = &pAd->cfg80211_ctrl.Cfg80211VifDevSet.vifDevList; PCFG80211_VIF_DEV pDevEntry = NULL; PLIST_ENTRY pListEntry = NULL; pListEntry = pCacheList->pHead; pDevEntry = (PCFG80211_VIF_DEV)pListEntry; while (pDevEntry != NULL) { if (RTMPEqualMemory(pDevEntry->net_dev->dev_addr, pNewNetDev->dev_addr, MAC_ADDR_LEN)) return pDevEntry; pListEntry = pListEntry->pNext; pDevEntry = (PCFG80211_VIF_DEV)pListEntry; } return NULL; }
static PCFG80211_VIF_DEV RTMP_CFG80211_FindVifEntry_ByMac(struct rtmp_adapter *pAd, struct net_device *pNewNetDev) { PLIST_HEADER pCacheList = &pAd->cfg80211_ctrl.Cfg80211VifDevSet.vifDevList; PCFG80211_VIF_DEV pDevEntry = NULL; PLIST_ENTRY pListEntry = NULL; pListEntry = pCacheList->pHead; pDevEntry = (PCFG80211_VIF_DEV)pListEntry; while (pDevEntry != NULL) { if (RTMPEqualMemory(pDevEntry->net_dev->dev_addr, pNewNetDev->dev_addr, MAC_ADDR_LEN)) return pDevEntry; pListEntry = pListEntry->pNext; pDevEntry = (PCFG80211_VIF_DEV)pListEntry; } return NULL; }
VOID P2pCrednTabDelete( IN PRTMP_ADAPTER pAd, IN UCHAR *pAddr) { PRT_P2P_TABLE Tab = &pAd->P2pTable; UCHAR i; /*UCHAR Zero[6] = {0,0,0,0,0,0}; */ DBGPRINT(RT_DEBUG_ERROR, (" P2P - P2pCrednTabDelete \n")); for (i = 0; i < MAX_P2P_TABLE_SIZE; i++) { if (RTMPEqualMemory(pAddr, Tab->TempCredential[i].InterAddr, MAC_ADDR_LEN)) { Tab->TempCredential[i].bValid = FALSE; RTMPZeroMemory(Tab->TempCredential[i].InterAddr, MAC_ADDR_LEN); RTMPZeroMemory(&Tab->TempCredential[i].Profile, sizeof(WSC_CREDENTIAL)); } } }
/* ========================================================================== Description: Check sanity of unicast cipher selector in RSN IE. Return: TRUE if match FALSE otherwise ========================================================================== */ BOOLEAN RTMPCheckUcast( IN PRTMP_ADAPTER pAd, IN PEID_STRUCT eid_ptr, IN MAC_TABLE_ENTRY *pEntry) { PUCHAR pStaTmp; USHORT Count; UCHAR apidx; ASSERT(pEntry); ASSERT(pEntry->apidx < pAd->ApCfg.BssidNum); apidx = pEntry->apidx; pEntry->WepStatus = pAd->ApCfg.MBSSID[apidx].WepStatus; if (eid_ptr->Len < 16) { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]RTMPCheckUcast : the length is too short(%d) \n", eid_ptr->Len)); return FALSE; } /* Store STA RSN_IE capability */ pStaTmp = (PUCHAR)&eid_ptr->Octet[0]; if(eid_ptr->Eid == IE_WPA2) { /* skip Version(2),Multicast cipter(4) 2+4==6 */ /* point to number of unicast */ pStaTmp +=6; } else if (eid_ptr->Eid == IE_WPA) { /* skip OUI(4),Vesrion(2),Multicast cipher(4) 4+2+4==10 */ /* point to number of unicast */ pStaTmp += 10; } else { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]RTMPCheckUcast : invalid IE=%d\n", eid_ptr->Eid)); return FALSE; } /* Store unicast cipher count */ NdisMoveMemory(&Count, pStaTmp, sizeof(USHORT)); Count = cpu2le16(Count); /* pointer to unicast cipher */ pStaTmp += sizeof(USHORT); if (eid_ptr->Len >= 16) { if (eid_ptr->Eid == IE_WPA) { if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled) {/* multiple cipher (TKIP/CCMP) */ while (Count > 0) { /* TKIP */ if (MIX_CIPHER_WPA_TKIP_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher)) { /* Compare if peer STA uses the TKIP as its unicast cipher */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4)) { pEntry->WepStatus = Ndis802_11Encryption2Enabled; return TRUE; } /* Our AP uses the AES as the secondary cipher */ /* Compare if the peer STA use AES as its unicast cipher */ if (MIX_CIPHER_WPA_AES_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher)) { if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][16], 4)) { pEntry->WepStatus = Ndis802_11Encryption3Enabled; return TRUE; } } } else { /* AES */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4)) { pEntry->WepStatus = Ndis802_11Encryption3Enabled; return TRUE; } } pStaTmp += 4; Count--; } } else {/* single cipher */ while (Count > 0) { if (RTMPEqualMemory(pStaTmp , &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4)) return TRUE; pStaTmp += 4; Count--; } } } else if (eid_ptr->Eid == IE_WPA2) { UCHAR IE_Idx = 0; /* When WPA1/WPA2 mix mode, the RSN_IE is stored in different structure */ if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) IE_Idx = 1; if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption4Enabled) {/* multiple cipher (TKIP/CCMP) */ while (Count > 0) { /* WPA2 TKIP */ if (MIX_CIPHER_WPA2_TKIP_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher)) { /* Compare if peer STA uses the TKIP as its unicast cipher */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4)) { pEntry->WepStatus = Ndis802_11Encryption2Enabled; return TRUE; } /* Our AP uses the AES as the secondary cipher */ /* Compare if the peer STA use AES as its unicast cipher */ if (MIX_CIPHER_WPA2_AES_ON(pAd->ApCfg.MBSSID[apidx].WpaMixPairCipher)) { if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][12], 4)) { pEntry->WepStatus = Ndis802_11Encryption3Enabled; return TRUE; } } } else { /* AES */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4)) { pEntry->WepStatus = Ndis802_11Encryption3Enabled; return TRUE; } } pStaTmp += 4; Count--; } } else {/* single cipher */ while (Count > 0) { if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4)) return TRUE; pStaTmp += 4; Count--; } } } } return FALSE; }
VOID RTUSBBulkOutDataPacket( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId, IN UCHAR Index) { PHT_TX_CONTEXT pHTTXContext; PURB pUrb; int ret = 0; PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL; PTXWI_STRUC pTxWI; ULONG TmpBulkEndPos, ThisBulkSize; unsigned long IrqFlags = 0, IrqFlags2 = 0; PUCHAR pWirelessPkt, pAppendant; BOOLEAN bTxQLastRound = FALSE; UCHAR allzero[4]= {0x0,0x0,0x0,0x0}; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) ) { pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; // Clear Data flag RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } // Clear Data flag RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; ThisBulkSize = 0; TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; if ((pHTTXContext->bCopySavePad == TRUE)) { if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8); pHTTXContext->bCopySavePad = FALSE; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition)); } do { pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos]; pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU)); // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) { if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { // Limit BulkOut size to about 4k bytes. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } // end Iverson else { if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) { // Limit BulkOut size to about 24k bytes. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } if (TmpBulkEndPos == pHTTXContext->CurWritePosition) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) if (pTxInfo->QSEL != FIFO_EDCA) { printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL); printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad); hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); } if (pTxInfo->USBDMATxPktLen <= 8) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos)); { DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } pAd->bForcePrintTX = TRUE; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen)); return; } // Increase Total transmit byte counter pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount; pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount; pLastTxInfo = pTxInfo; // Make sure we use EDCA QUEUE. pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) ThisBulkSize += (pTxInfo->USBDMATxPktLen+4); TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4); if (TmpBulkEndPos != pHTTXContext->CurWritePosition) pTxInfo->USBDMANextVLD = 1; if (pTxInfo->SwUseLastRound == 1) { if (pHTTXContext->CurWritePosition == 8) pTxInfo->USBDMANextVLD = 0; pTxInfo->SwUseLastRound = 0; bTxQLastRound = TRUE; pHTTXContext->ENextBulkOutPosition = 8; break; } }while (TRUE); // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. if (pLastTxInfo) { pLastTxInfo->USBDMANextVLD = 0; } /* We need to copy SavedPad when following condition matched! 1. Not the last round of the TxQueue and 2. any match of following cases: (1). The End Position of this bulk out is reach to the Currenct Write position and the TxInfo and related header already write to the CurWritePosition. =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition) (2). The EndPosition of the bulk out is not reach to the Current Write Position. =>(ENextBulkOutPosition != CurWritePosition) */ if ((bTxQLastRound == FALSE) && (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) || (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition)) ) { NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8); pHTTXContext->bCopySavePad = TRUE; if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { PUCHAR pBuf = &pHTTXContext->SavedPad[0]; DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize)); pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition]; DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7])); } //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); } if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); //DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound)); // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. pAppendant = &pWirelessPkt[TmpBulkEndPos]; NdisZeroMemory(pAppendant, 8); ThisBulkSize += 4; pHTTXContext->LastOne = TRUE; if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0) ThisBulkSize += 4; pHTTXContext->BulkOutSize = ThisBulkSize; pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1; BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); // Init Tx context descriptor RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete); pUrb = pHTTXContext->pUrb; if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret)); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext->IRPPending = TRUE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutReq++; }
static VOID APPeerAuthReqAtIdleAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { INT i; USHORT Seq, Alg, RspReason, Status; UCHAR Addr1[MAC_ADDR_LEN]; UCHAR Addr2[MAC_ADDR_LEN]; CHAR Chtxt[CIPHER_TEXT_LEN]; UINT32 apidx; PHEADER_802_11 pRcvHdr; HEADER_802_11 AuthHdr; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; MAC_TABLE_ENTRY *pEntry; UCHAR ChTxtIe = 16, ChTxtLen = CIPHER_TEXT_LEN; MULTISSID_STRUCT *pMbss; struct wifi_dev *wdev; CHAR rssi; if (! APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, &Alg, &Seq, &Status, Chtxt )) return; /* Find which MBSSID to be authenticate */ apidx = get_apidx_by_addr(pAd, Addr1); if (apidx >= pAd->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n")); return; } pMbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &pMbss->wdev; if ((wdev->if_dev == NULL) || ((wdev->if_dev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(wdev->if_dev)))) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); return; } pEntry = MacTableLookup(pAd, Addr2); if (pEntry && IS_ENTRY_CLIENT(pEntry)) { #ifdef DOT11W_PMF_SUPPORT if ((CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PMF_CAPABLE)) && (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)) goto SendAuth; #endif /* DOT11W_PMF_SUPPORT */ if (!RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, MAC_ADDR_LEN)) { MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); pEntry = NULL; DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n")); } else { if (pEntry->bIAmBadAtheros == TRUE) { AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n")); pEntry->bIAmBadAtheros = FALSE; } #ifdef DOT11_N_SUPPORT BASessionTearDownALL(pAd, pEntry->wcid); #endif /* DOT11_N_SUPPORT */ ASSERT(pEntry->Aid == Elem->Wcid); } } #ifdef DOT11W_PMF_SUPPORT SendAuth: #endif /* DOT11W_PMF_SUPPORT */ pRcvHdr = (PHEADER_802_11)(Elem->Msg); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from " "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", apidx, Seq, Alg, Status, Elem->Wcid, PRINT_MAC(Addr2))); /* YF@20130102: Refuse the weak signal of AuthReq */ rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, (CHAR)Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, (CHAR)Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, (CHAR)Elem->Rssi2, RSSI_2)); DBGPRINT(RT_DEBUG_TRACE, ("%s: AUTH_FAIL_REQ Threshold = %d, AUTH_NO_RSP_REQ Threshold = %d, AUTH RSSI = %d\n", wdev->if_dev->name, pMbss->AuthFailRssiThreshold, pMbss->AuthNoRspRssiThreshold, rssi)); if (((pMbss->AuthFailRssiThreshold != 0) && (rssi < pMbss->AuthFailRssiThreshold)) || ((pMbss->AuthNoRspRssiThreshold != 0) && (rssi < pMbss->AuthNoRspRssiThreshold))) { DBGPRINT(RT_DEBUG_TRACE, ("Reject this AUTH_REQ due to Weak Signal.\n")); if ((pMbss->AuthFailRssiThreshold != 0) && (rssi < pMbss->AuthFailRssiThreshold)) APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, Addr2, apidx, 0); return; } /* fail in ACL checking => send an AUTH-Fail seq#2. */ if (! ApCheckAccessControlList(pAd, Addr2, apidx)) { ASSERT(Seq == 1); ASSERT(pEntry == NULL); APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, Addr2, apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("Failed in ACL checking => send an AUTH seq#2 with " "Status code = %d\n", MLME_UNSPECIFY_FAIL)); return; } if ((Alg == AUTH_MODE_OPEN) && (pMbss->wdev.AuthMode != Ndis802_11AuthModeShared)) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, Addr2, wdev, apidx, OPMODE_AP, TRUE); if (pEntry) { #ifdef DOT11W_PMF_SUPPORT if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PMF_CAPABLE)) || (pEntry->PortSecured != WPA_802_1X_PORT_SECURED)) #endif /* DOT11W_PMF_SUPPORT */ { pEntry->AuthState = AS_AUTH_OPEN; pEntry->Sst = SST_AUTH; /* what if it already in SST_ASSOC ??????? */ } APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_SUCCESS); } else ; /* MAC table full, what should we respond ????? */ } else if ((Alg == AUTH_MODE_KEY) && ((wdev->AuthMode == Ndis802_11AuthModeShared) || (wdev->AuthMode == Ndis802_11AuthModeAutoSwitch))) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, Addr2, wdev, apidx, OPMODE_AP, TRUE); if (pEntry) { pEntry->AuthState = AS_AUTHENTICATING; pEntry->Sst = SST_NOT_AUTH; /* what if it already in SST_ASSOC ??????? */ /* log this STA in AuthRspAux machine, only one STA is stored. If two STAs using */ /* SHARED_KEY authentication mingled together, then the late comer will win. */ COPY_MAC_ADDR(&pAd->ApMlmeAux.Addr, Addr2); for(i=0; i<CIPHER_TEXT_LEN; i++) pAd->ApMlmeAux.Challenge[i] = RandomByte(pAd); RspReason = 0; Seq++; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if(NStatus != NDIS_STATUS_SUCCESS) return; /* if no memory, can't do anything */ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH seq#2 (Challenge)\n")); MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, wdev->if_addr, wdev->bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AuthHdr, 2, &Alg, 2, &Seq, 2, &RspReason, 1, &ChTxtIe, 1, &ChTxtLen, CIPHER_TEXT_LEN, pAd->ApMlmeAux.Challenge, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } else ; /* MAC table full, what should we respond ???? */ } else { /* wrong algorithm */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_ALG_NOT_SUPPORT); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Alg=%d, Seq=%d, AuthMode=%d\n", Alg, Seq, pAd->ApCfg.MBSSID[apidx].wdev.AuthMode)); } }
NDIS_STATUS MlmeHardTransmitTxRing( IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx, IN PNDIS_PACKET pPacket) { PACKET_INFO PacketInfo; PUCHAR pSrcBufVA; UINT SrcBufLen; PTXD_STRUC pTxD; #ifdef RT_BIG_ENDIAN PTXD_STRUC pDestTxD; TXD_STRUC TxD; #endif PHEADER_802_11 pHeader_802_11; BOOLEAN bAckRequired, bInsertTimestamp; ULONG SrcBufPA; /*UCHAR TxBufIdx;*/ UCHAR MlmeRate; ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; PTXWI_STRUC pFirstTxWI; /*ULONG i;*/ /*HTTRANSMIT_SETTING MlmeTransmit; Rate for this MGMT frame.*/ ULONG FreeNum; MAC_TABLE_ENTRY *pMacEntry = NULL; UINT8 TXWISize = pAd->chipCap.TXWISize; #ifdef CONFIG_AP_SUPPORT #ifdef SPECIFIC_TX_POWER_SUPPORT UCHAR TxPwrAdj = 0; #endif /* SPECIFIC_TX_POWER_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); if (pSrcBufVA == NULL) { /* The buffer shouldn't be NULL*/ return NDIS_STATUS_FAILURE; } /* Make sure MGMT ring resource won't be used by other threads*/ /*NdisAcquireSpinLock(&pAd->TxRingLock);*/ FreeNum = GET_TXRING_FREENO(pAd, QueIdx); if (FreeNum == 0) { /*NdisReleaseSpinLock(&pAd->TxRingLock);*/ return NDIS_STATUS_FAILURE; } SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; #ifdef RT_BIG_ENDIAN pDestTxD = (PTXD_STRUC)pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); #else pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; #endif if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) { DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n")); /*NdisReleaseSpinLock(&pAd->TxRingLock);*/ return NDIS_STATUS_FAILURE; } pFirstTxWI =(PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE); pHeader_802_11 = (PHEADER_802_11)(pSrcBufVA + TXINFO_SIZE + TXWISize); if (pHeader_802_11->Addr1[0] & 0x01) { MlmeRate = pAd->CommonCfg.BasicMlmeRate; } else { MlmeRate = pAd->CommonCfg.MlmeRate; } if ((pHeader_802_11->FC.Type == BTYPE_DATA) && (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) { pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); } /* Verify Mlme rate for a / g bands.*/ if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) /* 11A band*/ MlmeRate = RATE_6; /* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) Snice it's been set to 0 while on MgtMacHeaderInit By the way this will cause frame to be send on PWR_SAVE failed. */ /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame*/ bInsertTimestamp = FALSE; if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL*/ { bAckRequired = FALSE; } else /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame)*/ { if (pHeader_802_11->Addr1[0] & 0x01) /* MULTICAST, BROADCAST*/ { bAckRequired = FALSE; pHeader_802_11->Duration = 0; } else { bAckRequired = TRUE; pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) { bInsertTimestamp = TRUE; #ifdef CONFIG_AP_SUPPORT #ifdef SPECIFIC_TX_POWER_SUPPORT /* Find which MBSSID to be send this probeRsp */ UINT32 apidx; for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++) { if (RTMPEqualMemory(pHeader_802_11->Addr2, pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN)) break; } if (!(apidx >= pAd->ApCfg.BssidNum) && (pAd->ApCfg.MBSSID[apidx].TxPwrAdj != -1) && (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_CCK) && (pAd->CommonCfg.MlmeTransmit.field.MCS == RATE_1)) { TxPwrAdj = pAd->ApCfg.MBSSID[apidx].TxPwrAdj; } #endif /* SPECIFIC_TX_POWER_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ } } } pHeader_802_11->Sequence = pAd->Sequence++; if (pAd->Sequence > 0xfff) pAd->Sequence = 0; /* Before radar detection done, mgmt frame can not be sent but probe req*/ /* Because we need to use probe req to trigger driver to send probe req in passive scan*/ if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->Dot11_H.RDMode != RD_NORMAL_MODE)) { DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n")); /*NdisReleaseSpinLock(&pAd->TxRingLock);*/ return (NDIS_STATUS_FAILURE); } #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE); #endif /* Fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET should always has only one ohysical buffer, and the whole frame size equals to the first scatter buffer size */ /* Initialize TX Descriptor For inter-frame gap, the number is for this frame and next frame For MLME rate, we will fix as 2Mb to match other vendor's implement */ /* pAd->CommonCfg.MlmeTransmit.field.MODE = 1;*/ /* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.*/ /* Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.*/ if (pMacEntry == NULL) { RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWISize), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); #ifdef SPECIFIC_TX_POWER_SUPPORT if (IS_RT6352(pAd)) pFirstTxWI->TxPwrAdj = TxPwrAdj; #endif /* SPECIFIC_TX_POWER_SUPPORT */ } else { RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWISize), pMacEntry->MaxHTPhyMode.field.MCS, 0, (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS, IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); } pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket; pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL; /* pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE;*/ #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, (PUCHAR)pFirstTxWI, TYPE_TXWI); #endif SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, RTMP_PCI_DMA_TODEVICE); pTxD->LastSec0 = 1; pTxD->LastSec1 = 0; pTxD->SDLen1 = 0; pTxD->SDPtr0 = SrcBufPA; pTxD->SDLen0 = SrcBufLen; RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); #endif pAd->RalinkCounters.KickTxCount++; pAd->RalinkCounters.OneSecTxDoneCount++; /* flush dcache if no consistent memory is supported */ RTMP_DCACHE_FLUSH(SrcBufPA, SrcBufLen); RTMP_DCACHE_FLUSH(pAd->TxRing[QueIdx].Cell[SwIdx].AllocPa, RXD_SIZE); /* Increase TX_CTX_IDX, but write to register later.*/ INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE); RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx); /* Make sure to release MGMT ring resource*/ /* NdisReleaseSpinLock(&pAd->TxRingLock);*/ return NDIS_STATUS_SUCCESS; }
VOID RTMPInsertRepeaterEntry( IN PRTMP_ADAPTER pAd, IN UCHAR apidx, IN PUCHAR pAddr) { INT CliIdx, idx; UCHAR HashIdx; BOOLEAN Cancelled; UCHAR tempMAC[MAC_ADDR_LEN]; APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg; PREPEATER_CLIENT_ENTRY pReptCliEntry = NULL, pCurrEntry = NULL; PREPEATER_CLIENT_ENTRY_MAP pReptCliMap; UCHAR SPEC_ADDR[6][3] = {{0x02, 0x0F, 0xB5}, {0x02, 0x09, 0x5B}, {0x02, 0x14, 0x6C}, {0x02, 0x18, 0x4D}, {0x02, 0x1B, 0x2F}, {0x02, 0x1E, 0x2A}}; MAC_TABLE_ENTRY *pMacEntry = NULL; DBGPRINT(RT_DEBUG_TRACE, (" %s.\n", __FUNCTION__)); pMacEntry = MacTableLookup(pAd, pAddr); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)) { if (pMacEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED) { DBGPRINT(RT_DEBUG_ERROR, (" wireless client is not ready !!!\n")); return; } } NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); if (pAd->ApCfg.RepeaterCliSize >= MAX_EXT_MAC_ADDR_SIZE) { DBGPRINT(RT_DEBUG_ERROR, (" Repeater Client Full !!!\n")); NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return ; } for (CliIdx = 0; CliIdx < MAX_EXT_MAC_ADDR_SIZE; CliIdx++) { pReptCliEntry = &pAd->ApCfg.ApCliTab[apidx].RepeaterCli[CliIdx]; if ((pReptCliEntry->CliEnable) && (MAC_ADDR_EQUAL(pReptCliEntry->OriginalAddress, pAddr) || MAC_ADDR_EQUAL(pReptCliEntry->CurrentAddress, pAddr))) { DBGPRINT(RT_DEBUG_ERROR, ("\n receive mac :%02x:%02x:%02x:%02x:%02x:%02x !!!\n", pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5])); DBGPRINT(RT_DEBUG_ERROR, (" duplicate Insert !!!\n")); NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return ; } if (pReptCliEntry->CliEnable == FALSE) break; } if (CliIdx >= MAX_EXT_MAC_ADDR_SIZE) { DBGPRINT(RT_DEBUG_ERROR, (" Repeater Client Full !!!\n")); NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return ; } pReptCliEntry = &pAd->ApCfg.ApCliTab[apidx].RepeaterCli[CliIdx]; pReptCliMap = &pAd->ApCfg.ApCliTab[apidx].RepeaterCliMap[CliIdx]; /* ENTRY PREEMPTION: initialize the entry */ RTMPCancelTimer(&pReptCliEntry->ApCliAuthTimer, &Cancelled); RTMPCancelTimer(&pReptCliEntry->ApCliAssocTimer, &Cancelled); pReptCliEntry->CtrlCurrState = APCLI_CTRL_DISCONNECTED; pReptCliEntry->AuthCurrState = APCLI_AUTH_REQ_IDLE; pReptCliEntry->AssocCurrState = APCLI_ASSOC_IDLE; pReptCliEntry->CliConnectState = 0; pReptCliEntry->CliValid = FALSE; pReptCliEntry->bEthCli = FALSE; pReptCliEntry->MacTabWCID = 0xFF; pReptCliEntry->AuthReqCnt = 0; pReptCliEntry->AssocReqCnt = 0; pReptCliEntry->CliTriggerTime = 0; pReptCliEntry->pNext = NULL; pReptCliMap->pReptCliEntry = pReptCliEntry; pReptCliMap->pNext = NULL; COPY_MAC_ADDR(pReptCliEntry->OriginalAddress, pAddr); COPY_MAC_ADDR(tempMAC, pAddr); #ifdef SMART_MESH NdisZeroMemory(pAd->vMacAddrPrefix,sizeof(pAd->vMacAddrPrefix)); #endif /* SMART_MESH */ if (pAd->ApCfg.MACRepeaterOuiMode == 1) { DBGPRINT(RT_DEBUG_ERROR, (" todo !!!\n")); } else if (pAd->ApCfg.MACRepeaterOuiMode == 2) { INT IdxToUse; for (idx = 0; idx < 6; idx++) { if (RTMPEqualMemory(SPEC_ADDR[idx], pAddr, 3)) break; } /* If there is a matched one, use the next one; otherwise, use the first one. */ if (idx >= 0 && idx < 5) IdxToUse = idx + 1; else IdxToUse = 0; NdisCopyMemory(tempMAC, SPEC_ADDR[IdxToUse], 3); #ifdef SMART_MESH INT vMacIdx; if (IdxToUse >= 0 && IdxToUse < 5) vMacIdx = IdxToUse + 1; else vMacIdx = 0; NdisCopyMemory(pAd->vMacAddrPrefix, SPEC_ADDR[vMacIdx], sizeof(pAd->vMacAddrPrefix)); #endif /* SMART_MESH */ } else { NdisCopyMemory(tempMAC, pAd->ApCfg.ApCliTab[apidx].wdev.if_addr, 3); } COPY_MAC_ADDR(pReptCliEntry->CurrentAddress, tempMAC); pReptCliEntry->CliEnable = TRUE; pReptCliEntry->CliConnectState = 1; pReptCliEntry->pNext = NULL; NdisGetSystemUpTime(&pReptCliEntry->CliTriggerTime); RTMPInsertRepeaterAsicEntry(pAd, CliIdx, tempMAC); HashIdx = MAC_ADDR_HASH_INDEX(tempMAC); if (pAd->ApCfg.ReptCliHash[HashIdx] == NULL) { pAd->ApCfg.ReptCliHash[HashIdx] = pReptCliEntry; } else { pCurrEntry = pAd->ApCfg.ReptCliHash[HashIdx]; while (pCurrEntry->pNext != NULL) pCurrEntry = pCurrEntry->pNext; pCurrEntry->pNext = pReptCliEntry; } HashIdx = MAC_ADDR_HASH_INDEX(pReptCliEntry->OriginalAddress); if (pAd->ApCfg.ReptMapHash[HashIdx] == NULL) pAd->ApCfg.ReptMapHash[HashIdx] = pReptCliMap; else { PREPEATER_CLIENT_ENTRY_MAP pCurrMapEntry; pCurrMapEntry = pAd->ApCfg.ReptMapHash[HashIdx]; while (pCurrMapEntry->pNext != NULL) pCurrMapEntry = pCurrMapEntry->pNext; pCurrMapEntry->pNext = pReptCliMap; } pAd->ApCfg.RepeaterCliSize++; NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); NdisZeroMemory(&ApCliCtrlMsg, sizeof(APCLI_CTRL_MSG_STRUCT)); ApCliCtrlMsg.Status = MLME_SUCCESS; COPY_MAC_ADDR(&ApCliCtrlMsg.SrcAddr[0], tempMAC); ApCliCtrlMsg.BssIdx = apidx; ApCliCtrlMsg.CliIdx = CliIdx; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_MT2_AUTH_REQ, sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, apidx); }
static VOID APPeerAuthConfirmAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { AUTH_FRAME_INFO auth_info; PHEADER_802_11 pRcvHdr; MAC_TABLE_ENTRY *pEntry; UINT32 apidx; if (!APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, &auth_info)) return; apidx = get_apidx_by_addr(pAd, auth_info.addr1); if (apidx >= pAd->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n")); return; } if ((pAd->ApCfg.MBSSID[apidx].wdev.if_dev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].wdev.if_dev))) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); return; } /* End of if */ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) { DBGPRINT(RT_DEBUG_ERROR, ("AUTH - Invalid wcid (%d).\n", Elem->Wcid)); return; } pEntry = &pAd->MacTab.Content[Elem->Wcid]; if (pEntry && IS_ENTRY_CLIENT(pEntry)) { if (!RTMPEqualMemory(auth_info.addr1, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid, MAC_ADDR_LEN)) { MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); pEntry = NULL; DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n")); } else { if (pEntry->bIAmBadAtheros == TRUE) { AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n")); pEntry->bIAmBadAtheros = FALSE; } ASSERT(pEntry->Aid == Elem->Wcid); #ifdef DOT11_N_SUPPORT BASessionTearDownALL(pAd, pEntry->wcid); #endif /* DOT11_N_SUPPORT */ } } pRcvHdr = (PHEADER_802_11)(Elem->Msg); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from " "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", apidx, auth_info.auth_seq, auth_info.auth_alg, auth_info.auth_status, Elem->Wcid, PRINT_MAC(auth_info.addr2))); if (pEntry && MAC_ADDR_EQUAL(auth_info.addr2, pAd->ApMlmeAux.Addr)) { if ((pRcvHdr->FC.Wep == 1) && NdisEqualMemory(auth_info.Chtxt, pAd->ApMlmeAux.Challenge, CIPHER_TEXT_LEN)) { /* Successful */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_SUCCESS); pEntry->AuthState = AS_AUTH_KEY; pEntry->Sst = SST_AUTH; } else { /* send wireless event - Authentication rejected because of challenge failure */ RTMPSendWirelessEvent(pAd, IW_AUTH_REJECT_CHALLENGE_FAILURE, pEntry->Addr, 0, 0); /* fail - wep bit is not set or challenge text is not equal */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_REJ_CHALLENGE_FAILURE); MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); /*Chtxt[127]='\0'; */ /*pAd->ApMlmeAux.Challenge[127]='\0'; */ DBGPRINT(RT_DEBUG_TRACE, ("%s\n", ((pRcvHdr->FC.Wep == 1) ? "challenge text is not equal" : "wep bit is not set"))); /*DBGPRINT(RT_DEBUG_TRACE, ("Sent Challenge = %s\n",&pAd->ApMlmeAux.Challenge[100])); */ /*DBGPRINT(RT_DEBUG_TRACE, ("Rcv Challenge = %s\n",&Chtxt[100])); */ } } else { /* fail for unknown reason. most likely is AuthRspAux machine be overwritten by another */ /* STA also using SHARED_KEY authentication */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); } }
INT CFG80211_SendMgmtFrame(RTMP_ADAPTER *pAd, VOID *pData, ULONG Data) { struct ieee80211_mgmt *mgmt = NULL; #ifdef CONFIG_MULTI_CHANNEL if (pAd->MCC_InfraConnect_Protect == TRUE) { return; } if (pAd->Mlme.bStartMcc == TRUE) { // return; } #endif /* CONFIG_MULTI_CHANNEL */ if (pData != NULL) { PCFG80211_CTRL pCfg80211_ctrl = &pAd->cfg80211_ctrl; pCfg80211_ctrl->TxStatusInUsed = TRUE; pCfg80211_ctrl->TxStatusSeq = pAd->Sequence; RTMP_OS_INIT_COMPLETION(&pCfg80211_ctrl->fw_event_done); if (pCfg80211_ctrl->pTxStatusBuf != NULL) { os_free_mem(NULL, pCfg80211_ctrl->pTxStatusBuf); pCfg80211_ctrl->pTxStatusBuf = NULL; } os_alloc_mem(NULL, (UCHAR **)&pCfg80211_ctrl->pTxStatusBuf, Data); if (pCfg80211_ctrl->pTxStatusBuf != NULL) { NdisCopyMemory(pCfg80211_ctrl->pTxStatusBuf, pData, Data); pCfg80211_ctrl->TxStatusBufLen = Data; } else { pCfg80211_ctrl->TxStatusBufLen = 0; DBGPRINT(RT_DEBUG_ERROR, ("CFG_TX_STATUS: MEM ALLOC ERROR\n")); return NDIS_STATUS_FAILURE; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0) CFG80211_IsNeedTxStatus(pAd, pData, Data); #else pAd->cfg80211_ctrl.IsNeedTxStatus = CFG80211_IsNeedTxStatus(pAd, pData, Data); #endif if(TRUE == pAd->cfg80211_ctrl.IsNeedTxStatus) { int ret = 0; // send fw cmd to FW ret = CFG80211_TxStatusCmd(pAd, TXS_TIMEOUT, (UCHAR)pCfg80211_ctrl->TxStatusSeq, TXS_P2P_WCID, TXS_P2P_MgmtID, Data); DBGPRINT(RT_DEBUG_INFO, ("%s, send tx status cmd status(%d)\n", __FUNCTION__, ret)); } //Parser probe rsp to remove WPS IE #ifdef CONFIG_P2P_AUTO_GO_AS_SOFTAP if (pAd->p2pForceGOAsSoftAP) { PP2P_PUBLIC_FRAME pFrame = (PP2P_PUBLIC_FRAME)pData; mgmt = (struct ieee80211_mgmt *)pData; UINT Elemlen, Offset; PMULTISSID_STRUCT pMbss = &pAd->ApCfg.MBSSID[MAIN_MBSSID]; struct wifi_dev *pWdev = &pMbss->wdev; DBGPRINT(RT_DEBUG_TRACE, ("SubType: pFrame->p80211Header.FC.SubType: %d\n", pFrame->p80211Header.FC.SubType)); if (pFrame->p80211Header.FC.SubType == SUBTYPE_PROBE_RSP) { Offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); Elemlen = Data - Offset; if (mgmt && Elemlen > 0) { //DBGPRINT(RT_DEBUG_ERROR, ("IELen %d, lk added\n", Elemlen)); //hex_dump("probe_resp: variable:", (UCHAR *)mgmt->u.probe_resp.variable, Elemlen); #if 1 if (mgmt->u.probe_resp.variable) { //DBGPRINT(RT_DEBUG_TRACE,("Remove P2P IE done, lk added\n")); PUCHAR pVendorIE = NULL, pPreVendorIE = NULL, pIEData = NULL; UINT VendorIELen; pIEData = (PUCHAR)mgmt->u.probe_resp.variable; pVendorIE = pIEData; if ((pWdev->AuthMode == Ndis802_11AuthModeWPA2PSK) || (pWdev->AuthMode == Ndis802_11AuthModeOpen)) { while (pVendorIE < pIEData + Elemlen) { //Remove WPS IE extern UCHAR WPS_OUI[]; if (RTMPEqualMemory(pVendorIE + 2/*EID + Length*/, WPS_OUI, 4)) { VendorIELen = *(pVendorIE + 1); //hex_dump("pDest WPS IE 2:", pVendorIE, VendorIELen); RTMPZeroMemory(pVendorIE + 2, VendorIELen); pPreVendorIE = pVendorIE; pVendorIE += VendorIELen + 2; //Next Vendor IE address pointer if (pVendorIE < pIEData + Elemlen) { RTMPMoveMemory(pPreVendorIE, pVendorIE, pIEData + Elemlen - pVendorIE); } //Reset probe resp length Elemlen -= (VendorIELen + 2); pVendorIE = pPreVendorIE; break; } else { pVendorIE += *(pVendorIE + 1) + 2; } } } while (pVendorIE < pIEData + Elemlen) { if (RTMPEqualMemory(pVendorIE + 2/*EID + Length*/, P2POUIBYTE, 4)) //Remove P2P IE { VendorIELen = *(pVendorIE + 1); //hex_dump("pDest p2p IE 2:", pVendorIE, VendorIELen); RTMPZeroMemory(pVendorIE + 2, VendorIELen); pPreVendorIE = pVendorIE; pVendorIE += VendorIELen + 2; //Next Vendor IE address pointer if (pVendorIE < pIEData + Elemlen) { RTMPMoveMemory(pPreVendorIE, pVendorIE, pIEData + Elemlen - pVendorIE); } //Reset probe resp length Elemlen -= (VendorIELen + 2); pVendorIE = pPreVendorIE; break; } else { pVendorIE += *(pVendorIE + 1) + 2; } } Data = Elemlen + Offset; DBGPRINT(RT_DEBUG_TRACE,("Remove P2P IE RTMPZeroMemory done, lk added\n")); } #endif } }
VOID CFG80211_ParseBeaconIE(RTMP_ADAPTER *pAd, BSS_STRUCT *pMbss, struct wifi_dev *wdev, const UCHAR *wpa_ie, const UCHAR *rsn_ie) { PEID_STRUCT pEid; PUCHAR pTmp; NDIS_802_11_ENCRYPTION_STATUS TmpCipher; NDIS_802_11_ENCRYPTION_STATUS PairCipher; /* Unicast cipher 1, this one has more secured cipher suite */ NDIS_802_11_ENCRYPTION_STATUS PairCipherAux; /* Unicast cipher 2 if AP announce two unicast cipher suite */ //NDIS_802_11_ENCRYPTION_STATUS GroupCipher; /* Group cipher */ PAKM_SUITE_STRUCT pAKM; USHORT Count; BOOLEAN bWPA = FALSE; BOOLEAN bWPA2 = FALSE; BOOLEAN bMix = FALSE; /* Security */ PairCipher = Ndis802_11WEPDisabled; PairCipherAux = Ndis802_11WEPDisabled; if ((wpa_ie == NULL) && (rsn_ie == NULL)) //open case { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s:: Open/None case\n", __FUNCTION__)); wdev->AuthMode = Ndis802_11AuthModeOpen; wdev->WepStatus = Ndis802_11WEPDisabled; wdev->WpaMixPairCipher = MIX_CIPHER_NOTUSE; } if ((wpa_ie != NULL)) //wpapsk/tkipaes case { pEid = (PEID_STRUCT)wpa_ie; pTmp = (PUCHAR)pEid; if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) { wdev->AuthMode = Ndis802_11AuthModeOpen; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s:: WPA case\n", __FUNCTION__)); bWPA = TRUE; pTmp += 11; switch (*pTmp) { case 1: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Group Ndis802_11GroupWEP40Enabled\n")); wdev->GroupKeyWepStatus = Ndis802_11GroupWEP40Enabled; break; case 5: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Group Ndis802_11GroupWEP104Enabled\n")); wdev->GroupKeyWepStatus = Ndis802_11GroupWEP104Enabled; break; case 2: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Group Ndis802_11TKIPEnable\n")); wdev->GroupKeyWepStatus = Ndis802_11TKIPEnable; break; case 4: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,(" Group Ndis802_11AESEnable\n")); wdev->GroupKeyWepStatus = Ndis802_11AESEnable; break; default: break; } /* number of unicast suite*/ pTmp += 1; /* skip all unicast cipher suites*/ /*Count = *(PUSHORT) pTmp; */ Count = (pTmp[1]<<8) + pTmp[0]; pTmp += sizeof(USHORT); /* Parsing all unicast cipher suite*/ while (Count > 0) { /* Skip OUI*/ pTmp += 3; TmpCipher = Ndis802_11WEPDisabled; switch (*pTmp) { case 1: case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway*/ TmpCipher = Ndis802_11WEPEnabled; break; case 2: TmpCipher = Ndis802_11TKIPEnable; break; case 4: TmpCipher = Ndis802_11AESEnable; break; default: break; } if (TmpCipher > PairCipher) { /* Move the lower cipher suite to PairCipherAux*/ PairCipherAux = PairCipher; PairCipher = TmpCipher; } else { PairCipherAux = TmpCipher; } pTmp++; Count--; } switch (*pTmp) { case 1: /* Set AP support WPA-enterprise mode*/ wdev->AuthMode = Ndis802_11AuthModeWPA; break; case 2: /* Set AP support WPA-PSK mode*/ wdev->AuthMode = Ndis802_11AuthModeWPAPSK; break; default: break; } pTmp += 1; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("AuthMode = %s\n",GetAuthMode(wdev->AuthMode))); if (wdev->GroupKeyWepStatus == PairCipher) { wdev->WpaMixPairCipher = MIX_CIPHER_NOTUSE; pMbss->wdev.WepStatus=wdev->GroupKeyWepStatus; } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("WPA Mix TKIPAES\n")); bMix = TRUE; } pMbss->RSNIE_Len[0] = wpa_ie[1]; NdisMoveMemory(pMbss->RSN_IE[0], wpa_ie+2, wpa_ie[1]);//copy rsn ie } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s:: WPA Open/None case\n", __FUNCTION__)); wdev->AuthMode = Ndis802_11AuthModeOpen; } } if ((rsn_ie != NULL)) { PRSN_IE_HEADER_STRUCT pRsnHeader; PCIPHER_SUITE_STRUCT pCipher; pEid = (PEID_STRUCT)rsn_ie; pTmp = (PUCHAR)pEid; pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp; /* 0. Version must be 1*/ if (le2cpu16(pRsnHeader->Version) == 1) { pTmp += sizeof(RSN_IE_HEADER_STRUCT); /* 1. Check group cipher*/ pCipher = (PCIPHER_SUITE_STRUCT) pTmp; if (NdisEqualMemory(pTmp, RSN_OUI, 3)) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s:: WPA2 case\n", __FUNCTION__)); bWPA2 = TRUE; wdev->AuthMode = Ndis802_11AuthModeOpen; switch (pCipher->Type) { case 1: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Ndis802_11GroupWEP40Enabled\n")); wdev->GroupKeyWepStatus = Ndis802_11GroupWEP40Enabled; break; case 5: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Ndis802_11GroupWEP104Enabled\n")); wdev->GroupKeyWepStatus = Ndis802_11GroupWEP104Enabled; break; case 2: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Ndis802_11TKIPEnable\n")); wdev->GroupKeyWepStatus = Ndis802_11TKIPEnable; break; case 4: MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("Ndis802_11AESEnable\n")); wdev->GroupKeyWepStatus = Ndis802_11AESEnable; break; default: break; } /* set to correct offset for next parsing*/ pTmp += sizeof(CIPHER_SUITE_STRUCT); /* 2. Get pairwise cipher counts*/ /*Count = *(PUSHORT) pTmp;*/ Count = (pTmp[1]<<8) + pTmp[0]; pTmp += sizeof(USHORT); /* 3. Get pairwise cipher*/ /* Parsing all unicast cipher suite*/ while (Count > 0) { /* Skip OUI*/ pCipher = (PCIPHER_SUITE_STRUCT) pTmp; TmpCipher = Ndis802_11WEPDisabled; switch (pCipher->Type) { case 1: case 5: /* Although WEP is not allowed in WPA related auth mode, we parse it anyway*/ TmpCipher = Ndis802_11WEPEnabled; break; case 2: TmpCipher = Ndis802_11TKIPEnable; break; case 4: TmpCipher = Ndis802_11AESEnable; break; default: break; } //pMbss->wdev.WepStatus = TmpCipher; if (TmpCipher > PairCipher) { /* Move the lower cipher suite to PairCipherAux*/ PairCipherAux = PairCipher; PairCipher = TmpCipher; } else { PairCipherAux = TmpCipher; } pTmp += sizeof(CIPHER_SUITE_STRUCT); Count--; } /* 4. get AKM suite counts*/ /*Count = *(PUSHORT) pTmp;*/ Count = (pTmp[1]<<8) + pTmp[0]; pTmp += sizeof(USHORT); /* 5. Get AKM ciphers*/ /* Parsing all AKM ciphers*/ while (Count > 0) { pAKM = (PAKM_SUITE_STRUCT) pTmp; if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) break; switch (pAKM->Type) { case 0: wdev->AuthMode = Ndis802_11AuthModeWPANone; break; case 1: /* Set AP support WPA-enterprise mode*/ wdev->AuthMode = Ndis802_11AuthModeWPA2; break; case 2: /* Set AP support WPA-PSK mode*/ wdev->AuthMode = Ndis802_11AuthModeWPA2PSK; break; default: wdev->AuthMode = Ndis802_11AuthModeMax; break; } pTmp += sizeof(AKM_SUITE_STRUCT); Count--; } MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("AuthMode = %s\n",GetAuthMode(wdev->AuthMode))); if (wdev->GroupKeyWepStatus == PairCipher) { wdev->WpaMixPairCipher = MIX_CIPHER_NOTUSE; pMbss->wdev.WepStatus=wdev->GroupKeyWepStatus; } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("WPA2 Mix TKIPAES\n")); bMix= TRUE; } if (bWPA2 && bWPA) { pMbss->RSNIE_Len[1] = rsn_ie[1]; NdisMoveMemory(pMbss->RSN_IE[1], rsn_ie+2, rsn_ie[1]);//copy rsn ie } else { pMbss->RSNIE_Len[0] = rsn_ie[1]; NdisMoveMemory(pMbss->RSN_IE[0], rsn_ie+2, rsn_ie[1]);//copy rsn ie } } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("%s::RSN Open/None case\n", __FUNCTION__)); wdev->AuthMode = Ndis802_11AuthModeOpen; } } } if (bWPA2 && bWPA) { wdev->AuthMode = Ndis802_11AuthModeWPA1PSKWPA2PSK; if (bMix) { wdev->WpaMixPairCipher = WPA_TKIPAES_WPA2_TKIPAES; wdev->WepStatus = Ndis802_11TKIPAESMix; } } else if (bWPA2) { if (bMix) { wdev->WpaMixPairCipher = WPA_NONE_WPA2_TKIPAES; wdev->WepStatus = Ndis802_11TKIPAESMix; } } else if (bWPA) { if (bMix) { wdev->WpaMixPairCipher = WPA_TKIPAES_WPA2_NONE; wdev->WepStatus = Ndis802_11TKIPAESMix; } } MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE,("\n bwpa2 %d, bwpa %d, bmix %d,AuthMode = %s ,wdev->WpaMixPairCipher = %d\ wdev->WepStatus = %d wdev->GroupKeyWepStatus %d pMbss->wdev.WepStatus = %d\n" ,bWPA2,bWPA,bMix,GetAuthMode(wdev->AuthMode),wdev->WpaMixPairCipher,wdev->WepStatus,wdev->GroupKeyWepStatus,pMbss->wdev.WepStatus)); }
/*! \brief To substitute the message type if the message is coming from external * \param *Fr The frame received * \param *Machine The state machine * \param *MsgType the message type for the state machine * \return TRUE if the substitution is successful, FALSE otherwise * \pre * \post */ BOOLEAN APMsgTypeSubst( IN PRTMP_ADAPTER pAd, IN PFRAME_802_11 pFrame, OUT INT *Machine, OUT INT *MsgType) { USHORT Seq; UCHAR EAPType; BOOLEAN Return = FALSE; #ifdef WSC_AP_SUPPORT UCHAR EAPCode; PMAC_TABLE_ENTRY pEntry; #endif /* WSC_AP_SUPPORT */ /* TODO: only PROBE_REQ can be broadcast, all others must be unicast-to-me && is_mybssid; otherwise, ignore this frame */ /* wpa EAPOL PACKET */ if (pFrame->Hdr.FC.Type == BTYPE_DATA) { #ifdef WSC_AP_SUPPORT /*WSC EAPOL PACKET */ pEntry = MacTableLookup(pAd, pFrame->Hdr.Addr2); if (pEntry && ((pEntry->bWscCapable) || (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode < Ndis802_11AuthModeWPA))) { if ((MAC_ADDR_EQUAL(pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, pEntry->Addr) || MAC_ADDR_EQUAL(pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, ZERO_MAC_ADDR)) && IS_ENTRY_CLIENT(pEntry) && (pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscConfMode != WSC_DISABLE)) { *Machine = WSC_STATE_MACHINE; EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1); EAPCode = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 4); Return = WscMsgTypeSubst(EAPType, EAPCode, MsgType); } } #endif /* WSC_AP_SUPPORT */ if (!Return) { *Machine = WPA_STATE_MACHINE; EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1); Return = WpaMsgTypeSubst(EAPType, (INT *) MsgType); } return Return; } if (pFrame->Hdr.FC.Type != BTYPE_MGMT) return FALSE; switch (pFrame->Hdr.FC.SubType) { case SUBTYPE_ASSOC_REQ: *Machine = AP_ASSOC_STATE_MACHINE; *MsgType = APMT2_PEER_ASSOC_REQ; break; /* case SUBTYPE_ASSOC_RSP: *Machine = AP_ASSOC_STATE_MACHINE; *MsgType = APMT2_PEER_ASSOC_RSP; break; */ case SUBTYPE_REASSOC_REQ: *Machine = AP_ASSOC_STATE_MACHINE; *MsgType = APMT2_PEER_REASSOC_REQ; break; /* case SUBTYPE_REASSOC_RSP: *Machine = AP_ASSOC_STATE_MACHINE; *MsgType = APMT2_PEER_REASSOC_RSP; break; */ case SUBTYPE_PROBE_REQ: *Machine = AP_SYNC_STATE_MACHINE; *MsgType = APMT2_PEER_PROBE_REQ; break; /* test for 40Mhz intolerant */ /* For Active Scan */ case SUBTYPE_PROBE_RSP: *Machine = AP_SYNC_STATE_MACHINE; *MsgType = APMT2_PEER_PROBE_RSP; break; case SUBTYPE_BEACON: *Machine = AP_SYNC_STATE_MACHINE; *MsgType = APMT2_PEER_BEACON; break; /* case SUBTYPE_ATIM: *Machine = AP_SYNC_STATE_MACHINE; *MsgType = APMT2_PEER_ATIM; break; */ case SUBTYPE_DISASSOC: *Machine = AP_ASSOC_STATE_MACHINE; *MsgType = APMT2_PEER_DISASSOC_REQ; break; case SUBTYPE_AUTH: /* get the sequence number from payload 24 Mac Header + 2 bytes algorithm */ NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT)); *Machine = AP_AUTH_STATE_MACHINE; if (Seq == 1) *MsgType = APMT2_PEER_AUTH_REQ; else if (Seq == 3) *MsgType = APMT2_PEER_AUTH_CONFIRM; else { DBGPRINT(RT_DEBUG_TRACE,("wrong AUTH seq=%d Octet=%02x %02x %02x %02x %02x %02x %02x %02x\n", Seq, pFrame->Octet[0], pFrame->Octet[1], pFrame->Octet[2], pFrame->Octet[3], pFrame->Octet[4], pFrame->Octet[5], pFrame->Octet[6], pFrame->Octet[7])); return FALSE; } break; case SUBTYPE_DEAUTH: *Machine = AP_AUTH_STATE_MACHINE; /*AP_AUTH_RSP_STATE_MACHINE;*/ *MsgType = APMT2_PEER_DEAUTH; break; case SUBTYPE_ACTION: case SUBTYPE_ACTION_NO_ACK: *Machine = ACTION_STATE_MACHINE; /* Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support */ #ifdef P2P_SUPPORT /* Vendor specific usage. */ if ((pFrame->Octet[0] & 0x7F) == MT2_ACT_VENDOR) /* Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support */ { UCHAR P2POUIBYTE[4] = {0x50, 0x6f, 0x9a, 0x9}; DBGPRINT(RT_DEBUG_ERROR, ("Vendor Action frame OUI= 0x%x\n", *(PULONG)&pFrame->Octet[1])); /* Now support WFA P2P */ if (RTMPEqualMemory(&pFrame->Octet[1], P2POUIBYTE, 4) && (P2P_INF_ON(pAd))) { DBGPRINT(RT_DEBUG_TRACE, ("Vendor Action frame P2P OUI= 0x%x\n", *(PULONG)&pFrame->Octet[1])); *Machine = P2P_ACTION_STATE_MACHINE; if (pFrame->Octet[5] <= MT2_MAX_PEER_SUPPORT) { *MsgType = pFrame->Octet[5]; /* subtype. */ } else return FALSE; } else { return FALSE; } } else #endif /* P2P_SUPPORT */ if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG) { *MsgType = MT2_ACT_INVALID; } else { *MsgType = (pFrame->Octet[0]&0x7F); } break; default: return FALSE; break; } return TRUE; }
BOOLEAN CFG80211_CheckActionFrameType( IN RTMP_ADAPTER *pAd, IN PUCHAR preStr, IN PUCHAR pData, IN UINT32 length) { BOOLEAN isP2pFrame = FALSE; struct ieee80211_mgmt *mgmt; mgmt = (struct ieee80211_mgmt *)pData; if (ieee80211_is_mgmt(mgmt->frame_control)) { if (ieee80211_is_probe_resp(mgmt->frame_control)) { DBGPRINT(RT_DEBUG_INFO, ("CFG80211_PKT: %s ProbeRsp Frame %d\n", preStr, pAd->LatchRfRegs.Channel)); if (!mgmt->u.probe_resp.timestamp) { struct timeval tv; do_gettimeofday(&tv); mgmt->u.probe_resp.timestamp = ((UINT64) tv.tv_sec * 1000000) + tv.tv_usec; } } else if (ieee80211_is_disassoc(mgmt->frame_control)) { DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s DISASSOC Frame\n", preStr)); } else if (ieee80211_is_deauth(mgmt->frame_control)) { DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s Deauth Frame\n", preStr, pAd->LatchRfRegs.Channel)); } else if (ieee80211_is_action(mgmt->frame_control)) { PP2P_PUBLIC_FRAME pFrame = (PP2P_PUBLIC_FRAME)pData; if ((pFrame->p80211Header.FC.SubType == SUBTYPE_ACTION) && (pFrame->Category == CATEGORY_PUBLIC) && (pFrame->Action == ACTION_WIFI_DIRECT)) { isP2pFrame = TRUE; switch (pFrame->Subtype) { case GO_NEGOCIATION_REQ: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s GO_NEGOCIACTION_REQ %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case GO_NEGOCIATION_RSP: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s GO_NEGOCIACTION_RSP %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case GO_NEGOCIATION_CONFIRM: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s GO_NEGOCIACTION_CONFIRM %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case P2P_PROVISION_REQ: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2P_PROVISION_REQ %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case P2P_PROVISION_RSP: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2P_PROVISION_RSP %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case P2P_INVITE_REQ: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2P_INVITE_REQ %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case P2P_INVITE_RSP: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2P_INVITE_RSP %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case P2P_DEV_DIS_REQ: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2P_DEV_DIS_REQ %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case P2P_DEV_DIS_RSP: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2P_DEV_DIS_RSP %d\n", preStr, pAd->LatchRfRegs.Channel)); break; } } else if ((pFrame->p80211Header.FC.SubType == SUBTYPE_ACTION) && (pFrame->Category == CATEGORY_PUBLIC) && ((pFrame->Action == ACTION_GAS_INITIAL_REQ) || (pFrame->Action == ACTION_GAS_INITIAL_RSP) || (pFrame->Action == ACTION_GAS_COMEBACK_REQ ) || (pFrame->Action == ACTION_GAS_COMEBACK_RSP))) { isP2pFrame = TRUE; } else if ((pFrame->Category == CATEGORY_VENDOR_SPECIFIC_WFD) && RTMPEqualMemory(&pFrame->Octet[1], CFG_P2POUIBYTE, 4)) { isP2pFrame = TRUE; switch (pFrame->Subtype) { case P2PACT_NOA: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2PACT_NOA %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case P2PACT_PERSENCE_REQ: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2PACT_PERSENCE_REQ %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case P2PACT_PERSENCE_RSP: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2PACT_PERSENCE_RSP %d\n", preStr, pAd->LatchRfRegs.Channel)); break; case P2PACT_GO_DISCOVER_REQ: DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s P2PACT_GO_DISCOVER_REQ %d\n", preStr, pAd->LatchRfRegs.Channel)); break; } } else { DBGPRINT(RT_DEBUG_INFO, ("CFG80211_PKT: %s ACTION Frame with Channel%d\n", preStr, pAd->LatchRfRegs.Channel)); } } else { DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s UNKOWN MGMT FRAME TYPE\n", preStr)); } } else { DBGPRINT(RT_DEBUG_ERROR, ("CFG80211_PKT: %s UNKOWN FRAME TYPE\n", preStr)); } return isP2pFrame; }
/* ======================================================================== Routine Description: Sending EAP Req. frame to station in authenticating state. These frames come from Authenticator deamon. Arguments: pAdapter Pointer to our adapter pPacket Pointer to outgoing EAP frame body + 8023 Header Len length of pPacket Return Value: None ======================================================================== */ VOID WpaSend(struct rtmp_adapter *pAdapter, u8 *pPacket, ULONG Len) { PEAP_HDR pEapHdr; u8 Addr[MAC_ADDR_LEN]; u8 Header802_3[LENGTH_802_3]; MAC_TABLE_ENTRY *pEntry; u8 *pData; memmove(Addr, pPacket, 6); memmove(Header802_3, pPacket, LENGTH_802_3); pEapHdr = (EAP_HDR*)(pPacket + LENGTH_802_3); pData = (pPacket + LENGTH_802_3); if ((pEntry = MacTableLookup(pAdapter, Addr)) == NULL) { return; } /* Send EAP frame to STA */ if (((pEntry->AuthMode >= Ndis802_11AuthModeWPA) && (pEapHdr->ProType != EAPOLKey)) || (pAdapter->ApCfg.MBSSID[pEntry->apidx].wdev.IEEE8021X == true)) RTMPToWirelessSta(pAdapter, pEntry, Header802_3, LENGTH_802_3, pData, Len - LENGTH_802_3, (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? false : true); if (RTMPEqualMemory((pPacket+12), EAPOL, 2)) { switch (pEapHdr->code) { case EAP_CODE_REQUEST: if ((pEntry->WpaState >= AS_PTKINITDONE) && (pEapHdr->ProType == EAPPacket)) { pEntry->WpaState = AS_AUTHENTICATION; DBGPRINT(RT_DEBUG_TRACE, ("Start to re-authentication by 802.1x daemon\n")); } break; /* After receiving EAP_SUCCESS, trigger state machine */ case EAP_CODE_SUCCESS: if ((pEntry->AuthMode >= Ndis802_11AuthModeWPA) && (pEapHdr->ProType != EAPOLKey)) { DBGPRINT(RT_DEBUG_TRACE,("Send EAP_CODE_SUCCESS\n\n")); if (pEntry->Sst == SST_ASSOC) { pEntry->WpaState = AS_INITPMK; /* Only set the expire and counters */ pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; WPAStart4WayHS(pAdapter, pEntry, PEER_MSG1_RETRY_EXEC_INTV); } } else { pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; pEntry->WpaState = AS_PTKINITDONE; pAdapter->ApCfg.MBSSID[pEntry->apidx].wdev.PortSecured = WPA_802_1X_PORT_SECURED; pEntry->PortSecured = WPA_802_1X_PORT_SECURED; DBGPRINT(RT_DEBUG_TRACE,("IEEE8021X-WEP : Send EAP_CODE_SUCCESS\n\n")); } break; case EAP_CODE_FAILURE: break; default: break; } } else { DBGPRINT(RT_DEBUG_TRACE, ("Send Deauth, Reason : REASON_NO_LONGER_VALID\n")); MlmeDeAuthAction(pAdapter, pEntry, REASON_NO_LONGER_VALID, false); } }
/* ========================================================================== Description: Check sanity of unicast cipher selector in RSN IE. Return: true if match false otherwise ========================================================================== */ bool RTMPCheckUcast( IN struct rtmp_adapter * pAd, IN PEID_STRUCT eid_ptr, IN MAC_TABLE_ENTRY *pEntry) { u8 * pStaTmp; unsigned short Count; u8 apidx; struct rtmp_wifi_dev *wdev; ASSERT(pEntry); ASSERT(pEntry->apidx < pAd->ApCfg.BssidNum); apidx = pEntry->apidx; wdev = &pAd->ApCfg.MBSSID[apidx].wdev; pEntry->WepStatus = wdev->WepStatus; if (eid_ptr->Len < 16) { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]RTMPCheckUcast : the length is too short(%d) \n", eid_ptr->Len)); return false; } /* Store STA RSN_IE capability */ pStaTmp = (u8 *)&eid_ptr->Octet[0]; if(eid_ptr->Eid == IE_WPA2) { /* skip Version(2),Multicast cipter(4) 2+4==6 */ /* point to number of unicast */ pStaTmp +=6; } else if (eid_ptr->Eid == IE_WPA) { /* skip OUI(4),Vesrion(2),Multicast cipher(4) 4+2+4==10 */ /* point to number of unicast */ pStaTmp += 10; } else { DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]RTMPCheckUcast : invalid IE=%d\n", eid_ptr->Eid)); return false; } /* Store unicast cipher count */ memmove(&Count, pStaTmp, sizeof(unsigned short)); Count = cpu2le16(Count); /* pointer to unicast cipher */ pStaTmp += sizeof(unsigned short); if (eid_ptr->Len >= 16) { if (eid_ptr->Eid == IE_WPA) { if (wdev->WepStatus == Ndis802_11TKIPAESMix) {/* multiple cipher (TKIP/CCMP) */ while (Count > 0) { /* TKIP */ if (MIX_CIPHER_WPA_TKIP_ON(wdev->WpaMixPairCipher)) { /* Compare if peer STA uses the TKIP as its unicast cipher */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4)) { pEntry->WepStatus = Ndis802_11TKIPEnable; return true; } /* Our AP uses the AES as the secondary cipher */ /* Compare if the peer STA use AES as its unicast cipher */ if (MIX_CIPHER_WPA_AES_ON(wdev->WpaMixPairCipher)) { if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][16], 4)) { pEntry->WepStatus = Ndis802_11AESEnable; return true; } } } else { /* AES */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4)) { pEntry->WepStatus = Ndis802_11AESEnable; return true; } } pStaTmp += 4; Count--; } } else {/* single cipher */ while (Count > 0) { if (RTMPEqualMemory(pStaTmp , &pAd->ApCfg.MBSSID[apidx].RSN_IE[0][12], 4)) return true; pStaTmp += 4; Count--; } } } else if (eid_ptr->Eid == IE_WPA2) { u8 IE_Idx = 0; /* When WPA1/WPA2 mix mode, the RSN_IE is stored in different structure */ if ((wdev->AuthMode == Ndis802_11AuthModeWPA1WPA2) || (wdev->AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) IE_Idx = 1; if (wdev->WepStatus == Ndis802_11TKIPAESMix) {/* multiple cipher (TKIP/CCMP) */ while (Count > 0) { /* WPA2 TKIP */ if (MIX_CIPHER_WPA2_TKIP_ON(wdev->WpaMixPairCipher)) { /* Compare if peer STA uses the TKIP as its unicast cipher */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4)) { pEntry->WepStatus = Ndis802_11TKIPEnable; return true; } /* Our AP uses the AES as the secondary cipher */ /* Compare if the peer STA use AES as its unicast cipher */ if (MIX_CIPHER_WPA2_AES_ON(wdev->WpaMixPairCipher)) { if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][12], 4)) { pEntry->WepStatus = Ndis802_11AESEnable; return true; } } } else { /* AES */ if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4)) { pEntry->WepStatus = Ndis802_11AESEnable; return true; } } pStaTmp += 4; Count--; } } else {/* single cipher */ while (Count > 0) { if (RTMPEqualMemory(pStaTmp, &pAd->ApCfg.MBSSID[apidx].RSN_IE[IE_Idx][8], 4)) return true; pStaTmp += 4; Count--; } } } } return false; }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ USHORT TDLS_TPKMsg3Process( IN PRTMP_ADAPTER pAd, IN PRT_802_11_TDLS pTDLS, IN PUCHAR pRsnIe, IN UCHAR RsnLen, IN PUCHAR pFTIe, IN UCHAR FTLen, IN PUCHAR pTIIe, IN UCHAR TILen) { USHORT StatusCode = MLME_SUCCESS; UCHAR CipherTmp[64] = {0}; UCHAR CipherTmpLen = 0; FT_FTIE *ft = NULL; UCHAR oldMic[16]; UCHAR LinkIdentifier[20]; // Validate RsnIE // if (RsnLen == 0) // RSN not exist return MLME_INVALID_INFORMATION_ELEMENT; if (pRsnIe[2] < 1) // Smaller version return MLME_NOT_SUPPORT_RSN_VERSION; CipherTmpLen = CipherSuiteTDLSLen; if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) NdisMoveMemory(CipherTmp, CipherSuiteTDLSWpa2PskTkip, CipherTmpLen); else NdisMoveMemory(CipherTmp, CipherSuiteTDLSWpa2PskAes, CipherTmpLen); if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) CipherTmp[19] = TDLS_AKM_SUITE_1X; if ( RTMPEqualMemory(&pRsnIe[16], &CipherTmp[16], 4) == 0) // Invalid TDLS AKM return MLME_INVALID_AKMP; if ( RTMPEqualMemory(&pRsnIe[20], &CipherTmp[20], 2) == 0) // Invalid RSN capability return MLME_INVALID_RSN_CAPABILITIES; if ((RsnLen != 22) || (RTMPEqualMemory(pRsnIe, CipherTmp, RsnLen) == 0)) // Invalid Pairwise Cipher return REASON_UCIPHER_NOT_VALID; // Validate FTIE // ft = (PFT_FTIE)(pFTIe + 2); // point to the element of IE if ((FTLen != (sizeof(FT_FTIE) + 2)) || RTMPEqualMemory(&ft->MICCtr, TdlsZeroSsid, 2) == 0 || (RTMPEqualMemory(ft->SNonce, pTDLS->SNonce, 32) == 0) || (RTMPEqualMemory(ft->ANonce, pTDLS->ANonce, 32) == 0)) return REASON_FT_INVALID_FTIE; // Validate TIIE // if ((TILen != 7) || (pTIIe[2] != 2) || ( le2cpu32(*((PULONG) (pTIIe + 3))) < pTDLS->KeyLifetime)) return TDLS_STATUS_CODE_UNACCEPTABLE_LIFETIME; // Validate the MIC field of FTIE // // point to the element of IE ft = (PFT_FTIE)(pFTIe + 2); // backup MIC fromm the peer TDLS NdisMoveMemory(oldMic, ft->MIC, 16); // set MIC field to zero before MIC calculation NdisZeroMemory(ft->MIC, 16); // Construct LinkIdentifier (IE + Length + BSSID + Initiator MAC + Responder MAC) NdisZeroMemory(LinkIdentifier, 20); LinkIdentifier[0] = IE_TDLS_LINK_IDENTIFIER; LinkIdentifier[1] = 18; NdisMoveMemory(&LinkIdentifier[2], pAd->CommonCfg.Bssid, 6); NdisMoveMemory(&LinkIdentifier[8], pTDLS->MacAddr, 6); NdisMoveMemory(&LinkIdentifier[14], pAd->CurrentAddress, 6); //////////////////////////////////////////////////////////////////////// // The MIC field of FTIE shall be calculated on the concatenation, in the following order, of // 1. MAC_I (6 bytes) // 2. MAC_R (6 bytes) // 3. Transaction Sequence = 3 (1 byte) // 4. Link Identifier (20 bytes) // 5. RSN IE without the IE header (20 bytes) // 6. Timeout Interval IE (7 bytes) // 7. FTIE without the IE header, with the MIC field of FTIE set to zero (82 bytes) { UCHAR content[512]; ULONG c_len = 0; ULONG tmp_len = 0; UCHAR Seq = 3; UCHAR mic[16]; UINT tmp_aes_len = 0; NdisZeroMemory(mic, sizeof(mic)); /* make a header frame for calculating MIC. */ MakeOutgoingFrame(content, &tmp_len, MAC_ADDR_LEN, pTDLS->MacAddr, MAC_ADDR_LEN, pAd->CurrentAddress, 1, &Seq, END_OF_ARGS); c_len += tmp_len; /* concatenate Link Identifier */ MakeOutgoingFrame(content + c_len, &tmp_len, 20, LinkIdentifier, END_OF_ARGS); c_len += tmp_len; /* concatenate RSNIE */ MakeOutgoingFrame(content + c_len, &tmp_len, 20, pRsnIe + 2, END_OF_ARGS); c_len += tmp_len; /* concatenate Timeout Interval IE */ MakeOutgoingFrame(content + c_len, &tmp_len, 7, pTIIe, END_OF_ARGS); c_len += tmp_len; /* concatenate FTIE */ MakeOutgoingFrame(content + c_len, &tmp_len, sizeof(FT_FTIE), (PUCHAR)ft, END_OF_ARGS); c_len += tmp_len; /* Calculate MIC */ //AES_128_CMAC(pTDLS->TPK, content, c_len, mic); /* Compute AES-128-CMAC over the concatenation */ tmp_aes_len = AES_KEY128_LENGTH; AES_CMAC(content, c_len, pTDLS->TPK, 16, mic, &tmp_aes_len); NdisMoveMemory(ft->MIC, mic, 16); } //////////////////////////////////////////////////////////////////////// if (RTMPEqualMemory(oldMic, ft->MIC, 16) == 0) { DBGPRINT(RT_DEBUG_ERROR,("TDLS_TPKMsg3Process() MIC Error!!! \n")); return MLME_REQUEST_DECLINED; } return StatusCode; }
/* ======================================================================== Description: This routine frees all packets in PSQ that's destined to a specific DA. BCAST/MCAST in DTIMCount=0 case is also handled here, just like a PS-POLL is received from a WSTA which has MAC address FF:FF:FF:FF:FF:FF ======================================================================== */ VOID RtmpHandleRxPsPoll(RTMP_ADAPTER *pAd, UCHAR *pAddr, USHORT wcid, BOOLEAN isActive) { MAC_TABLE_ENTRY *pMacEntry; STA_TR_ENTRY *tr_entry = NULL; ASSERT(wcid < MAX_LEN_OF_MAC_TABLE); pMacEntry = &pAd->MacTab.Content[wcid]; tr_entry = &pAd->MacTab.tr_entry[wcid]; if (!RTMPEqualMemory(pMacEntry->Addr, pAddr, MAC_ADDR_LEN)) { DBGPRINT(RT_DEBUG_WARN | DBG_FUNC_PS,("%s(%d) PS-POLL (MAC addr not match) from %02x:%02x:%02x:%02x:%02x:%02x. Why???\n", __FUNCTION__, __LINE__, PRINT_MAC(pAddr))); return; } #ifdef UAPSD_SUPPORT00 if (UAPSD_MR_IS_ALL_AC_UAPSD(isActive, pMacEntry)) { /* IEEE802.11e spec. 11.2.1.7 Receive operation for STAs in PS mode during the CP When a non-AP QSTA that is using U-APSD and has all ACs delivery-enabled detects that the bit corresponding to its AID is set in the TIM, the non-AP QSTA shall issue a trigger frame or a PS-Poll frame to retrieve the buffered MSDU or management frames. WMM Spec. v1.1a 070601 3.6.2 U-APSD STA Operation 3.6.2.3 In case one or more ACs are not delivery-enabled ACs, the WMM STA may retrieve MSDUs and MMPDUs belonging to those ACs by sending PS-Polls to the WMM AP. In case all ACs are delivery enabled ACs, WMM STA should only use trigger frames to retrieve MSDUs and MMPDUs belonging to those ACs, and it should not send PS-Poll frames. Different definitions in IEEE802.11e and WMM spec. But we follow the WiFi WMM Spec. */ DBGPRINT(RT_DEBUG_TRACE, ("All AC are UAPSD, can not use PS-Poll\n")); return; /* all AC are U-APSD, can not use PS-Poll */ } #endif /* UAPSD_SUPPORT */ /* Reset ContinueTxFailCnt */ pMacEntry->ContinueTxFailCnt = 0; pAd->MacTab.tr_entry[pMacEntry->wcid].ContinueTxFailCnt = 0; if (isActive == FALSE) { if (tr_entry->PsDeQWaitCnt == 0) { tr_entry->PsDeQWaitCnt = 1; } else { DBGPRINT(RT_DEBUG_TRACE, ("%s(): : packet not send by HW then ignore other PS-Poll Aid[%d]!\n", __FUNCTION__, pMacEntry->Aid)); return; } } else tr_entry->PsDeQWaitCnt = 0; #ifdef CONFIG_AP_SUPPORT #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) { MtHandleRxPsPoll(pAd, pAddr, wcid, isActive); } #endif /* MT_MAC */ #if defined(RTMP_MAC) || defined(RLT_MAC) if ((pAd->chipCap.hif_type == HIF_RTMP) || (pAd->chipCap.hif_type == HIF_RLT)) { RalHandleRxPsPoll(pAd, pAddr, wcid, isActive); } #endif /* RTMP_MAC || RLT_MAC */ #endif /* CONFIG_AP_SUPPORT */ }
VOID RRM_EnqueueNeighborRep( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN UINT8 DialogToken, IN PCHAR pSsid, IN UINT8 SsidLen) { #define MIN(_x, _y) ((_x) > (_y) ? (_x) : (_y)) INT loop; HEADER_802_11 ActHdr; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen; ULONG PktLen; if ((pEntry == NULL) || (pEntry->func_tb_idx >= pAd->ApCfg.BssidNum)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Invalid STA.\n", __FUNCTION__)); return; } NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); /*Get an unused nonpaged memory */ if(NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__)); return; } /* build action frame header. */ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.if_addr, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid); NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); FrameLen = sizeof(HEADER_802_11); InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_RM, RRM_NEIGHTBOR_RSP); /* fill Dialog Token */ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken); #ifdef AP_SCAN_SUPPORT /* insert NeighborRep IE. */ for (loop = 0; loop < pAd->ScanTab.BssNr; loop++) { UINT8 BssMatch = FALSE; BSS_ENTRY *pBssEntry = &pAd->ScanTab.BssEntry[loop]; /* Discards all remain Bss if the packet length exceed packet buffer size. */ PktLen = FrameLen + sizeof(RRM_NEIGHBOR_REP_INFO) + (pAd->ApCfg.MBSSID[pEntry->func_tb_idx].RrmCfg.bDot11kRRMNeighborRepTSFEnable == TRUE ? 6 : 0); if (PktLen >= MGMT_DMA_BUFFER_SIZE) break; if (SsidLen != 0) BssMatch = RTMPEqualMemory(pBssEntry->Ssid, pSsid, MIN(SsidLen, pBssEntry->SsidLen)); else BssMatch = TRUE; if (BssMatch) { RRM_BSSID_INFO BssidInfo; BssidInfo.word = 0; BssidInfo.field.APReachAble = 3; BssidInfo.field.Security = 0; /* rrm to do. */ BssidInfo.field.KeyScope = 0; /* "report AP has same authenticator as the AP. */ BssidInfo.field.SepctrumMng = (pBssEntry->CapabilityInfo & (1 << 8))?1:0; BssidInfo.field.Qos = (pBssEntry->CapabilityInfo & (1 << 9))?1:0; BssidInfo.field.APSD = (pBssEntry->CapabilityInfo & (1 << 11))?1:0; BssidInfo.field.RRM = (pBssEntry->CapabilityInfo & RRM_CAP_BIT)?1:0; BssidInfo.field.DelayBlockAck = (pBssEntry->CapabilityInfo & (1 << 14))?1:0; BssidInfo.field.ImmediateBA = (pBssEntry->CapabilityInfo & (1 << 15))?1:0; /* reference 2012 spec. 802.11-2012.pdf page#581 (0 is not euqal to no security ) The Security bit, if 1, indicates that the AP identified by this BSSID supports the same security provisioning as used by the STA in its current association. If the bit is 0, it indicates either that the AP does not support the same security provisioning or that the security information is not available at this time. */ BssidInfo.field.KeyScope = 0; /* "report AP has same authenticator as the AP. */ /* reference 2012 spec. 802.11-2012.pdf page#582 (0 means information is not available ) The Key Scope bit, when set, indicates the AP indicated by this BSSID has the same authenticator as the AP sending the report. If this bit is 0, it indicates a distinct authenticator or the information is not available. */ BssidInfo.field.SepctrumMng = (pBssEntry->CapabilityInfo & (1 << 8))?1:0; BssidInfo.field.Qos = (pBssEntry->CapabilityInfo & (1 << 9))?1:0; BssidInfo.field.APSD = (pBssEntry->CapabilityInfo & (1 << 11))?1:0; BssidInfo.field.RRM = (pBssEntry->CapabilityInfo & RRM_CAP_BIT)?1:0; BssidInfo.field.DelayBlockAck = (pBssEntry->CapabilityInfo & (1 << 14))?1:0; BssidInfo.field.ImmediateBA = (pBssEntry->CapabilityInfo & (1 << 15))?1:0; BssidInfo.field.MobilityDomain = (pBssEntry->bHasMDIE )?1:0; BssidInfo.field.HT = (pBssEntry->HtCapabilityLen != 0)?1:0; #ifdef DOT11_VHT_AC BssidInfo.field.VHT = (pBssEntry->vht_cap_len != 0)?1:0; #endif /* DOT11_VHT_AC */ /* reference spec: dot11FrameRprtPhyType OBJECT-TYPE SYNTAX INTEGER { fhss(1), dsss(2), irbaseband(3), ofdm(4), hrdsss(5), erp(6), ht(7), vht(9) } */ if (pBssEntry->Channel > 14) // 5G case { if (pBssEntry->HtCapabilityLen != 0) // HT or Higher case { #ifdef DOT11_VHT_AC if (pBssEntry->vht_cap_len != 0) pBssEntry->CondensedPhyType = 9; else #endif /* DOT11_VHT_AC */ pBssEntry->CondensedPhyType = 7; } else // OFDM case { pBssEntry->CondensedPhyType = 4; } } else // 2.4G case { if (pBssEntry->HtCapabilityLen != 0) //HT case pBssEntry->CondensedPhyType = 7; else if (ERP_IS_NON_ERP_PRESENT(pBssEntry->Erp)) //ERP case pBssEntry->CondensedPhyType = 6; else if (pBssEntry->SupRateLen > 4)// OFDM case (1,2,5.5,11 for CCK 4 Rates) pBssEntry->CondensedPhyType = 4; /* no CCK's definition in spec. */ } RRM_InsertNeighborRepIE(pAd, (pOutBuffer + FrameLen), &FrameLen, sizeof(RRM_NEIGHBOR_REP_INFO), pBssEntry->Bssid, BssidInfo, pBssEntry->RegulatoryClass, pBssEntry->Channel, pBssEntry->CondensedPhyType); } /* shall insert Neighbor Report TSF offset when the MIB attribute dot11RRMNeighborReportTSFOffsetEnabled is true. */ if (pAd->ApCfg.MBSSID[pEntry->func_tb_idx].RrmCfg.bDot11kRRMNeighborRepTSFEnable) { UINT32 Ttfs = (UINT32)(pBssEntry->TTSF[3] << 24) + (UINT32)(pBssEntry->TTSF[2] << 16) + (UINT32)(pBssEntry->TTSF[1] << 8) + (UINT32)(pBssEntry->TTSF[0]); UINT32 Ptfs = (UINT32)(pBssEntry->PTSF[3] << 24) + (UINT32)(pBssEntry->PTSF[2] << 16) + (UINT32)(pBssEntry->PTSF[1] << 8) + (UINT32)(pBssEntry->PTSF[0]); RRM_InsertNeighborTSFOffsetSubIE(pAd, (pOutBuffer + FrameLen), &FrameLen, cpu2le16((UINT16)ABS(Ttfs, Ptfs)), pBssEntry->BeaconPeriod); } } #endif /* AP_SCAN_SUPPORT */ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); if (pOutBuffer) MlmeFreeMemory(pAd, pOutBuffer); return; }
VOID RTUSBBulkOutDataPacket( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId, IN UCHAR Index) { PHT_TX_CONTEXT pHTTXContext; PURB pUrb; int ret = 0; PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL; PTXWI_STRUC pTxWI; ULONG TmpBulkEndPos, ThisBulkSize; unsigned long IrqFlags = 0, IrqFlags2 = 0; PUCHAR pWirelessPkt, pAppendant; BOOLEAN bTxQLastRound = FALSE; UCHAR allzero[4]= {0x0,0x0,0x0,0x0}; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) ) { pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; ThisBulkSize = 0; TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; if ((pHTTXContext->bCopySavePad == TRUE)) { if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8); pHTTXContext->bCopySavePad = FALSE; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition)); } do { pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos]; pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU)); if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) { if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) ) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } else { if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) ) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } if (TmpBulkEndPos == pHTTXContext->CurWritePosition) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } if (pTxInfo->QSEL != FIFO_EDCA) { printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL); printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad); hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); } if (pTxInfo->USBDMATxPktLen <= 8) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); DBGPRINT(RT_DEBUG_ERROR ,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos)); { DBGPRINT_RAW(RT_DEBUG_ERROR ,("%x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } pAd->bForcePrintTX = TRUE; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount; pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount; pLastTxInfo = pTxInfo; pTxInfo->QSEL = FIFO_EDCA; ThisBulkSize += (pTxInfo->USBDMATxPktLen+4); TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4); if (TmpBulkEndPos != pHTTXContext->CurWritePosition) pTxInfo->USBDMANextVLD = 1; if (pTxInfo->SwUseLastRound == 1) { if (pHTTXContext->CurWritePosition == 8) pTxInfo->USBDMANextVLD = 0; pTxInfo->SwUseLastRound = 0; bTxQLastRound = TRUE; pHTTXContext->ENextBulkOutPosition = 8; break; } }while (TRUE); if (pLastTxInfo) { pLastTxInfo->USBDMANextVLD = 0; } if ((bTxQLastRound == FALSE) && (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) || (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition)) ) { NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8); pHTTXContext->bCopySavePad = TRUE; if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { PUCHAR pBuf = &pHTTXContext->SavedPad[0]; DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize)); pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition]; DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7])); } } if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); pAppendant = &pWirelessPkt[TmpBulkEndPos]; NdisZeroMemory(pAppendant, 8); ThisBulkSize += 4; pHTTXContext->LastOne = TRUE; if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0) ThisBulkSize += 4; pHTTXContext->BulkOutSize = ThisBulkSize; pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1; BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete); pUrb = pHTTXContext->pUrb; if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret)); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext->IRPPending = TRUE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutReq++; }
/* ======================================================================== Description: This routine frees all packets in PSQ that's destined to a specific DA. BCAST/MCAST in DTIMCount=0 case is also handled here, just like a PS-POLL is received from a WSTA which has MAC address FF:FF:FF:FF:FF:FF ======================================================================== */ VOID RtmpHandleRxPsPoll(RTMP_ADAPTER *pAd, UCHAR *pAddr, USHORT wcid, BOOLEAN isActive) { QUEUE_ENTRY *pQEntry; MAC_TABLE_ENTRY *pMacEntry; unsigned long IrqFlags; /* DBGPRINT(RT_DEBUG_TRACE, ("rcv PS-POLL (AID=%d) from %02x:%02x:%02x:%02x:%02x:%02x\n", Aid, PRINT_MAC(pAddr))); */ pMacEntry = &pAd->MacTab.Content[wcid]; if (RTMPEqualMemory(pMacEntry->Addr, pAddr, MAC_ADDR_LEN)) { #ifdef DROP_MASK_SUPPORT /* Disable Drop Mask */ set_drop_mask_per_client(pAd, pMacEntry, 2, 0); #endif /* DROP_MASK_SUPPORT */ #ifdef PS_ENTRY_MAITENANCE pMacEntry->continuous_ps_count = 0; #endif /* PS_ENTRY_MAITENANCE */ /* Sta is change to Power Active stat. Reset ContinueTxFailCnt */ pMacEntry->ContinueTxFailCnt = 0; #ifdef UAPSD_SUPPORT if (UAPSD_MR_IS_ALL_AC_UAPSD(isActive, pMacEntry)) { /* IEEE802.11e spec. 11.2.1.7 Receive operation for STAs in PS mode during the CP When a non-AP QSTA that is using U-APSD and has all ACs delivery-enabled detects that the bit corresponding to its AID is set in the TIM, the non-AP QSTA shall issue a trigger frame or a PS-Poll frame to retrieve the buffered MSDU or management frames. WMM Spec. v1.1a 070601 3.6.2 U-APSD STA Operation 3.6.2.3 In case one or more ACs are not delivery-enabled ACs, the WMM STA may retrieve MSDUs and MMPDUs belonging to those ACs by sending PS-Polls to the WMM AP. In case all ACs are delivery enabled ACs, WMM STA should only use trigger frames to retrieve MSDUs and MMPDUs belonging to those ACs, and it should not send PS-Poll frames. Different definitions in IEEE802.11e and WMM spec. But we follow the WiFi WMM Spec. */ DBGPRINT(RT_DEBUG_TRACE, ("All AC are UAPSD, can not use PS-Poll\n")); return; /* all AC are U-APSD, can not use PS-Poll */ } #endif /* UAPSD_SUPPORT */ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); if (isActive == FALSE) { if (pMacEntry->PsQueue.Head) { #ifdef UAPSD_SUPPORT UINT32 NumOfOldPsPkt; NumOfOldPsPkt = pAd->TxSwQueue[QID_AC_BE].Number; #endif /* UAPSD_SUPPORT */ pQEntry = RemoveHeadQueue(&pMacEntry->PsQueue); if ( pMacEntry->PsQueue.Number >=1 ) RTMP_SET_PACKET_MOREDATA(RTPKT_TO_OSPKT(pQEntry), TRUE); InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QID_AC_BE], pQEntry); #ifdef UAPSD_SUPPORT /* we need to call RTMPDeQueuePacket() immediately as below */ if (NumOfOldPsPkt != pAd->TxSwQueue[QID_AC_BE].Number) { if (RTMP_GET_PACKET_DHCP(RTPKT_TO_OSPKT(pQEntry)) || RTMP_GET_PACKET_EAPOL(RTPKT_TO_OSPKT(pQEntry)) || RTMP_GET_PACKET_WAI(RTPKT_TO_OSPKT(pQEntry))) { /* These packets will use 1M/6M rate to send. If you use 1M(2.4G)/6M(5G) to send, no statistics count in NICUpdateFifoStaCounters(). So we can not count it for UAPSD; Or the SP will not closed until timeout. */ } else UAPSD_MR_MIX_PS_POLL_RCV(pAd, pMacEntry); } #endif /* UAPSD_SUPPORT */ } else { /* or transmit a (QoS) Null Frame; In addtion, in Station Keep Alive mechanism, we need to send a QoS Null frame to detect the station live status. */ BOOLEAN bQosNull = FALSE; if (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)) bQosNull = TRUE; RtmpEnqueueNullFrame(pAd, pMacEntry->Addr, pMacEntry->CurrTxRate, pMacEntry->Aid, pMacEntry->apidx, bQosNull, TRUE, 0); } } else { #ifdef UAPSD_SUPPORT /* deliver all queued UAPSD packets */ UAPSD_AllPacketDeliver(pAd, pMacEntry); /* end the SP if exists */ UAPSD_MR_ENTRY_RESET(pAd, pMacEntry); #endif /* UAPSD_SUPPORT */ while(pMacEntry->PsQueue.Head) { pQEntry = RemoveHeadQueue(&pMacEntry->PsQueue); InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QID_AC_BE], pQEntry); } } if ((pMacEntry->Aid > 0) && (pMacEntry->Aid < MAX_LEN_OF_MAC_TABLE) && (pMacEntry->PsQueue.Number == 0)) { /* clear corresponding TIM bit because no any PS packet */ #ifdef CONFIG_AP_SUPPORT if(pMacEntry->wdev->wdev_type == WDEV_TYPE_AP) { WLAN_MR_TIM_BIT_CLEAR(pAd, pMacEntry->apidx, pMacEntry->Aid); } #endif /* CONFIG_AP_SUPPORT */ pMacEntry->PsQIdleCount = 0; } RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); /* Dequeue outgoing frames from TxSwQueue0..3 queue and process it TODO: 2004-12-27 it's not a good idea to handle "More Data" bit here. because the RTMPDeQueue process doesn't guarantee to de-queue the desired MSDU from the corresponding TxSwQueue/PsQueue when QOS in-used. We should consider "HardTransmt" this MPDU using MGMT queue or things like that. */ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); } else { DBGPRINT(RT_DEBUG_ERROR,("rcv PS-POLL (AID=%d not match) from %02x:%02x:%02x:%02x:%02x:%02x\n", pMacEntry->Aid, PRINT_MAC(pAddr))); } }
VOID WfdParseSubElmt( IN PRTMP_ADAPTER pAd, IN PWFD_ENTRY_INFO pWfdEntryInfo, IN VOID *Msg, IN ULONG MsgLen) { PWFD_COUPLED_SINK_INFO pSinkInfo; PWFD_DEVICE_INFO pWfd_info; WFD_DEVICE_INFO DevInfo; PP2PEID_STRUCT pWfdEid; PEID_STRUCT pEid; PUCHAR pWfdIe = NULL; ULONG AccuWfdIELen; ULONG AccuIeLen = 0; ULONG Length = 0; ULONG AttriLen; UCHAR offset; BOOLEAN bTdlsEntry = FALSE; DBGPRINT(RT_DEBUG_INFO, ("%s ----->\n", __FUNCTION__)); //QQ TBD, p2p widi need to parse rtsp port! { if ((!pAd->StaCfg.WfdCfg.bWfdEnable) || (MsgLen == 0)) return; } // hex_dump("WfdParseSubElmt::", Msg, MsgLen); pEid = (PEID_STRUCT)Msg; AccuIeLen = pEid->Len + 2; // printk("MsgLen = %d. AccuIeLen = %d.\n", MsgLen, AccuIeLen); while ((ULONG)(AccuIeLen) <= MsgLen) { if (RTMPEqualMemory(&pEid->Octet[0], WIFIDISPLAY_OUI, 4)) { /* Get Request content capability */ pWfdIe = pWfdEid = (PP2PEID_STRUCT) &pEid->Octet[4]; AccuWfdIELen = pEid->Len; // printk("AccuWfdIeLen = %d. EidLen = %04x\n", AccuWfdIELen, pEid->Len); /* The value of AccuP2PIELen shall reduce the length of OUI (4) */ AccuWfdIELen -= 4; AttriLen = pWfdEid->Len[1] + (pWfdEid->Len[0] << 8); Length = 0; // printk("AttriLen = %d. WfdEid = %d. WfdEidLen = %x %x\n", AttriLen, pWfdEid->Eid, pWfdEid->Len[1], pWfdEid->Len[0]); pWfdEntryInfo->bWfdClient = TRUE; /* Set the P2P client as the WFD device */ // while (Length <=(Length + 3 + AttriLen) <= AccuWfdIELen) while (Length <= AccuWfdIELen) { // printk(">> Eid = %d.\n", pWfdEid->Eid); switch (pWfdEid->Eid) { case SUBID_WFD_DEVICE_INFO: { pWfd_info = &(pWfdEid->Octet[0]); RTMPMoveMemory(&DevInfo, pWfdIe, sizeof(WFD_DEVICE_INFO)); RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_device_info_ie, pWfdEid->Octet, SUBID_WFD_DEVICE_INFO_LEN); cpu2le16(&DevInfo); pWfdEntryInfo->wfd_devive_type = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 0) & 0x3); pWfdEntryInfo->source_coupled = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 2) & 0x1); pWfdEntryInfo->sink_coupled = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 3) & 0x1); pWfdEntryInfo->session_avail = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 4) & 0x3); pWfdEntryInfo->wfd_service_discovery = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 6) & 0x1); pWfdEntryInfo->wfd_PC = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 7) & 0x1); pWfdEntryInfo->wfd_CP = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 8) & 0x1); pWfdEntryInfo->wfd_time_sync = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 9) & 0x1); pWfdEntryInfo->sink_audio_unsupport = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 10) & 0x1); pWfdEntryInfo->source_audio_only= ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 11) & 0x1); pWfdEntryInfo->tdls_persistent_group = ((be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[0]))) >> 12) & 0x1); pWfdEntryInfo->rtsp_port = be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[2]))); pWfdEntryInfo->max_throughput = be2cpu16(get_unaligned((PUSHORT)(&pWfdEid->Octet[4]))); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_DEVICE_INFO\n", __FUNCTION__)); break; } case SUBID_WFD_ASSOCIATED_BSSID: { RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_associate_bssid_ie, pWfdEid->Octet, SUBID_WFD_ASSOCIATED_BSSID_LEN); RTMPMoveMemory(&pWfdEntryInfo->assoc_addr, pWfdEid->Octet, MAC_ADDR_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_ASSOCIATED_BSSID\n", __FUNCTION__)); break; } case SUBID_WFD_AUDIO_FORMATS: { RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_audio_format_ie, pWfdEid->Octet, SUBID_WFD_AUDIO_FORMATS_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_AUDIO_FORMATS\n", __FUNCTION__)); break; } case SUBID_WFD_VIDEO_FORMATS: { RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_video_format_ie, pWfdEid->Octet, SUBID_WFD_VIDEO_FORMATS_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_VIDEO_FORMATS\n", __FUNCTION__)); break; } case SUBID_WFD_3D_VIDEO_FORMATS: { RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_3d_video_format_ie, pWfdEid->Octet, SUBID_WFD_3D_VIDEO_FORMATS_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_3D_VIDEO_FORMATS\n", __FUNCTION__)); break; } case SUBID_WFD_CONTENT_PROTECTION: { RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_content_proctection, pWfdEid->Octet, SUBID_WFD_CONTENT_PROTECTION_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_CONTENT_PROTECTION\n", __FUNCTION__)); break; } case SUBID_WFD_COUPLED_SINK_INFO: { RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_couple_sink_info_ie, pWfdEid->Octet, SUBID_WFD_COUPLED_SINK_INFO_LEN); RTMPMoveMemory(&pWfdEntryInfo->coupled_sink_status, pWfdEid->Octet, SUBID_WFD_COUPLED_SINK_INFO_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_COUPLED_SINK_INFO\n", __FUNCTION__)); break; } case SUBID_WFD_EXTENDED_CAP: { RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_extent_capability_ie, &pWfdEid->Octet, SUBID_WFD_EXTENDED_CAP_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_EXTENDED_CAP\n", __FUNCTION__)); break; } case SUBID_WFD_LOCAL_IP_ADDR: { RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_local_ip_ie, &pWfdEid->Octet, SUBID_WFD_LOCAL_IP_ADDR_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_LOCAL_IP_ADDR\n", __FUNCTION__)); break; } case SUBID_WFD_SESSION_INFO: { /* TODO : allocate memory to store the parsed WFD device tables */ RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_session_info_ie, &pWfdEid->Octet, SUBID_WFD_DEVICE_INFO_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_SESSION_INFO\n", __FUNCTION__)); break; } case SUBID_WFD_ALTERNATE_MAC_ADDR: { RTMPMoveMemory(&pWfdEntryInfo->wfd_serv_disc_query_info.wfd_alternate_mac_addr_ie, &pWfdEid->Octet, SUBID_WFD_ALTERNATE_MAC_ADDR_LEN); DBGPRINT(RT_DEBUG_INFO, ("%s::SUBID_WFD_ALTERNATE_MAC_ADDR\n", __FUNCTION__)); break; } default: DBGPRINT(RT_DEBUG_ERROR, (" SUBID_WFD_ unknown Eid = %x \n", pWfdEid->Eid)); hex_dump("WfdParseSubElement::", Msg, MsgLen); break; } // printk("<< Length = %d. AttriLen = %d. AccuWfdIELen = %d.\n", Length, AttriLen, AccuWfdIELen); Length = Length + 3 + AttriLen; /* Eid[1] + Len[2] + content[Len] */ // printk(">> Length = %d. AttriLen = %d. AccuWfdIELen = %d.\n", Length, AttriLen, AccuWfdIELen); if (Length >= AccuWfdIELen) break; pWfdEid = (PP2PEID_STRUCT)((UCHAR*)pWfdEid + 3 + AttriLen); AttriLen = pWfdEid->Len[1] + (pWfdEid->Len[0] << 8); } } /* Already reach the final IE and stop finding next Eid. */ if (AccuIeLen >= MsgLen) break; /* Forward buffer to next pEid */ if (RTMPEqualMemory(&pEid->Octet[0], WIFIDISPLAY_OUI, 4)) { pEid = (PEID_STRUCT)((UCHAR*)pEid + pEid->Len + 2); } /* Since we get the next pEid, Predict the accumulated IeLen after adding the next pEid's length. The accumulated IeLen is for checking length. */ if (RTMPEqualMemory(&pEid->Octet[0], WIFIDISPLAY_OUI, 4)) { AccuIeLen += (pEid->Len + 2); } }
static VOID APPeerAuthReqAtIdleAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) { INT i; USHORT RspReason; AUTH_FRAME_INFO auth_info; UINT32 apidx; PHEADER_802_11 pRcvHdr; HEADER_802_11 AuthHdr; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; MAC_TABLE_ENTRY *pEntry; STA_TR_ENTRY *tr_entry; UCHAR ChTxtIe = 16, ChTxtLen = CIPHER_TEXT_LEN; BSS_STRUCT *pMbss; struct wifi_dev *wdev; if (pAd->ApCfg.BANClass3Data == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("Disallow new Association\n")); return; } if (!APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, &auth_info)) return; /* Find which MBSSID to be authenticate */ apidx = get_apidx_by_addr(pAd, auth_info.addr1); if (apidx >= pAd->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n")); return; } pMbss = &pAd->ApCfg.MBSSID[apidx]; wdev = &pMbss->wdev; ASSERT((wdev->func_idx == apidx)); if ((wdev->if_dev == NULL) || ((wdev->if_dev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(wdev->if_dev)))) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); return; } pEntry = MacTableLookup(pAd, auth_info.addr2); if (pEntry && IS_ENTRY_CLIENT(pEntry)) { tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; #ifdef DOT11W_PMF_SUPPORT if ((CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PMF_CAPABLE)) && (tr_entry->PortSecured == WPA_802_1X_PORT_SECURED)) goto SendAuth; #endif /* DOT11W_PMF_SUPPORT */ if (!RTMPEqualMemory(auth_info.addr1, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid, MAC_ADDR_LEN)) { MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); pEntry = NULL; DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n")); } else { if (pEntry->bIAmBadAtheros == TRUE) { AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n")); pEntry->bIAmBadAtheros = FALSE; } #ifdef DOT11_N_SUPPORT BASessionTearDownALL(pAd, pEntry->wcid); #endif /* DOT11_N_SUPPORT */ ASSERT(pEntry->Aid == Elem->Wcid); } } #ifdef DOT11W_PMF_SUPPORT SendAuth: #endif /* DOT11W_PMF_SUPPORT */ pRcvHdr = (PHEADER_802_11)(Elem->Msg); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from " "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", apidx, auth_info.auth_seq, auth_info.auth_alg, auth_info.auth_status, Elem->Wcid, PRINT_MAC(auth_info.addr2))); #ifdef WSC_V2_SUPPORT /* Do not check ACL when WPS V2 is enabled and ACL policy is positive. */ if ((pMbss->WscControl.WscConfMode != WSC_DISABLE) && (pMbss->WscControl.WscV2Info.bEnableWpsV2) && (pMbss->WscControl.WscV2Info.bWpsEnable) && (pMbss->AccessControlList.Policy == 1)) ; else #endif /* WSC_V2_SUPPORT */ /* fail in ACL checking => send an AUTH-Fail seq#2. */ if (! ApCheckAccessControlList(pAd, auth_info.addr2, apidx)) { ASSERT(auth_info.auth_seq == 1); ASSERT(pEntry == NULL); APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, auth_info.addr2, wdev->wdev_idx, 0); DBGPRINT(RT_DEBUG_TRACE, ("Failed in ACL checking => send an AUTH seq#2 with " "Status code = %d\n", MLME_UNSPECIFY_FAIL)); return; } if ((auth_info.auth_alg == AUTH_MODE_OPEN) && (pMbss->wdev.AuthMode != Ndis802_11AuthModeShared)) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, auth_info.addr2, wdev, ENTRY_CLIENT, OPMODE_AP, TRUE); if (pEntry) { tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; #ifdef DOT11W_PMF_SUPPORT if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PMF_CAPABLE)) || (tr_entry->PortSecured != WPA_802_1X_PORT_SECURED)) #endif /* DOT11W_PMF_SUPPORT */ { pEntry->AuthState = AS_AUTH_OPEN; pEntry->Sst = SST_AUTH; /* what if it already in SST_ASSOC ??????? */ } APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_SUCCESS); } else ; /* MAC table full, what should we respond ????? */ } else if ((auth_info.auth_alg == AUTH_MODE_KEY) && ((wdev->AuthMode == Ndis802_11AuthModeShared) || (wdev->AuthMode == Ndis802_11AuthModeAutoSwitch))) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, auth_info.addr2, wdev, ENTRY_CLIENT, OPMODE_AP, TRUE); if (pEntry) { pEntry->AuthState = AS_AUTHENTICATING; pEntry->Sst = SST_NOT_AUTH; /* what if it already in SST_ASSOC ??????? */ /* log this STA in AuthRspAux machine, only one STA is stored. If two STAs using */ /* SHARED_KEY authentication mingled together, then the late comer will win. */ COPY_MAC_ADDR(&pAd->ApMlmeAux.Addr, auth_info.addr2); for(i=0; i<CIPHER_TEXT_LEN; i++) pAd->ApMlmeAux.Challenge[i] = RandomByte(pAd); RspReason = 0; auth_info.auth_seq++; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if(NStatus != NDIS_STATUS_SUCCESS) return; /* if no memory, can't do anything */ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH seq#2 (Challenge)\n")); MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, auth_info.addr2, wdev->if_addr, wdev->bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AuthHdr, 2, &auth_info.auth_alg, 2, &auth_info.auth_seq, 2, &RspReason, 1, &ChTxtIe, 1, &ChTxtLen, CIPHER_TEXT_LEN, pAd->ApMlmeAux.Challenge, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } else ; /* MAC table full, what should we respond ???? */ } else { /* wrong algorithm */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, auth_info.auth_alg, auth_info.auth_seq + 1, MLME_ALG_NOT_SUPPORT); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->wcid, pEntry->Addr); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Alg=%d, Seq=%d, AuthMode=%d\n", auth_info.auth_alg, auth_info.auth_seq, pAd->ApCfg.MBSSID[apidx].wdev.AuthMode)); } }
static VOID APPeerAuthReqAtIdleAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { int i; USHORT Seq, Alg, RspReason, Status; UCHAR Addr1[MAC_ADDR_LEN]; UCHAR Addr2[MAC_ADDR_LEN]; CHAR Chtxt[CIPHER_TEXT_LEN]; UINT32 apidx; PHEADER_802_11 pRcvHdr; HEADER_802_11 AuthHdr; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; MAC_TABLE_ENTRY *pEntry; UCHAR ChTxtIe = 16, ChTxtLen = CIPHER_TEXT_LEN; if (! APPeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, &Alg, &Seq, &Status, Chtxt )) return; /* Find which MBSSID to be authenticate */ for (apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++) { if (RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[apidx].Bssid, MAC_ADDR_LEN)) break; } if (apidx >= pAd->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid not found\n")); return; } if ((pAd->ApCfg.MBSSID[apidx].MSSIDDev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].MSSIDDev))) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Bssid IF didn't up yet.\n")); return; } /* End of if */ pEntry = MacTableLookup(pAd, Addr2); if (pEntry && IS_ENTRY_CLIENT(pEntry)) { if (!RTMPEqualMemory(Addr1, pAd->ApCfg.MBSSID[pEntry->apidx].Bssid, MAC_ADDR_LEN)) { MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); pEntry = NULL; DBGPRINT(RT_DEBUG_WARN, ("AUTH - Bssid does not match\n")); } else { if (pEntry->bIAmBadAtheros == TRUE) { AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("Atheros Problem. Turn on RTS/CTS!!!\n")); pEntry->bIAmBadAtheros = FALSE; } #ifdef DOT11_N_SUPPORT BASessionTearDownALL(pAd, pEntry->Aid); #endif /* DOT11_N_SUPPORT */ ASSERT(pEntry->Aid == Elem->Wcid); } } pRcvHdr = (PHEADER_802_11)(Elem->Msg); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MBSS(%d), Rcv AUTH seq#%d, Alg=%d, Status=%d from " "[wcid=%d]%02x:%02x:%02x:%02x:%02x:%02x\n", apidx, Seq, Alg, Status, Elem->Wcid, PRINT_MAC(Addr2))); /* fail in ACL checking => send an AUTH-Fail seq#2. */ if (! ApCheckAccessControlList(pAd, Addr2, apidx)) { ASSERT(Seq == 1); ASSERT(pEntry == NULL); APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_UNSPECIFY_FAIL); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, Addr2, apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("Failed in ACL checking => send an AUTH seq#2 with " "Status code = %d\n", MLME_UNSPECIFY_FAIL)); return; } if ((Alg == AUTH_MODE_OPEN) && (pAd->ApCfg.MBSSID[apidx].AuthMode != Ndis802_11AuthModeShared)) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, Addr2, apidx, OPMODE_AP, TRUE); if (pEntry) { { pEntry->AuthState = AS_AUTH_OPEN; pEntry->Sst = SST_AUTH; /* what if it already in SST_ASSOC ??????? */ } APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_SUCCESS); } else ; /* MAC table full, what should we respond ????? */ } else if ((Alg == AUTH_MODE_KEY) && ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeShared) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeAutoSwitch))) { if (!pEntry) pEntry = MacTableInsertEntry(pAd, Addr2, apidx, OPMODE_AP, TRUE); if (pEntry) { pEntry->AuthState = AS_AUTHENTICATING; pEntry->Sst = SST_NOT_AUTH; /* what if it already in SST_ASSOC ??????? */ /* log this STA in AuthRspAux machine, only one STA is stored. If two STAs using */ /* SHARED_KEY authentication mingled together, then the late comer will win. */ COPY_MAC_ADDR(&pAd->ApMlmeAux.Addr, Addr2); for(i=0; i<CIPHER_TEXT_LEN; i++) pAd->ApMlmeAux.Challenge[i] = RandomByte(pAd); RspReason = 0; Seq++; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if(NStatus != NDIS_STATUS_SUCCESS) return; /* if no memory, can't do anything */ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH seq#2 (Challenge)\n")); MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, pAd->ApCfg.MBSSID[apidx].Bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AuthHdr, 2, &Alg, 2, &Seq, 2, &RspReason, 1, &ChTxtIe, 1, &ChTxtLen, CIPHER_TEXT_LEN, pAd->ApMlmeAux.Challenge, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } else ; /* MAC table full, what should we respond ???? */ } else { /* wrong algorithm */ APPeerAuthSimpleRspGenAndSend(pAd, pRcvHdr, Alg, Seq + 1, MLME_ALG_NOT_SUPPORT); /* If this STA exists, delete it. */ if (pEntry) MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Alg=%d, Seq=%d, AuthMode=%d\n", Alg, Seq, pAd->ApCfg.MBSSID[apidx].AuthMode)); } }
VOID RTUSBBulkOutDataPacket( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId, IN UCHAR Index) { PHT_TX_CONTEXT pHTTXContext; PURB pUrb; int ret = 0; PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL; PTXWI_STRUC pTxWI; ULONG TmpBulkEndPos, ThisBulkSize; unsigned long IrqFlags = 0, IrqFlags2 = 0; PUCHAR pWirelessPkt, pAppendant; #ifdef USB_BULK_BUF_ALIGMENT BOOLEAN bLasAlignmentsectiontRound = FALSE; #else BOOLEAN bTxQLastRound = FALSE; UCHAR allzero[4]= {0x0,0x0,0x0,0x0}; #endif /* USB_BULK_BUF_ALIGMENT */ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) { BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } pAd->BulkOutPending[BulkOutPipeId] = TRUE; if (((!OPSTATUS_TEST_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED)) && ( !OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))) ) { pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext = &(pAd->TxContext[BulkOutPipeId]); BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); #ifdef USB_BULK_BUF_ALIGMENT if ( (pHTTXContext->NextBulkIdx != pHTTXContext->CurtBulkIdx) || ((pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition) &&(pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx)) || ((pHTTXContext->CurWriteRealPos == 0) && (pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx)) ) #else if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) #endif /* USB_BULK_BUF_ALIGMENT */ /* druing writing. */ { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; /* Clear Data flag*/ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } /* Clear Data flag*/ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)); RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); /*DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), */ /* pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, */ /* pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));*/ pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition; ThisBulkSize = 0; TmpBulkEndPos = pHTTXContext->NextBulkOutPosition; #ifdef USB_BULK_BUF_ALIGMENT INT idx; idx = pHTTXContext->NextBulkIdx; pWirelessPkt = &pHTTXContext->TransferBuffer[idx]->field.WirelessPacket[0]; #else pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0]; #endif /* USB_BULK_BUF_ALIGMENT */ #ifndef USB_BULK_BUF_ALIGMENT if ((pHTTXContext->bCopySavePad == TRUE)) { if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8); pHTTXContext->bCopySavePad = FALSE; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition)); } #endif /* USB_BULK_BUF_ALIGMENT */ do { pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos]; pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE]; if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU)); /* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items*/ /*if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/ if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) { #ifdef INF_AMAZON_SE /*Iverson Add for AMAZON USB (RT2070 && RT3070) to pass WMM A2-T4 ~ A2-T10*/ if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) { /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate*/ if(pTxWI->PacketId == 6) { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&pAd->BulkOutDataSizeLimit[BulkOutPipeId]) == pAd->BulkOutDataSizeLimit[BulkOutPipeId])) { /*printk("===Bulkout size limit :%d ===\n",MaxBulkOutSize);*/ /*DBGPRINT(RT_DEBUG_TRACE,("b mode BulkOutPipeId %d pAd->BulkOutDataSizeLimit[BulkOutPipeId] %d \n",BulkOutPipeId,pAd->BulkOutDataSizeLimit[BulkOutPipeId]));*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } } else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { /* Limit BulkOut size to about 4k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #endif /* INF_AMAZON_SE */ #ifndef INF_AMAZON_SE #ifndef USB_BULK_BUF_ALIGMENT if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { /* Limit BulkOut size to about 4k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) { /* Limit BulkOut size to about 24k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; /* when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section. */ bLasAlignmentsectiontRound = TRUE; break; } #endif /* USB_BULK_BUF_ALIGMENT */ #endif /* INF_AMAZON_SE */ #ifndef USB_BULK_BUF_ALIGMENT else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #else else if (((pAd->BulkOutMaxPacketSize < 512) && (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) )) { /* Limit BulkOut size to about 24k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; /* when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section. */ bLasAlignmentsectiontRound = TRUE; break; } #endif /* USB_BULK_BUF_ALIGMENT */ } /* end Iverson*/ else { #ifdef USB_BULK_BUF_ALIGMENT if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) #else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) #endif /* USB_BULK_BUF_ALIGMENT */ { /* Limit BulkOut size to about 24k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; #ifdef USB_BULK_BUF_ALIGMENT /* when bulk size is > 0x6000, it mean that this is the lasttround at this alignmnet section. */ bLasAlignmentsectiontRound = TRUE; /* printk("data bulk out bLasAlignmentsectiontRound \n");*/ #endif /* USB_BULK_BUF_ALIGMENT */ break; } #ifdef INF_AMAZON_SE else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&pAd->BulkOutDataSizeLimit[BulkOutPipeId]) == pAd->BulkOutDataSizeLimit[BulkOutPipeId])) { /*printk("===Bulkout size limit :%d ===\n",ThisBulkSize);*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #endif /* INF_AMAZON_SE */ #ifndef USB_BULK_BUF_ALIGMENT else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { /* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */ /* For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #else else if (((pAd->BulkOutMaxPacketSize < 512) && (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&BULKOUT_SIZE) == BULKOUT_SIZE)) )) { /* Limit BulkOut size to about 24k bytes.*/ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; /* when bulk size is > 6000, it mean that this is the lasttround at this alignmnet section. */ bLasAlignmentsectiontRound = TRUE; break; } #endif /* USB_BULK_BUF_ALIGMENT */ } #ifdef USB_BULK_BUF_ALIGMENT if ((TmpBulkEndPos == pHTTXContext->CurWritePosition) && (pHTTXContext->NextBulkIdx == pHTTXContext->CurWriteIdx)) #else if (TmpBulkEndPos == pHTTXContext->CurWritePosition) #endif /* USB_BULK_BUF_ALIGMENT */ { pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } #if !defined(CONFIG_MULTI_CHANNEL) && !defined(DOT11Z_TDLS_SUPPORT) if (pTxInfo->QSEL != FIFO_EDCA) { DBGPRINT(RT_DEBUG_ERROR, ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL)); DBGPRINT(RT_DEBUG_ERROR, ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); } #endif /* !defined(CONFIG_MULTI_CHANNEL) && !defined(DOT11Z_TDLS_SUPPORT) */ if (pTxInfo->USBDMATxPktLen <= 8) { BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n", pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos)); { DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n", pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3] ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7])); } pAd->bForcePrintTX = TRUE; BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); /*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));*/ return; } /* Increase Total transmit byte counter*/ pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount; pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount; pLastTxInfo = pTxInfo; #if !defined(CONFIG_MULTI_CHANNEL) && !defined(DOT11Z_TDLS_SUPPORT) /* Make sure we use EDCA QUEUE. */ pTxInfo->QSEL = FIFO_EDCA; #endif /* !defined(CONFIG_MULTI_CHANNEL) && !defined(DOT11Z_TDLS_SUPPORT) */ ThisBulkSize += (pTxInfo->USBDMATxPktLen+4); TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4); if (TmpBulkEndPos != pHTTXContext->CurWritePosition) pTxInfo->USBDMANextVLD = 1; #ifdef USB_BULK_BUF_ALIGMENT /* this is for frag packet , because it will finish this section when ((((pHTTXContext->CurWritePosition + 3906)& 0x00007fff) & 0xffff6000) == 0x00006000) */ if (pTxInfo->SwRingUseLastRound == 1) { bLasAlignmentsectiontRound = TRUE; #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); #endif /* RT_BIG_ENDIAN */ break; } #else if (pTxInfo->SwRingUseLastRound == 1) { if (pHTTXContext->CurWritePosition == 8) pTxInfo->USBDMANextVLD = 0; pTxInfo->SwRingUseLastRound = 0; bTxQLastRound = TRUE; pHTTXContext->ENextBulkOutPosition = 8; #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); #endif /* RT_BIG_ENDIAN */ break; } #endif /* USB_BULK_BUF_ALIGMENT */ #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO); RTMPWIEndianChange(pAd, (PUCHAR)pTxWI, TYPE_TXWI); #endif /* RT_BIG_ENDIAN */ }while (TRUE); /* adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.*/ if (pLastTxInfo) { #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO); #endif /* RT_BIG_ENDIAN */ pLastTxInfo->USBDMANextVLD = 0; #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO); #endif /* RT_BIG_ENDIAN */ } /* We need to copy SavedPad when following condition matched! 1. Not the last round of the TxQueue and 2. any match of following cases: (1). The End Position of this bulk out is reach to the Currenct Write position and the TxInfo and related header already write to the CurWritePosition. =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition) (2). The EndPosition of the bulk out is not reach to the Current Write Position. =>(ENextBulkOutPosition != CurWritePosition) */ #ifndef USB_BULK_BUF_ALIGMENT if ((bTxQLastRound == FALSE) && (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) || (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition)) ) { NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8); pHTTXContext->bCopySavePad = TRUE; if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4)) { PUCHAR pBuf = &pHTTXContext->SavedPad[0]; DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize)); pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition]; DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7])); } /*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));*/ } #endif /* USB_BULK_BUF_ALIGMENT */ if (pAd->bForcePrintTX == TRUE) DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); /*DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));*/ /* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.*/ pAppendant = &pWirelessPkt[TmpBulkEndPos]; NdisZeroMemory(pAppendant, 8); ThisBulkSize += 4; pHTTXContext->LastOne = TRUE; pHTTXContext->BulkOutSize = ThisBulkSize; #ifdef USB_BULK_BUF_ALIGMENT /* if it is the last alignment section round,that we just need to add nextbulkindex, otherwise we both need to add nextbulkindex and CurWriteIdx (because when alignment section round happened, the CurWriteIdx is added at function writing resource.) */ if(bLasAlignmentsectiontRound == TRUE) { CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE); pHTTXContext->ENextBulkOutPosition = 0; } else { CUR_WRITE_IDX_INC(pHTTXContext->NextBulkIdx, BUF_ALIGMENT_RINGSIZE); pHTTXContext->ENextBulkOutPosition = 0; CUR_WRITE_IDX_INC(pHTTXContext->CurWriteIdx, BUF_ALIGMENT_RINGSIZE); pHTTXContext->CurWritePosition = 0; } #endif /* USB_BULK_BUF_ALIGMENT */ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1; BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2); /* Init Tx context descriptor*/ RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RtmpUsbBulkOutDataPacketComplete); #ifdef USB_BULK_BUF_ALIGMENT pUrb = pHTTXContext->pUrb[pHTTXContext->CurtBulkIdx]; #else pUrb = pHTTXContext->pUrb; #endif /* USB_BULK_BUF_ALIGMENT */ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0) { DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret)); BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutPending[BulkOutPipeId] = FALSE; pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); return; } BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pHTTXContext->IRPPending = TRUE; BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); pAd->BulkOutReq++; }
VOID RTMPHandleSTAKey( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN MLME_QUEUE_ELEM *Elem) { extern UCHAR OUI_WPA2_WEP40[]; ULONG FrameLen = 0; PUCHAR pOutBuffer = NULL; UCHAR Header802_3[14]; UCHAR *mpool; PEAPOL_PACKET pOutPacket; PEAPOL_PACKET pSTAKey; PHEADER_802_11 pHeader; UCHAR Offset = 0; ULONG MICMsgLen; UCHAR DA[MAC_ADDR_LEN]; UCHAR Key_Data[512]; UCHAR key_length; UCHAR mic[LEN_KEY_DESC_MIC]; UCHAR rcv_mic[LEN_KEY_DESC_MIC]; UCHAR digest[80]; UCHAR temp[64]; PMAC_TABLE_ENTRY pDaEntry; /*Benson add for big-endian 20081016--> */ KEY_INFO peerKeyInfo; /*Benson add 20081016 <-- */ DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleSTAKey\n")); if (!pEntry) return; if ((pEntry->WpaState != AS_PTKINITDONE)) { DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here")); return; } pHeader = (PHEADER_802_11) Elem->Msg; /* QoS control field (2B) is took off */ /* if (pHeader->FC.SubType & 0x08) */ /* Offset += 2; */ pSTAKey = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + Offset]; /*Benson add for big-endian 20081016--> */ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo)); NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pSTAKey->KeyDesc.KeyInfo, sizeof(KEY_INFO)); *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo)); /*Benson add 20081016 <-- */ /* Check Replay Counter */ if (!RTMPEqualMemory(pSTAKey->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY)) { DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in STAKey handshake!! \n")); DBGPRINT(RT_DEBUG_ERROR, ("Receive : %d %d %d %d \n", pSTAKey->KeyDesc.ReplayCounter[0], pSTAKey->KeyDesc.ReplayCounter[1], pSTAKey->KeyDesc.ReplayCounter[2], pSTAKey->KeyDesc.ReplayCounter[3])); DBGPRINT(RT_DEBUG_ERROR, ("Current : %d %d %d %d \n", pEntry->R_Counter[4],pEntry->R_Counter[5], pEntry->R_Counter[6],pEntry->R_Counter[7])); return; } /* Check MIC, if not valid, discard silently */ NdisMoveMemory(DA, &pSTAKey->KeyDesc.KeyData[6], MAC_ADDR_LEN); if (peerKeyInfo.KeyMic && peerKeyInfo.Secure && peerKeyInfo.Request)/*Benson add for big-endian 20081016 --> */ { pEntry->bDlsInit = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("STAKey Initiator: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pEntry->Addr))); } MICMsgLen = pSTAKey->Body_Len[1] | ((pSTAKey->Body_Len[0]<<8) && 0xff00); MICMsgLen += LENGTH_EAPOL_H; if (MICMsgLen > (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H)) { DBGPRINT(RT_DEBUG_ERROR, ("Receive wrong format EAPOL packets \n")); return; } /* This is proprietary DLS protocol, it will be adhered when spec. is finished. */ NdisZeroMemory(temp, 64); NdisZeroMemory(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, sizeof(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK)); NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, temp, pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK); DBGPRINT(RT_DEBUG_TRACE, ("PTK-%x %x %x %x %x %x %x %x \n", pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7])); /* Record the received MIC for check later */ NdisMoveMemory(rcv_mic, pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); NdisZeroMemory(pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); if (pEntry->WepStatus == Ndis802_11TKIPEnable) { RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey, MICMsgLen, mic, MD5_DIGEST_SIZE); } else { RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey, MICMsgLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); } if (!RTMPEqualMemory(rcv_mic, mic, LEN_KEY_DESC_MIC)) { DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in STAKey handshake!! \n")); return; } else DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in STAKey handshake!! \n")); /* Receive init STA's STAKey Message-2, and terminate the handshake */ /*if (pEntry->bDlsInit && !pSTAKey->KeyDesc.KeyInfo.Request) */ if (pEntry->bDlsInit && !peerKeyInfo.Request) /*Benson add for big-endian 20081016 --> */ { pEntry->bDlsInit = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("Receive init STA's STAKey Message-2, STAKey handshake finished \n")); return; } /* Receive init STA's STAKey Message-2, and terminate the handshake */ if (RTMPEqualMemory(&pSTAKey->KeyDesc.KeyData[2], OUI_WPA2_WEP40, 3)) { DBGPRINT(RT_DEBUG_WARN, ("Receive a STAKey message which not support currently, just drop it \n")); return; } do { pDaEntry = MacTableLookup(pAd, DA); if (!pDaEntry) break; if ((pDaEntry->WpaState != AS_PTKINITDONE)) { DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here \n")); break; } MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); /* allocate memory */ if(pOutBuffer == NULL) break; MAKE_802_3_HEADER(Header802_3, pDaEntry->Addr, pAd->ApCfg.MBSSID[pDaEntry->apidx].wdev.bssid, EAPOL); /* Increment replay counter by 1 */ ADD_ONE_To_64BIT_VAR(pDaEntry->R_Counter); /* Allocate memory for output */ os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER); if (mpool == NULL) { MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__)); return; } pOutPacket = (PEAPOL_PACKET)mpool; NdisZeroMemory(pOutPacket, TX_EAPOL_BUFFER); /* 0. init Packet and Fill header */ pOutPacket->ProVer = EAPOL_VER; pOutPacket->ProType = EAPOLKey; pOutPacket->Body_Len[1] = 0x5f; /* 1. Fill replay counter */ /* NdisMoveMemory(pDaEntry->R_Counter, pAd->ApCfg.R_Counter, sizeof(pDaEntry->R_Counter)); */ NdisMoveMemory(pOutPacket->KeyDesc.ReplayCounter, pDaEntry->R_Counter, LEN_KEY_DESC_REPLAY); /* 2. Fill key version, keyinfo, key len */ pOutPacket->KeyDesc.KeyInfo.KeyDescVer= GROUP_KEY; pOutPacket->KeyDesc.KeyInfo.KeyType = GROUPKEY; pOutPacket->KeyDesc.KeyInfo.Install = 1; pOutPacket->KeyDesc.KeyInfo.KeyAck = 1; pOutPacket->KeyDesc.KeyInfo.KeyMic = 1; pOutPacket->KeyDesc.KeyInfo.Secure = 1; pOutPacket->KeyDesc.KeyInfo.EKD_DL = 1; DBGPRINT(RT_DEBUG_TRACE, ("STAKey handshake for peer STA %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(DA))); if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPAPSK)) { pOutPacket->KeyDesc.Type = WPA1_KEY_DESC; DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA/WPAPSK\n")); } else if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) { pOutPacket->KeyDesc.Type = WPA2_KEY_DESC; pOutPacket->KeyDesc.KeyDataLen[1] = 0; DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA2/WPA2PSK\n")); } pOutPacket->KeyDesc.KeyLength[1] = LEN_TKIP_TK; pOutPacket->KeyDesc.KeyDataLen[1] = LEN_TKIP_TK; pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_TKIP; if (pDaEntry->WepStatus == Ndis802_11AESEnable) { pOutPacket->KeyDesc.KeyLength[1] = LEN_AES_TK; pOutPacket->KeyDesc.KeyDataLen[1] = LEN_AES_TK; pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_AES; } /* Key Data Encapsulation format, use Ralink OUI to distinguish proprietary and standard. */ Key_Data[0] = 0xDD; Key_Data[1] = 0x00; /* Length (This field will be filled later) */ Key_Data[2] = 0x00; /* OUI */ Key_Data[3] = 0x0C; /* OUI */ Key_Data[4] = 0x43; /* OUI */ Key_Data[5] = 0x02; /* Data Type (STAKey Key Data Encryption) */ /* STAKey Data Encapsulation format */ Key_Data[6] = 0x00; /*Reserved */ Key_Data[7] = 0x00; /*Reserved */ /* STAKey MAC address */ NdisMoveMemory(&Key_Data[8], pEntry->Addr, MAC_ADDR_LEN); /* initiator MAC address */ /* STAKey (Handle the difference between TKIP and AES-CCMP) */ if (pDaEntry->WepStatus == Ndis802_11AESEnable) { Key_Data[1] = 0x1E; /* 4+2+6+16(OUI+Reserved+STAKey_MAC_Addr+STAKey) */ NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_AES_TK); } else { Key_Data[1] = 0x2E; /* 4+2+6+32(OUI+Reserved+STAKey_MAC_Addr+STAKey) */ NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_TK); NdisMoveMemory(&Key_Data[14+LEN_TK], pEntry->PairwiseKey.TxMic, LEN_TKIP_MIC); NdisMoveMemory(&Key_Data[14+LEN_TK+LEN_TKIP_MIC], pEntry->PairwiseKey.RxMic, LEN_TKIP_MIC); } key_length = Key_Data[1]; pOutPacket->Body_Len[1] = key_length + 0x5f; /* This is proprietary DLS protocol, it will be adhered when spec. is finished. */ NdisZeroMemory(temp, 64); NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, temp, DA, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK); DBGPRINT(RT_DEBUG_TRACE, ("PTK-0-%x %x %x %x %x %x %x %x \n", pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6], pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7])); NdisMoveMemory(pOutPacket->KeyDesc.KeyData, Key_Data, key_length); NdisZeroMemory(mic, sizeof(mic)); *(USHORT *)(&pOutPacket->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pOutPacket->KeyDesc.KeyInfo)); MakeOutgoingFrame(pOutBuffer, &FrameLen, pOutPacket->Body_Len[1] + 4, pOutPacket, END_OF_ARGS); /* Calculate MIC */ if (pDaEntry->WepStatus == Ndis802_11AESEnable) { RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC); } else { RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, mic, MD5_DIGEST_SIZE); NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC); } RTMPToWirelessSta(pAd, pDaEntry, Header802_3, LENGTH_802_3, (PUCHAR)pOutPacket, pOutPacket->Body_Len[1] + 4, FALSE); MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); os_free_mem(NULL, mpool); }while(FALSE); DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleSTAKey: FrameLen=%ld\n", FrameLen)); }