/* ======================================================================== Routine Description: Arguments: Return Value: Note: ======================================================================== */ BOOLEAN PMF_PerformRxFrameAction( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk) { INT FrameType; PUCHAR pMgmtFrame; UINT mgmt_len; PRXWI_STRUC pRxWI = pRxBlk->pRxWI; PHEADER_802_11 pHeader = pRxBlk->pHeader; PMAC_TABLE_ENTRY pEntry = NULL; pMgmtFrame = (PUCHAR)pHeader; mgmt_len = pRxWI->MPDUtotalByteCount; #ifdef CONFIG_AP_SUPPORT pEntry = MacTableLookup(pAd, pHeader->Addr2); #endif /* CONFIG_AP_SUPPORT */ FrameType = PMF_RobustFrameClassify(pHeader, (PUCHAR)(pMgmtFrame + LENGTH_802_11), (mgmt_len - LENGTH_802_11), (PUCHAR) pEntry, TRUE); switch (FrameType) { case ERROR_FRAME: DBGPRINT(RT_DEBUG_ERROR, ("[PMF]%s: ERROR FRAME\n", __FUNCTION__)); return FALSE; #ifdef CONFIG_AP_SUPPORT case NORMAL_FRAME: case NOT_ROBUST_GROUP_FRAME: break; case NOT_ROBUST_UNICAST_FRAME: DBGPRINT(RT_DEBUG_ERROR, ("[PMF]%s: ERROR FRAME\n", __FUNCTION__)); return FALSE; #endif /* CONFIG_AP_SUPPORT */ case UNICAST_ROBUST_FRAME: { if (PMF_DecryptUniRobustFrameAction(pAd, pMgmtFrame, mgmt_len) != PMF_STATUS_SUCCESS) return FALSE; /* update the total length */ pRxWI->MPDUtotalByteCount -= (LEN_CCMP_HDR + LEN_CCMP_MIC); break; } case GROUP_ROBUST_FRAME: { if (PMF_ExtractBIPAction(pAd, pMgmtFrame, mgmt_len) != PMF_STATUS_SUCCESS) return FALSE; /* update the total length */ pRxWI->MPDUtotalByteCount -= (2 + LEN_PMF_MMIE); break; } } return TRUE; }
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)); } }
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; }
/* ======================================================================== Routine Description: Check if ASIC can go to sleep mode. Arguments: pAd - WLAN control block pointer PsmOld - Current power save mode PsmNew - New power save mode Return Value: None Note: ======================================================================== */ VOID TDLS_UAPSDP_PsmModeChange( IN PRTMP_ADAPTER pAd, IN USHORT PsmOld, IN USHORT PsmNew) { MAC_TABLE_ENTRY *pMacEntry; RT_802_11_TDLS *pTDLS; UINT32 IdTdls; if (PsmOld == PsmNew) return; /* no inform needs */ /* sanity check */ /* WPA 802.1x secured port control */ if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) #ifdef WPA_SUPPLICANT_SUPPORT || (pAd->StaCfg.IEEE8021X == TRUE) #endif ) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) { return; /* port not yet secure */ } DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> our PSM mode change!\n")); /* indicate the peer */ TDLS_SEMLOCK(pAd); for(IdTdls=0; IdTdls<MAX_NUM_OF_TDLS_ENTRY; IdTdls++) { pTDLS = (RT_802_11_TDLS *) &pAd->StaCfg.TdlsInfo.TDLSEntry[IdTdls]; if ((pTDLS->Valid) && (pTDLS->Status == TDLS_MODE_CONNECTED)) { /* get MAC Entry */ pMacEntry = MacTableLookup(pAd, pTDLS->MacAddr); if (pMacEntry == NULL) continue; /* check next one */ /* check if the peer is in ACTIVE mode */ if (TDLS_UAPSD_ARE_PEER_IN_ACTIVE(pMacEntry)) { /* pMacEntry->RssiSample.LastRssi0 is used to check if we have ever received any packet from the peer. */ /* send a null frame to the peer directly */ DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> send a NULL frame!\n")); RtmpEnqueueNullFrame(pAd, pMacEntry->Addr, pAd->CommonCfg.TxRate, pMacEntry->Aid, pMacEntry->apidx, TRUE, FALSE, 0); continue; } /* Send traffic indication frame to the peer when the peer is in power-save mode. */ TDLS_UAPSD_TrafficIndSend(pAd, pMacEntry->Addr); } } TDLS_SEMUNLOCK(pAd); }
/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ========================================================================== */ VOID PeerDeauthAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM Elem) { UCHAR Addr1[MAC_ADDR_LEN]; UCHAR Addr2[MAC_ADDR_LEN]; UCHAR Addr3[MAC_ADDR_LEN]; USHORT Reason; BOOLEAN bDoIterate = FALSE; if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, Addr3, &Reason)) { if (INFRA_ON(pAd) && (MAC_ADDR_EQUAL(Addr1, pAd->CurrentAddress) || MAC_ADDR_EQUAL(Addr1, BROADCAST_ADDR)) && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid) && MAC_ADDR_EQUAL(Addr3, pAd->CommonCfg.Bssid) ) { DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason)); if (Reason == REASON_4_WAY_TIMEOUT) RTMPSendWirelessEvent(pAd, IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG, NULL, 0, 0); if (Reason == REASON_GROUP_KEY_HS_TIMEOUT) RTMPSendWirelessEvent(pAd, IW_GROUP_HS_TIMEOUT_EVENT_FLAG, NULL, 0, 0); #ifdef WAPI_SUPPORT WAPI_InternalCmdAction(pAd, pAd->StaCfg.AuthMode, BSS0, Addr2, WAI_MLME_DISCONNECT); #endif // WAPI_SUPPORT // #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CGIWAP, -1, NULL, NULL, 0); #endif // NATIVE_WPA_SUPPLICANT_SUPPORT // // send wireless event - for deauthentication RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, NULL, BSS0, 0); #ifdef WPA_SUPPLICANT_SUPPORT if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) pAd->StaCfg.bLostAp = TRUE; #endif // WPA_SUPPLICANT_SUPPORT // /* Some customer would set AP1 & AP2 same SSID, AuthMode & EncrypType but different WPAPSK, therefore we need to do iterate here. */ if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) && ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) #ifdef WSC_STA_SUPPORT && (pAd->StaCfg.WscControl.WscState < WSC_STATE_LINK_UP) #endif // WSC_STA_SUPPORT // ) bDoIterate = TRUE; LinkDown(pAd, TRUE); if (bDoIterate) { pAd->MlmeAux.BssIdx++; IterateOnBssTab(pAd); } } #ifdef ADHOC_WPA2PSK_SUPPORT else if (ADHOC_ON(pAd) && (MAC_ADDR_EQUAL(Addr1, pAd->CurrentAddress) || MAC_ADDR_EQUAL(Addr1, BROADCAST_ADDR))) { MAC_TABLE_ENTRY *pEntry; pEntry = MacTableLookup(pAd, Addr2); if (pEntry && IS_ENTRY_CLIENT(pEntry)) MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from %02x:%02x:%02x:%02x:%02x:%02x \n", PRINT_MAC(Addr2))); } #endif // ADHOC_WPA2PSK_SUPPORT // } else { DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n")); } }
/* ========================================================================== Description: Process the received ProbeRequest from clients Parameters: Elem - msg containing the ProbeReq frame ========================================================================== */ VOID APPeerProbeReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Addr2[MAC_ADDR_LEN]; CHAR Ssid[MAX_LEN_OF_SSID]; UCHAR SsidLen; //, Rates[MAX_LEN_OF_SUPPORTED_RATES], RatesLen; HEADER_802_11 ProbeRspHdr; NDIS_STATUS NStatus; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0, TmpLen; LARGE_INTEGER FakeTimestamp; UCHAR DsLen = 1;//, IbssLen = 2, TimLen=1, //BitmapControl=0, VirtualBitmap=0; UCHAR ErpIeLen = 1; UCHAR apidx = 0; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2;//, RSN_Len=22; BOOLEAN bRequestRssi=FALSE; #ifdef WSC_AP_SUPPORT UCHAR Addr3[MAC_ADDR_LEN]; PFRAME_802_11 pFrame = (PFRAME_802_11)Elem->Msg; COPY_MAC_ADDR(Addr3, pFrame->Hdr.Addr3); #endif // WSC_AP_SUPPORT // #ifdef WDS_SUPPORT // if in bridge mode, no need to reply probe req. if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE) return; #endif // WDS_SUPPORT // if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen, &bRequestRssi)) return; for(apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++) { RSNIe = IE_WPA; if ((pAd->ApCfg.MBSSID[apidx].MSSIDDev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].MSSIDDev))) { /* the interface is down, so we can not send probe response */ continue; } /* End of if */ if (((SsidLen == 0) && (! pAd->ApCfg.MBSSID[apidx].bHideSsid)) || #ifdef WSC_AP_SUPPORT /* buffalo WPS testbed STA send ProbrRequest ssid length = 32 and ssid are not AP , but DA are AP. for WPS test send ProbeResponse */ ((SsidLen == 32) && MAC_ADDR_EQUAL(Addr3, pAd->ApCfg.MBSSID[apidx].Bssid) && (pAd->ApCfg.MBSSID[apidx].bHideSsid == 0)) || #endif // WSC_AP_SUPPORT // ((SsidLen == pAd->ApCfg.MBSSID[apidx].SsidLen) && NdisEqualMemory(Ssid, pAd->ApCfg.MBSSID[apidx].Ssid, (ULONG) SsidLen))) ; else continue; /* check next BSS */ // allocate and send out ProbeRsp frame NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, pAd->ApCfg.MBSSID[apidx].Bssid); if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; #ifdef WAPI_SUPPORT else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAICERT) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAIPSK)) RSNIe = IE_WAPI; #endif // WAPI_SUPPORT // MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &ProbeRspHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &pAd->ApCfg.MBSSID[apidx].CapabilityInfo, 1, &SsidIe, 1, &pAd->ApCfg.MBSSID[apidx].SsidLen, pAd->ApCfg.MBSSID[apidx].SsidLen, pAd->ApCfg.MBSSID[apidx].Ssid, 1, &SupRateIe, 1, &pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); if (pAd->CommonCfg.ExtRateLen) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ErpIe, 1, &ErpIeLen, 1, &pAd->ApCfg.ErpIeContent, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } #ifdef A_BAND_SUPPORT // add Channel switch announcement IE if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->CommonCfg.RadarDetect.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->CommonCfg.RadarDetect.CSCount, END_OF_ARGS); FrameLen += TmpLen; } #endif // A_BAND_SUPPORT // #ifdef DOT11_N_SUPPORT if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen, NewExtLen; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif #ifdef A_BAND_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement && (pAd->CommonCfg.Channel > 14)) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); FrameLen += TmpLen; } #endif // A_BAND_SUPPORT // HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); NewExtLen = 1; //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability, 1, &AddHtInfoIe, 1, &AddHtLen, sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo, 1, &NewExtChanIe, 1, &NewExtLen, sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif // UNALIGNMENT_SUPPORT // NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &AddHtLen, AddHtLen, &addHTInfoTmp, 1, &NewExtChanIe, 1, &NewExtLen, sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset, END_OF_ARGS); #endif FrameLen += TmpLen; } #endif // DOT11_N_SUPPORT // // Append RSN_IE when WPA OR WPAPSK, if (pAd->ApCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA) ; // enough information else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0], 1, &RSNIe2, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1], pAd->ApCfg.MBSSID[apidx].RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } // add WMM IE here if (pAd->ApCfg.MBSSID[apidx].bWmmCapable) { UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_AP_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], pAd); #endif // UAPSD_AP_SUPPORT // for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + // b5-6 is ACI ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + // b4 is ACM (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f); // b0-3 is AIFSN WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + // b5-8 is CWMAX (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); // b0-3 is CWMIN WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); // low byte of TXOP WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); // high byte of TXOP } MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->FlgQloadEnable != 0) { FrameLen += QBSS_LoadElementAppend(pAd, pOutBuffer+FrameLen); } #endif // AP_QLOAD_SUPPORT // #ifdef DOT11K_RRM_SUPPORT if (IS_RRM_ENABLE(pAd, apidx)) { // add country IE, power constraint IE if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen, TmpLen2=0; UCHAR TmpFrame[256]; UCHAR CountryIe = IE_COUNTRY; NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); // prepare channel information #ifdef EXT_BUILD_CHANNEL_LIST BuildBeaconChList(pAd, TmpFrame, &TmpLen2); #else { UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel); MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; } #endif // EXT_BUILD_CHANNEL_LIST // #ifdef DOT11K_RRM_SUPPORT if (IS_RRM_ENABLE(pAd, apidx) && (pAd->CommonCfg.RegulatoryClass[0] != 0)) { TmpLen2 = 0; NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); RguClass_BuildBcnChList(pAd, TmpFrame, &TmpLen2); } #endif // DOT11K_RRM_SUPPORT // // need to do the padding bit check, and concatenate it if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pOutBuffer+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pOutBuffer+FrameLen,&TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; } InsertTpcReportIE(pAd, pOutBuffer+FrameLen, &FrameLen, RTMP_GetTxPwr(pAd, pAd->CommonCfg.MlmeTransmit), 0); RRM_InsertRRMEnCapIE(pAd, pOutBuffer+FrameLen, &FrameLen, apidx); } { INT loop; for (loop=0; loop<MAX_NUM_OF_REGULATORY_CLASS; loop++) { if (pAd->CommonCfg.RegulatoryClass[loop] == 0) break; InsertChannelRepIE(pAd, pOutBuffer+FrameLen, &FrameLen, (PSTRING)pAd->CommonCfg.CountryCode, pAd->CommonCfg.RegulatoryClass[loop]); } } /* Insert BSS AC Access Delay IE. */ RRM_InsertBssACDelayIE(pAd, pOutBuffer+FrameLen, &FrameLen); /* Insert BSS Available Access Capacity IE. */ RRM_InsertBssAvailableACIE(pAd, pOutBuffer+FrameLen, &FrameLen); #endif // DOT11K_RRM_SUPPORT // #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 // P802.11n_D3.03 // 7.3.2.60 Overlapping BSS Scan Parameters IE if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pAd->CommonCfg.Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pAd->CommonCfg.Dot11OBssScanActivityThre); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } // 7.3.2.27 Extended Capabilities IE { ULONG TmpLen; EXT_CAP_INFO_ELEMENT extCapInfo; UCHAR extInfoLen; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); // P802.11n_D1.10 // HT Information Exchange Support if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { extCapInfo.BssCoexistMgmtSupport = 1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #endif // DOT11N_DRAFT3 // #endif // DOT11_N_SUPPORT // /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back Byte0.b3=1 for rssi-feedback */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pAd->CommonCfg.bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pAd->CommonCfg.bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bRdg) RalinkSpecificIe[5] |= 0x4; #endif // DOT11_N_SUPPORT // #ifdef RSSI_FEEDBACK if (bRequestRssi == TRUE) { MAC_TABLE_ENTRY *pEntry=NULL; DBGPRINT(RT_DEBUG_ERROR, ("SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5] )); RalinkSpecificIe[5] |= 0x8; pEntry = MacTableLookup(pAd, Addr2); if (pEntry != NULL) { RalinkSpecificIe[6] = (UCHAR)pEntry->RssiSample.AvgRssi0; RalinkSpecificIe[7] = (UCHAR)pEntry->RssiSample.AvgRssi1; RalinkSpecificIe[8] = (UCHAR)pEntry->RssiSample.AvgRssi2; } } #endif // RSSI_FEEDBACK // MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef A_BAND_SUPPORT // add Channel switch announcement IE if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->CommonCfg.RadarDetect.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->CommonCfg.RadarDetect.CSCount, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); } #endif // DOT11_N_SUPPORT // FrameLen += TmpLen; } #endif // A_BAND_SUPPORT // // add country IE, power constraint IE if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen2=0; UCHAR TmpFrame[256]; UCHAR CountryIe = IE_COUNTRY; UCHAR MaxTxPower=16; #ifdef A_BAND_SUPPORT // Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) // in beacons and probe response frames if (pAd->CommonCfg.Channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) { // prepare power constraint IE MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 3, PowerConstraintIE, END_OF_ARGS); FrameLen += TmpLen; } #endif // A_BAND_SUPPORT // NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); // prepare channel information MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; // need to do the padding bit check, and concatenate it if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; }// Country IE - #ifdef DOT11_N_SUPPORT if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen;//, NewExtLen; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif // UNALIGNMENT_SUPPORT // MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = AddHtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } } #endif // DOT11_N_SUPPORT // #ifdef WSC_AP_SUPPORT /* for windows 7 logo test */ if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE) && #ifdef DOT1X_SUPPORT (pAd->ApCfg.MBSSID[apidx].IEEE8021X == FALSE) && #endif // DOT1X_SUPPORT // (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled)) { /* Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">> A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network. The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero) http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp */ ULONG TempLen1 = 0; UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00}; MakeOutgoingFrame(pOutBuffer+FrameLen, &TempLen1, 7, PROVISION_SERVICE_IE, END_OF_ARGS); FrameLen += TempLen1; } // add Simple Config Information Element if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode > WSC_DISABLE) && (pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen)) { ULONG WscTmpLen = 0; MakeOutgoingFrame(pOutBuffer+FrameLen, &WscTmpLen, pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen, pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.Value, END_OF_ARGS); FrameLen += WscTmpLen; } #endif // WSC_AP_SUPPORT // #ifdef DOT11R_FT_SUPPORT /* The Mobility Domain information element (MDIE) is present in Probe- ** Request frame when dot11FastBssTransitionEnable is set to true. */ if (pAd->ApCfg.MBSSID[apidx].FtCfg.FtCapFlag.Dot11rFtEnable) { PFT_CFG pFtCfg = &pAd->ApCfg.MBSSID[apidx].FtCfg; FT_CAP_AND_POLICY FtCap; FtCap.field.FtOverDs = pFtCfg->FtCapFlag.FtOverDs; FtCap.field.RsrReqCap = pFtCfg->FtCapFlag.RsrReqCap; FT_InsertMdIE(pAd, pOutBuffer + FrameLen, &FrameLen, pFtCfg->FtMdId, FtCap); } #endif // DOT11R_FT_SUPPORT // // 802.11n 11.1.3.2.2 active scanning. sending probe response with MCS rate is MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }
VOID PeerBeacon( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; CHAR Ssid[MAX_LEN_OF_SSID]; CF_PARM CfParm; UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0; UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0; USHORT CapabilityInfo, AtimWin, BeaconPeriod; LARGE_INTEGER TimeStamp; USHORT TbttNumToNextWakeUp; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; UCHAR CkipFlag; USHORT LenVIE; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; ULONG RalinkIe; UCHAR VarIE[MAX_VIE_LEN]; NDIS_802_11_VARIABLE_IEs *pVIE = NULL; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; UCHAR HtCapabilityLen, PreNHtCapabilityLen; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; #ifdef RALINK_ATE if (ATE_ON(pAd)) { return; } #endif if (!(INFRA_ON(pAd) || ADHOC_ON(pAd) )) return; pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; RTMPZeroMemory(&HtCapability, sizeof(HtCapability)); RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE)); if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Elem->Channel, Addr2, Bssid, Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &CfParm, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &HtCapabilityLen, &PreNHtCapabilityLen, &HtCapability, &AddHtInfoLen, &AddHtInfo, &NewExtChannelOffset, &LenVIE, pVIE)) { BOOLEAN is_my_bssid, is_my_ssid; ULONG Bssidx, Now; BSS_ENTRY *pBss; CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE; is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE; if ((! is_my_ssid) && (! is_my_bssid)) return; if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC) return; #ifdef DOT11_N_SUPPORT if (AddHtInfoLen != 0) Channel = AddHtInfo.ControlChan; if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) HtCapabilityLen = SIZE_HT_CAP_IE; #endif Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); if (Bssidx == BSS_NOT_FOUND) { Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel, RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) return; NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); } if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel)) { AsicSwitchChannel(pAd, 1, FALSE); AsicLockChannel(pAd, 1); LinkDown(pAd, FALSE); MlmeQueueInit(&pAd->Mlme.Queue); BssTableInit(&pAd->ScanTab); RTMPusecDelay(1000000); for (index = 0 ; index < pAd->ChannelListNum; index++) { if (pAd->ChannelList[index].Channel == NewChannel) { pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel; pAd->CommonCfg.Channel = NewChannel; AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel)); break; } } if (index >= pAd->ChannelListNum) { DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum)); } } if ((! is_my_bssid) && ADHOC_ON(pAd)) { INT i; if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus) { return; } for (i = 0; i < 6; i++) { if (Bssid[i] > pAd->CommonCfg.Bssid[i]) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n", Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5])); AsicDisableSync(pAd); COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid); AsicSetBssid(pAd, pAd->CommonCfg.Bssid); MakeIbssBeacon(pAd); AsicEnableIbssSync(pAd); is_my_bssid = TRUE; break; } else if (Bssid[i] < pAd->CommonCfg.Bssid[i]) break; } } NdisGetSystemUpTime(&Now); pBss = &pAd->ScanTab.BssEntry[Bssidx]; pBss->Rssi = RealRssi; pBss->LastBeaconRxTime = Now; if (is_my_bssid) { RXWI_STRUC RxWI; pAd->StaCfg.DtimCount = DtimCount; pAd->StaCfg.DtimPeriod = DtimPeriod; pAd->StaCfg.LastBeaconRxTime = Now; RxWI.RSSI0 = Elem->Rssi0; RxWI.RSSI1 = Elem->Rssi1; RxWI.RSSI2 = Elem->Rssi2; Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI); if (AironetCellPowerLimit != 0xFF) { ChangeToCellPowerLimit(pAd, AironetCellPowerLimit); } else { pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; } if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) { UCHAR MaxSupportedRateIn500Kbps = 0; UCHAR idx; MAC_TABLE_ENTRY *pEntry; for (idx=0; idx<SupRateLen; idx++) { if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f)) MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f; } for (idx=0; idx<ExtRateLen; idx++) { if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f)) MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f; } pEntry = MacTableLookup(pAd, Addr2); if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) || (pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now))) { if (pEntry == NULL) pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE); if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, &AddHtInfo, AddHtInfoLen, CapabilityInfo) == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n")); return; } if (pEntry && (Elem->Wcid == RESERVED_WCID)) { idx = pAd->StaCfg.DefaultKeyId; RTMP_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry); } } if (pEntry && pEntry->ValidAsCLI) pEntry->LastBeaconRxTime = Now; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); pAd->IndicateMediaState = NdisMediaStateConnected; RTMP_IndicateMediaState(pAd); pAd->ExtraInfo = GENERAL_LINK_UP; AsicSetBssid(pAd, pAd->CommonCfg.Bssid); Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); if (Bssidx == BSS_NOT_FOUND) { Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); } DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n")); } } if (INFRA_ON(pAd)) { BOOLEAN bUseShortSlot, bUseBGProtection; bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo); if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) AsicSetSlotTime(pAd, bUseShortSlot); bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp)); if (pAd->CommonCfg.Channel > 14) bUseBGProtection = FALSE; if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { if (bUseBGProtection) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); } else { OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)); } DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection)); } #ifdef DOT11_N_SUPPORT if ((AddHtInfoLen != 0) && ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) || (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent))) { pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent; pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode; if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) { AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE); } else AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode)); } #endif if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) && ERP_IS_USE_BARKER_PREAMBLE(Erp)) { MlmeSetTxPreamble(pAd, Rt802_11PreambleLong); DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n")); } if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (EdcaParm.bValid == TRUE) && (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount)) { DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n", pAd->CommonCfg.APEdcaParm.EdcaUpdateCount, EdcaParm.EdcaUpdateCount)); AsicSetEdcaParm(pAd, &EdcaParm); } NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave)) { UCHAR FreeNumber; if (MessageToMe) { #ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO) { pAd->CommonCfg.bNeedSendTriggerFrame = TRUE; } else RTMP_PS_POLL_ENQUEUE(pAd); } else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM)) { #ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif } else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) || (pAd->TxSwQueue[QID_AC_BE].Number != 0) || (pAd->TxSwQueue[QID_AC_VI].Number != 0) || (pAd->TxSwQueue[QID_AC_VO].Number != 0) || (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) || (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)) { #ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) { if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } #endif } else { if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) || (pAd->CommonCfg.bACMAPSDTr[QID_AC_BE])) { } else { USHORT NextDtim = DtimCount; if (NextDtim == 0) NextDtim = DtimPeriod; TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount; if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim)) TbttNumToNextWakeUp = NextDtim; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp; AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp); } } } } } } }
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)); }
int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd, u8 QueIdx, void *pPacket) { struct rt_packet_info PacketInfo; u8 *pSrcBufVA; u32 SrcBufLen; struct rt_txd * pTxD; struct rt_header_802_11 * pHeader_802_11; BOOLEAN bAckRequired, bInsertTimestamp; unsigned long SrcBufPA; /*u8 TxBufIdx; */ u8 MlmeRate; unsigned long SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; struct rt_txwi * pFirstTxWI; /*unsigned long i; */ /*HTTRANSMIT_SETTING MlmeTransmit; //Rate for this MGMT frame. */ unsigned long FreeNum; struct rt_mac_table_entry *pMacEntry = NULL; RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); if (pSrcBufVA == NULL) { /* The buffer shouldn't be NULL */ return NDIS_STATUS_FAILURE; } /* Make sure MGMT ring resource won't be used by other threads */ /*NdisAcquireSpinLock(&pAd->TxRingLock); */ FreeNum = GET_TXRING_FREENO(pAd, QueIdx); if (FreeNum == 0) { /*NdisReleaseSpinLock(&pAd->TxRingLock); */ return NDIS_STATUS_FAILURE; } SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; pTxD = (struct rt_txd *) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) { DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n")); /*NdisReleaseSpinLock(&pAd->TxRingLock); */ return NDIS_STATUS_FAILURE; } { /* outgoing frame always wakeup PHY to prevent frame lost */ /* if (pAd->StaCfg.Psm == PWR_SAVE) */ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) AsicForceWakeup(pAd, TRUE); } pFirstTxWI = (struct rt_txwi *) pSrcBufVA; pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXWI_SIZE); if (pHeader_802_11->Addr1[0] & 0x01) { MlmeRate = pAd->CommonCfg.BasicMlmeRate; } else { MlmeRate = pAd->CommonCfg.MlmeRate; } if ((pHeader_802_11->FC.Type == BTYPE_DATA) && (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) { pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); } /* Verify Mlme rate for a / g bands. */ if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) /* 11A band */ MlmeRate = RATE_6; /* */ /* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */ /* Snice it's been set to 0 while on MgtMacHeaderInit */ /* By the way this will cause frame to be send on PWR_SAVE failed. */ /* */ /* */ /* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */ /* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */ if (pHeader_802_11->FC.Type != BTYPE_DATA) { if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) { pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; } else { pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave; } } bInsertTimestamp = FALSE; if (pHeader_802_11->FC.Type == BTYPE_CNTL) /* must be PS-POLL */ { bAckRequired = FALSE; } else /* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */ { if (pHeader_802_11->Addr1[0] & 0x01) /* MULTICAST, BROADCAST */ { bAckRequired = FALSE; pHeader_802_11->Duration = 0; } else { bAckRequired = TRUE; pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) { bInsertTimestamp = TRUE; } } } pHeader_802_11->Sequence = pAd->Sequence++; if (pAd->Sequence > 0xfff) pAd->Sequence = 0; /* Before radar detection done, mgmt frame can not be sent but probe req */ /* Because we need to use probe req to trigger driver to send probe req in passive scan */ if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) { DBGPRINT(RT_DEBUG_ERROR, ("MlmeHardTransmit --> radar detect not in normal mode!\n")); /*NdisReleaseSpinLock(&pAd->TxRingLock); */ return (NDIS_STATUS_FAILURE); } /* */ /* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */ /* should always has only one ohysical buffer, and the whole frame size equals */ /* to the first scatter buffer size */ /* */ /* Initialize TX Descriptor */ /* For inter-frame gap, the number is for this frame and next frame */ /* For MLME rate, we will fix as 2Mb to match other vendor's implement */ /* pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */ /* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */ /* Only beacon use Nseq=TRUE. So here we use Nseq=FALSE. */ if (pMacEntry == NULL) { RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0, (u8)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); } else { RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE), pMacEntry->MaxHTPhyMode.field.MCS, 0, (u8)pMacEntry->MaxHTPhyMode.field.MCS, IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); } pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket; pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL; /* pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE; */ SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE); RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA); pTxD->LastSec0 = 1; pTxD->LastSec1 = 1; pTxD->SDLen0 = SrcBufLen; pTxD->SDLen1 = 0; pTxD->SDPtr0 = SrcBufPA; pTxD->DMADONE = 0; pAd->RalinkCounters.KickTxCount++; pAd->RalinkCounters.OneSecTxDoneCount++; /* Increase TX_CTX_IDX, but write to register later. */ INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE); RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * 0x10, pAd->TxRing[QueIdx].TxCpuIdx); /* Make sure to release MGMT ring resource */ /* NdisReleaseSpinLock(&pAd->TxRingLock); */ return NDIS_STATUS_SUCCESS; }
/* ======================================================================== Routine Description: Process MGMT ring DMA done interrupt, running in DPC level Arguments: pAd Pointer to our adapter Return Value: None IRQL = DISPATCH_LEVEL Note: ======================================================================== */ VOID RTMPHandleMgmtRingDmaDoneInterrupt( IN PRTMP_ADAPTER pAd) { PTXD_STRUC pTxD; #ifdef RT_BIG_ENDIAN PTXD_STRUC pDestTxD; TXD_STRUC TxD; #endif PNDIS_PACKET pPacket; // int i; UCHAR FREE = 0; PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing; NdisAcquireSpinLock(&pAd->MgmtRingLock); RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx); while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx) { FREE++; #ifdef RT_BIG_ENDIAN pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); #else pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); #endif pTxD->DMADONE = 0; pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket; if (pPacket == NULL) continue; #ifdef CONFIG_AP_SUPPORT #define LMR_FRAME_GET() (GET_OS_PKT_DATAPTR(pPacket)+TXWI_SIZE) #ifdef UAPSD_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { UAPSD_QoSNullTxMgmtTxDoneHandle(pAd, pPacket, LMR_FRAME_GET()); } #endif // UAPSD_AP_SUPPORT // #ifdef WMM_ACM_SUPPORT { HEADER_802_11 *pHeader; /* handle Power Save ADDTS Response */ pHeader = (HEADER_802_11 *)(LMR_FRAME_GET()); if ((pHeader->FC.Type == BTYPE_MGMT) && (pHeader->FC.SubType == SUBTYPE_ACTION)) { ACMP_PsRspDeltsSentOutHandle(pAd, MacTableLookup(pAd, pHeader->Addr1), ((UCHAR *)pHeader)+sizeof(HEADER_802_11)); } } #endif // WMM_ACM_SUPPORT // #endif // CONFIG_AP_SUPPORT // if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL; pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket; if (pPacket) { PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); } pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL; INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD); #endif } NdisReleaseSpinLock(&pAd->MgmtRingLock); }
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; #ifdef DOT11W_PMF_SUPPORT STA_TR_ENTRY *tr_entry; #endif /* DOT11W_PMF_SUPPORT */ UCHAR ChTxtIe = 16, ChTxtLen = CIPHER_TEXT_LEN; #ifdef DOT11R_FT_SUPPORT PFT_CFG pFtCfg; PFT_INFO pFtInfoBuf; #endif /* DOT11R_FT_SUPPORT */ BSS_STRUCT *pMbss; struct wifi_dev *wdev; UINT32 u4MaxMBSSIDSize = sizeof(pAd->ApCfg.MBSSID)/sizeof(pAd->ApCfg.MBSSID[0]); #ifdef BAND_STEERING BOOLEAN bBndStrgCheck = TRUE; #endif /* BAND_STEERING */ 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) || (apidx >= u4MaxMBSSIDSize)) { 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)) { #ifdef DOT11W_PMF_SUPPORT tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; 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; } #ifdef BAND_STEERING BND_STRG_CHECK_CONNECTION_REQ( pAd, NULL, auth_info.addr2, Elem->MsgType, Elem->rssi_info, &bBndStrgCheck); if (bBndStrgCheck == FALSE) return; #endif /* BAND_STEERING */ #ifdef DOT11R_FT_SUPPORT pFtCfg = &pMbss->FtCfg; if ((pFtCfg->FtCapFlag.Dot11rFtEnable) && (auth_info.auth_alg == AUTH_MODE_FT)) { USHORT result; if (!pEntry) pEntry = MacTableInsertEntry(pAd, auth_info.addr2, wdev, ENTRY_CLIENT, OPMODE_AP, TRUE); if (pEntry != NULL) { os_alloc_mem(pAd, (UCHAR **)&pFtInfoBuf, sizeof(FT_INFO)); if (pFtInfoBuf) { result = FT_AuthReqHandler(pAd, pEntry, &auth_info.FtInfo, pFtInfoBuf); if (result == MLME_SUCCESS) { NdisMoveMemory(&pEntry->MdIeInfo, &auth_info.FtInfo.MdIeInfo, sizeof(FT_MDIE_INFO)); pEntry->AuthState = AS_AUTH_OPEN; pEntry->Sst = SST_AUTH; } FT_EnqueueAuthReply(pAd, pRcvHdr, auth_info.auth_alg, 2, result, &pFtInfoBuf->MdIeInfo, &pFtInfoBuf->FtIeInfo, NULL, pFtInfoBuf->RSN_IE, pFtInfoBuf->RSNIE_Len); os_free_mem(NULL, pFtInfoBuf); } } return; } else #endif /* DOT11R_FT_SUPPORT */ 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) { #ifdef DOT11W_PMF_SUPPORT tr_entry = &pAd->MacTab.tr_entry[pEntry->wcid]; 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)); } }
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; 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; #ifndef RT_BIG_ENDIAN pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; #else pDestTxD = (PTXD_STRUC)pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); #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; pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE); if (pHeader_802_11->Addr1[0] & 0x01) { MlmeRate = pAd->CommonCfg.BasicMlmeRate; } else { MlmeRate = pAd->CommonCfg.MlmeRate; } if ((pHeader_802_11->FC.Type == BTYPE_DATA) && (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) { pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); } // Verify Mlme rate for a / g bands. if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band MlmeRate = RATE_6; // // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) // Snice it's been set to 0 while on MgtMacHeaderInit // By the way this will cause frame to be send on PWR_SAVE failed. // // // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame bInsertTimestamp = FALSE; if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL { bAckRequired = FALSE; } else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame) { if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST { bAckRequired = FALSE; pHeader_802_11->Duration = 0; } else { bAckRequired = TRUE; pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) { bInsertTimestamp = TRUE; } } } pHeader_802_11->Sequence = pAd->Sequence++; if (pAd->Sequence > 0xfff) pAd->Sequence = 0; // Before radar detection done, mgmt frame can not be sent but probe req // Because we need to use probe req to trigger driver to send probe req in passive scan if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) { DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n")); //NdisReleaseSpinLock(&pAd->TxRingLock); return (NDIS_STATUS_FAILURE); } #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 - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); } else { RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE), pMacEntry->MaxHTPhyMode.field.MCS, 0, (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS, IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); } pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket; pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL; // pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE; #ifdef RT_BIG_ENDIAN RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI); #endif SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE); RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA); pTxD->LastSec0 = 1; pTxD->LastSec1 = 1; pTxD->SDLen0 = SrcBufLen; pTxD->SDLen1 = 0; pTxD->SDPtr0 = SrcBufPA; pTxD->DMADONE = 0; #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); #endif pAd->RalinkCounters.KickTxCount++; pAd->RalinkCounters.OneSecTxDoneCount++; // Increase TX_CTX_IDX, but write to register later. INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE); RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx); // Make sure to release MGMT ring resource // NdisReleaseSpinLock(&pAd->TxRingLock); return NDIS_STATUS_SUCCESS; }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ NDIS_STATUS TDLS_ChannelSwitchReqAction( IN PRTMP_ADAPTER pAd, IN PMLME_TDLS_CH_SWITCH_STRUCT pChSwitchReq) { UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d}; UCHAR Header802_3[14]; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG TempLen; UCHAR RemoteFrameType = PROTO_NAME_TDLS; NDIS_STATUS NStatus = NDIS_STATUS_SUCCESS; MAC_TABLE_ENTRY *pEntry = NULL; UINT16 SwitchTime = pAd->StaCfg.TdlsInfo.TdlsSwitchTime; //micro seconds UINT16 SwitchTimeout = pAd->StaCfg.TdlsInfo.TdlsSwitchTimeout; // micro seconds int LinkId = 0xff; PRT_802_11_TDLS pTDLS = NULL; DBGPRINT(RT_DEBUG_WARN, ("====> TDLS_ChannelSwitchReqAction\n")); MAKE_802_3_HEADER(Header802_3, pChSwitchReq->PeerMacAddr, pAd->CurrentAddress, TDLS_ETHERTYPE); // Allocate buffer for transmitting message NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return NStatus; MakeOutgoingFrame(pOutBuffer, &TempLen, 1, &RemoteFrameType, END_OF_ARGS); FrameLen = FrameLen + TempLen; TDLS_BuildChannelSwitchRequest(pAd, pOutBuffer, &FrameLen, pChSwitchReq->PeerMacAddr,SwitchTime, SwitchTimeout, pChSwitchReq->TargetChannel, pChSwitchReq->TargetChannelBW); pEntry = MacTableLookup(pAd, pChSwitchReq->PeerMacAddr); if (pEntry && IS_ENTRY_TDLS(pEntry)) { pTDLS->ChannelSwitchCurrentState = TDLS_CHANNEL_SWITCH_WAIT_RSP; if (pChSwitchReq->TargetChannel != pAd->CommonCfg.Channel) RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE, RTMP_TDLS_SPECIFIC_EDCA); else RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE, RTMP_TDLS_SPECIFIC_HCCA); pAd->StaCfg.TdlsCurrentChannel = pChSwitchReq->TargetChannel; pAd->StaCfg.TdlsCurrentChannelBW = pChSwitchReq->TargetChannelBW; } else { DBGPRINT(RT_DEBUG_ERROR, ("Can't find TDLS entry on mac TABLE !!!!\n")); } hex_dump("TDLS switch channel request send pack", pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_WARN, ("<==== TDLS_ChannelSwitchReqAction\n")); return NStatus; }
INT PMF_EncryptUniRobustFrameAction( IN PRTMP_ADAPTER pAd, IN PUCHAR pMgmtFrame, IN UINT mgmt_len) { PMAC_TABLE_ENTRY pEntry = NULL; PHEADER_802_11 pHdr = (PHEADER_802_11)pMgmtFrame; INT data_len; PUCHAR pBuf; INT Status; /* Check if the length is valid */ data_len = mgmt_len - (LENGTH_802_11 + LEN_CCMP_HDR + LEN_CCMP_MIC); if (data_len <= 0) { DBGPRINT(RT_DEBUG_ERROR, ("%s : The payload length(%d) is invalid\n", __FUNCTION__, data_len)); return PMF_UNICAST_ENCRYPT_FAILURE; } /* Look up the entry through Address 1 of 802.11 header */ #ifdef CONFIG_AP_SUPPORT pEntry = MacTableLookup(pAd, pHdr->Addr1); #endif /* CONFIG_AP_SUPPORT */ if (pEntry == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s : The entry doesn't exist\n", __FUNCTION__)); return PMF_UNICAST_ENCRYPT_FAILURE; } /* check the PMF capable for this entry */ if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PMF_CAPABLE) == FALSE) { DBGPRINT(RT_DEBUG_ERROR,("%s : the entry no PMF capable !\n", __FUNCTION__)); return PMF_UNICAST_ENCRYPT_FAILURE; } /* Allocate a buffer for building PMF packet */ Status = MlmeAllocateMemory(pAd, &pBuf); if (Status != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_ERROR,("%s : allocate PMF buffer fail!\n", __FUNCTION__)); return PMF_UNICAST_ENCRYPT_FAILURE; } /* Construct and insert 8-bytes CCMP header to MPDU header */ RTMPConstructCCMPHdr(0, pEntry->PmfTxTsc, pBuf); NdisMoveMemory(pBuf + LEN_CCMP_HDR, &pHdr->Octet[0], data_len); // Encrypt the MPDU data by software RTMPSoftEncryptCCMP(pAd, (PUCHAR)pHdr, pEntry->PmfTxTsc, pEntry->PairwiseKey.Key, pBuf + LEN_CCMP_HDR, data_len); data_len += (LEN_CCMP_HDR + LEN_CCMP_MIC); NdisMoveMemory(&pHdr->Octet[0], pBuf, data_len); /* TSC increment for next transmittion */ INC_TX_TSC(pEntry->PmfTxTsc, LEN_WPA_TSC); MlmeFreeMemory(pAd, pBuf); return PMF_STATUS_SUCCESS; }
BOOLEAN CFG80211DRV_ApKeyAdd( VOID *pAdOrg, VOID *pData) { #ifdef CONFIG_AP_SUPPORT PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; CMD_RTPRIV_IOCTL_80211_KEY *pKeyInfo; MAC_TABLE_ENTRY *pEntry=NULL; UINT Wcid = 0; #ifdef RT_CFG80211_P2P_SUPPORT UINT apidx = CFG_GO_BSSID_IDX; #else UINT apidx = MAIN_MBSSID; #endif /*RT_CFG80211_P2P_SUPPORT*/ BSS_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx]; struct wifi_dev *pWdev = &pMbss->wdev; DBGPRINT(RT_DEBUG_TRACE,("%s =====> \n", __FUNCTION__)); pKeyInfo = (CMD_RTPRIV_IOCTL_80211_KEY *)pData; if (pKeyInfo->KeyType == RT_CMD_80211_KEY_WEP40 || pKeyInfo->KeyType == RT_CMD_80211_KEY_WEP104) { pWdev->WepStatus = Ndis802_11WEPEnabled; { //UCHAR CipherAlg; CIPHER_KEY *pSharedKey; POS_COOKIE pObj; pObj = (POS_COOKIE) pAd->OS_Cookie; pSharedKey = &pAd->SharedKey[apidx][pKeyInfo->KeyId]; pSharedKey->KeyLen = pKeyInfo->KeyLen; NdisMoveMemory(pSharedKey->Key, pKeyInfo->KeyBuf, pKeyInfo->KeyLen); if (pKeyInfo->KeyType == RT_CMD_80211_KEY_WEP40) pAd->SharedKey[apidx][pKeyInfo->KeyId].CipherAlg = CIPHER_WEP64; else pAd->SharedKey[apidx][pKeyInfo->KeyId].CipherAlg = CIPHER_WEP128; AsicAddSharedKeyEntry(pAd, apidx, pKeyInfo->KeyId, pSharedKey); } } else if(pKeyInfo->KeyType == RT_CMD_80211_KEY_WPA) { if (pKeyInfo->cipher == Ndis802_11AESEnable) { /* AES */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) if (pKeyInfo->bPairwise == FALSE ) #else if (pKeyInfo->KeyId > 0) #endif /* LINUX_VERSION_CODE 2.6.37 */ { if (pWdev->GroupKeyWepStatus == Ndis802_11Encryption3Enabled) { DBGPRINT(RT_DEBUG_TRACE, ("CFG: Set AES Security Set. (GROUP) %d\n", pKeyInfo->KeyLen)); pAd->SharedKey[apidx][pKeyInfo->KeyId].KeyLen= LEN_TK; NdisMoveMemory(pAd->SharedKey[apidx][pKeyInfo->KeyId].Key, pKeyInfo->KeyBuf, pKeyInfo->KeyLen); pAd->SharedKey[apidx][pKeyInfo->KeyId].CipherAlg = CIPHER_AES; AsicAddSharedKeyEntry(pAd, apidx, pKeyInfo->KeyId, &pAd->SharedKey[apidx][pKeyInfo->KeyId]); GET_GroupKey_WCID(pAd, Wcid, apidx); RTMPSetWcidSecurityInfo(pAd, apidx, (UINT8)(pKeyInfo->KeyId), pAd->SharedKey[apidx][pKeyInfo->KeyId].CipherAlg, Wcid, SHAREDKEYTABLE); #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) CmdProcAddRemoveKey(pAd, 0, apidx, pKeyInfo->KeyId, Wcid, SHAREDKEYTABLE, &pAd->SharedKey[apidx][pKeyInfo->KeyId], BROADCAST_ADDR); #endif /* MT_MAC */ } } else { if (pKeyInfo->MAC) pEntry = MacTableLookup(pAd, pKeyInfo->MAC); if(pEntry) { DBGPRINT(RT_DEBUG_TRACE, ("CFG: Set AES Security Set. (PAIRWISE) %d\n", pKeyInfo->KeyLen)); pEntry->PairwiseKey.KeyLen = LEN_TK; NdisCopyMemory(&pEntry->PTK[OFFSET_OF_PTK_TK], pKeyInfo->KeyBuf, OFFSET_OF_PTK_TK); NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[OFFSET_OF_PTK_TK], pKeyInfo->KeyLen); pEntry->PairwiseKey.CipherAlg = CIPHER_AES; AsicAddPairwiseKeyEntry(pAd, (UCHAR)pEntry->Aid, &pEntry->PairwiseKey); RTMPSetWcidSecurityInfo(pAd, pEntry->func_tb_idx, (UINT8)(pKeyInfo->KeyId & 0x0fff), pEntry->PairwiseKey.CipherAlg, pEntry->Aid, PAIRWISEKEYTABLE); #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) CmdProcAddRemoveKey(pAd, 0, apidx, pKeyInfo->KeyId, pEntry->wcid, PAIRWISEKEYTABLE, &pEntry->PairwiseKey, pEntry->Addr); #endif /* MT_MAC */ #ifdef RT_CFG80211_P2P_MULTI_CHAN_SUPPORT MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("%s: InfraCh=%d, pWdev->channel=%d\n", __FUNCTION__, pAd->MlmeAux.InfraChannel, pWdev->channel)); if (INFRA_ON(pAd) && ( ((pAd->StaCfg.wdev.bw == pWdev->bw) && (pAd->StaCfg.wdev.channel != pWdev->channel )) ||!((pAd->StaCfg.wdev.bw == pWdev->bw) && ((pAd->StaCfg.wdev.channel == pWdev->channel))))) { /*wait 1 s DHCP for P2P CLI */ OS_WAIT(1000); DBGPRINT(RT_DEBUG_TRACE, ("OS WAIT 1000 FOR DHCP\n")); // pAd->MCC_GOConnect_Protect = FALSE; // pAd->MCC_GOConnect_Count = 0; Start_MCC(pAd); MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("infra => GO test\n")); } else if((pAd->StaCfg.wdev.bw != pWdev->bw) && ((pAd->StaCfg.wdev.channel == pWdev->channel))) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("start bw != && SCC\n")); pAd->Mlme.bStartScc = TRUE; } /*after p2p cli connect , neet to change to default configure*/ //DBGPRINT(RT_DEBUG_TRACE, ("iversontest pWdev->bw %d \n",pWdev->bw)); if (pWdev->bw == 0) { pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW; pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; pAd->CommonCfg.HT_Disable = 0; SetCommonHT(pAd); } #endif /* RT_CFG80211_P2P_MULTI_CHAN_SUPPORT */ } else { DBGPRINT(RT_DEBUG_ERROR,("CFG: Set AES Security Set. (PAIRWISE) But pEntry NULL\n")); } } }else if (pKeyInfo->cipher == Ndis802_11TKIPEnable){ /* TKIP */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) if (pKeyInfo->bPairwise == FALSE ) #else if (pKeyInfo->KeyId > 0) #endif /* LINUX_VERSION_CODE 2.6.37 */ { if (pWdev->GroupKeyWepStatus == Ndis802_11Encryption2Enabled) { DBGPRINT(RT_DEBUG_TRACE, ("CFG: Set TKIP Security Set. (GROUP) %d\n", pKeyInfo->KeyLen)); pAd->SharedKey[apidx][pKeyInfo->KeyId].KeyLen= LEN_TK; NdisMoveMemory(pAd->SharedKey[apidx][pKeyInfo->KeyId].Key, pKeyInfo->KeyBuf, pKeyInfo->KeyLen); pAd->SharedKey[apidx][pKeyInfo->KeyId].CipherAlg = CIPHER_TKIP; AsicAddSharedKeyEntry(pAd, apidx, pKeyInfo->KeyId, &pAd->SharedKey[apidx][pKeyInfo->KeyId]); GET_GroupKey_WCID(pAd, Wcid, apidx); RTMPSetWcidSecurityInfo(pAd, apidx, (UINT8)(pKeyInfo->KeyId), pAd->SharedKey[apidx][pKeyInfo->KeyId].CipherAlg, Wcid, SHAREDKEYTABLE); #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) CmdProcAddRemoveKey(pAd, 0, apidx, pKeyInfo->KeyId, Wcid, SHAREDKEYTABLE, &pAd->SharedKey[apidx][pKeyInfo->KeyId], BROADCAST_ADDR); #endif /* MT_MAC */ } } else { if (pKeyInfo->MAC) pEntry = MacTableLookup(pAd, pKeyInfo->MAC); if(pEntry) { DBGPRINT(RT_DEBUG_TRACE, ("CFG: Set TKIP Security Set. (PAIRWISE) %d\n", pKeyInfo->KeyLen)); pEntry->PairwiseKey.KeyLen = LEN_TK; NdisCopyMemory(&pEntry->PTK[OFFSET_OF_PTK_TK], pKeyInfo->KeyBuf, OFFSET_OF_PTK_TK); NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[OFFSET_OF_PTK_TK], pKeyInfo->KeyLen); pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP; AsicAddPairwiseKeyEntry(pAd, (UCHAR)pEntry->Aid, &pEntry->PairwiseKey); RTMPSetWcidSecurityInfo(pAd, pEntry->func_tb_idx, (UINT8)(pKeyInfo->KeyId & 0x0fff), pEntry->PairwiseKey.CipherAlg, pEntry->Aid, PAIRWISEKEYTABLE); #ifdef MT_MAC if (pAd->chipCap.hif_type == HIF_MT) CmdProcAddRemoveKey(pAd, 0, apidx, pKeyInfo->KeyId, pEntry->wcid, PAIRWISEKEYTABLE, &pEntry->PairwiseKey, pEntry->Addr); #endif /* MT_MAC */ } else { DBGPRINT(RT_DEBUG_ERROR,("CFG: Set TKIP Security Set. (PAIRWISE) But pEntry NULL\n")); } } } } #endif /* CONFIG_AP_SUPPORT */ return TRUE; }
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 MlmeRate; ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; PTXWI_STRUC pFirstTxWI; ULONG FreeNum; MAC_TABLE_ENTRY *pMacEntry = NULL; RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); if (pSrcBufVA == NULL) { return NDIS_STATUS_FAILURE; } FreeNum = GET_TXRING_FREENO(pAd, QueIdx); if (FreeNum == 0) { return NDIS_STATUS_FAILURE; } SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; #ifndef RT_BIG_ENDIAN pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; #else pDestTxD = (PTXD_STRUC)pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; TxD = *pDestTxD; pTxD = &TxD; RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); #endif if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) { DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n")); return NDIS_STATUS_FAILURE; } #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) AsicForceWakeup(pAd, TRUE); } #endif pFirstTxWI =(PTXWI_STRUC)pSrcBufVA; pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE); if (pHeader_802_11->Addr1[0] & 0x01) { MlmeRate = pAd->CommonCfg.BasicMlmeRate; } else { MlmeRate = pAd->CommonCfg.MlmeRate; } if ((pHeader_802_11->FC.Type == BTYPE_DATA) && (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) { pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); } if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) MlmeRate = RATE_6; #ifdef CONFIG_STA_SUPPORT if (pHeader_802_11->FC.Type != BTYPE_DATA) { if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) { pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; } else { pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave; } } #endif bInsertTimestamp = FALSE; if (pHeader_802_11->FC.Type == BTYPE_CNTL) { bAckRequired = FALSE; } else { if (pHeader_802_11->Addr1[0] & 0x01) { bAckRequired = FALSE; pHeader_802_11->Duration = 0; } else { bAckRequired = TRUE; pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) { bInsertTimestamp = TRUE; } } } pHeader_802_11->Sequence = pAd->Sequence++; if (pAd->Sequence > 0xfff) pAd->Sequence = 0; if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) { DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n")); return (NDIS_STATUS_FAILURE); } #ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE); #endif if (pMacEntry == NULL) { RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); } else { RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE), pMacEntry->MaxHTPhyMode.field.MCS, 0, (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS, IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); } pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket; pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL; #ifdef RT_BIG_ENDIAN RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI); #endif SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE); RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA); pTxD->LastSec0 = 1; pTxD->LastSec1 = 1; pTxD->SDLen0 = SrcBufLen; pTxD->SDLen1 = 0; pTxD->SDPtr0 = SrcBufPA; pTxD->DMADONE = 0; #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD); WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD); #endif pAd->RalinkCounters.KickTxCount++; pAd->RalinkCounters.OneSecTxDoneCount++; INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE); RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx); return NDIS_STATUS_SUCCESS; }
static VOID ApCliTrialConnectRetryTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PAPCLI_STRUCT pApCliEntry = (APCLI_STRUCT *)FunctionContext; RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)pApCliEntry->pAd; PULONG pCurrState = &pAd->ApCfg.ApCliTab[pApCliEntry->ifIndex].CtrlCurrState; int i; UCHAR ifIndex = pApCliEntry->ifIndex; UCHAR tempBuf[10] = {}; UCHAR BBPValue; PMAC_TABLE_ENTRY pMacEntry; //PMAC_TABLE_ENTRY pOldRootAp = &pApCliEntry->oldRootAP; pMacEntry = MacTableLookup(pAd, pApCliEntry->MlmeAux.Bssid); //find rootAp that is under connecting if exists in mactable. if (pMacEntry == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("ApCli_SYNC - %s, no CfgApCliBssid in mactable!\n", __func__)); *pCurrState = APCLI_CTRL_DISCONNECTED; pApCliEntry->NewRootApRetryCnt++; if (pApCliEntry->NewRootApRetryCnt >= 10) { DBGPRINT(RT_DEBUG_TRACE, ("%s, RetryCnt:%d, pCurrState = %d, \n", __func__, pApCliEntry->NewRootApRetryCnt, *pCurrState)); pApCliEntry->TrialCh=0; ApCliLinkDown(pAd, ifIndex); MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, ifIndex); NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].CfgSsid, MAX_LEN_OF_SSID);//cleanup CfgSsid. pApCliEntry->CfgSsidLen = 0; pApCliEntry->NewRootApRetryCnt = 0;//cleanup retry count pApCliEntry->Enable = FALSE; } AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, TRUE); AsicEnableBssSync(pAd);//jump back to origin channel, regenerate beacon. return; } if ((pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED) && (*pCurrState == APCLI_CTRL_CONNECTED)) { DBGPRINT(RT_DEBUG_TRACE, ("ApCli_SYNC - %s, new rootAP connected!!\n", __func__)); /* connected to new ap ok, change common channel to new channel */ //AsicSetApCliBssid(pAd, pApCliEntry->ApCliMlmeAux.Bssid, 1); //MacTableDeleteEntry(pAd, pApCliEntry->MacTabWCID, APCLI_ROOT_BSSID_GET(pAd, pApCliEntry->MacTabWCID)); DBGPRINT(RT_DEBUG_TRACE, ("ApCli_SYNC - %s, jump back to origin channel to wait for User's operation!\n", __func__)); AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, TRUE); AsicEnableBssSync(pAd);//jump back to origin channel, regenerate beacon. NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].CfgSsid, MAX_LEN_OF_SSID);//cleanup CfgSsid. pApCliEntry->CfgSsidLen = 0; pApCliEntry->NewRootApRetryCnt = 0;//cleanup retry count pApCliEntry->Enable = FALSE; // sprintf(tempBuf, "%d", pApCliEntry->TrialCh); // DBGPRINT(RT_DEBUG_TRACE, ("Follow new rootAP Switch to channel :%s\n", tempBuf)); // Set_Channel_Proc(pAd, tempBuf);//APStartUp will regenerate beacon. pApCliEntry->TrialCh=0; } else { /* Apcli does not connect to new root ap successfully yet, jump back to origin channel to serve old rootap traffic. re-issue assoc_req to go later. */ //pApCliEntry->MacTabWCID = pOldRootAp->Aid; pApCliEntry->NewRootApRetryCnt++; if (pApCliEntry->NewRootApRetryCnt < 10) RTMPSetTimer(&(pApCliEntry->TrialConnectPhase2Timer), TRIAL_TIMEOUT); else { DBGPRINT(RT_DEBUG_TRACE, ("%s, RetryCnt:%d, pCurrState = %d, \n", __func__, pApCliEntry->NewRootApRetryCnt, *pCurrState)); pApCliEntry->TrialCh=0; MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_DISCONNECT_REQ, 0, NULL, ifIndex); NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].CfgSsid, MAX_LEN_OF_SSID);//cleanup CfgSsid. pApCliEntry->CfgSsidLen = 0; pApCliEntry->NewRootApRetryCnt = 0;//cleanup retry count pApCliEntry->Enable = FALSE; ApCliLinkDown(pAd, ifIndex); } AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, TRUE); AsicEnableBssSync(pAd);//jump back to origin channel, regenerate beacon. } return; }
BOOLEAN CFG80211DRV_StaGet( VOID *pAdOrg, VOID *pData) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg; CMD_RTPRIV_IOCTL_80211_STA *pIbssInfo; pIbssInfo = (CMD_RTPRIV_IOCTL_80211_STA *)pData; #ifdef CONFIG_AP_SUPPORT { MAC_TABLE_ENTRY *pEntry; ULONG DataRate = 0; UINT32 RSSI; pEntry = MacTableLookup(pAd, pIbssInfo->MAC); if (pEntry == NULL) return FALSE; /* End of if */ /* fill tx rate */ getRate(pEntry->HTPhyMode, &DataRate); if ((pEntry->HTPhyMode.field.MODE == MODE_HTMIX) || (pEntry->HTPhyMode.field.MODE == MODE_HTGREENFIELD)) { if (pEntry->HTPhyMode.field.BW) pIbssInfo->TxRateFlags |= RT_CMD_80211_TXRATE_BW_40; /* End of if */ if (pEntry->HTPhyMode.field.ShortGI) pIbssInfo->TxRateFlags |= RT_CMD_80211_TXRATE_SHORT_GI; /* End of if */ pIbssInfo->TxRateMCS = pEntry->HTPhyMode.field.MCS; } else { pIbssInfo->TxRateFlags = RT_CMD_80211_TXRATE_LEGACY; pIbssInfo->TxRateMCS = DataRate*1000; /* unit: 100kbps */ } /* End of if */ /* fill signal */ RSSI = (pEntry->RssiSample.AvgRssi0 + pEntry->RssiSample.AvgRssi1 + pEntry->RssiSample.AvgRssi2) / 3; pIbssInfo->Signal = RSSI; /* fill tx count */ pIbssInfo->TxPacketCnt = pEntry->OneSecTxNoRetryOkCount + pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount; /* fill inactive time */ pIbssInfo->InactiveTime = pEntry->NoDataIdleCount * 1000; /* unit: ms */ pIbssInfo->InactiveTime *= MLME_TASK_EXEC_MULTIPLE; pIbssInfo->InactiveTime /= 20; } #endif /* CONFIG_AP_SUPPORT */ return TRUE; }
VOID PMF_PeerSAQueryReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Action = Elem->Msg[LENGTH_802_11+1]; if (Action == ACTION_SAQ_REQUEST) { PMAC_TABLE_ENTRY pEntry; PFRAME_802_11 pHeader; USHORT TransactionID; PUCHAR pOutBuffer = NULL; HEADER_802_11 SAQRspHdr; UINT32 FrameLen = 0; UCHAR SACategoryType, SAActionType; //UINT ccmp_len = LEN_CCMP_HDR + LEN_CCMP_MIC; //UCHAR ccmp_buf[ccmp_len]; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s : Receive SA Query Request\n", __FUNCTION__)); pHeader = (PFRAME_802_11) Elem->Msg; pEntry = MacTableLookup(pAd, pHeader->Hdr.Addr2); if (!pEntry) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s : Entry is not found, STA(%02x:%02x:%02x:%02x:%02x:%02x)\n", __FUNCTION__, PRINT_MAC(pHeader->Hdr.Addr2))); return; } if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_PMF_CAPABLE))) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s : Entry is not PMF capable, STA(%02x:%02x:%02x:%02x:%02x:%02x)\n", __FUNCTION__, PRINT_MAC(pHeader->Hdr.Addr2))); return; } NdisMoveMemory(&TransactionID, &Elem->Msg[LENGTH_802_11+2], sizeof(USHORT)); /* Response the SA Query */ os_alloc_mem(NULL, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER); if(pOutBuffer == NULL) return; #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { MgtMacHeaderInit(pAd, &SAQRspHdr, SUBTYPE_ACTION, 0, pHeader->Hdr.Addr2, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid, pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.bssid); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { MgtMacHeaderInit(pAd, &SAQRspHdr, SUBTYPE_ACTION, 0, pHeader->Hdr.Addr2, pAd->CurrentAddress, pHeader->Hdr.Addr2); } #endif /* CONFIG_STA_SUPPORT */ SACategoryType = CATEGORY_SA; SAActionType = ACTION_SAQ_RESPONSE; MakeOutgoingFrame(pOutBuffer, (ULONG *) &FrameLen, sizeof(HEADER_802_11), &SAQRspHdr, 1, &SACategoryType, 1, &SAActionType, 2, &TransactionID, END_OF_ARGS); /* transmit the frame */ MiniportMMRequest(pAd, QID_MGMT, pOutBuffer, FrameLen); os_free_mem(NULL, pOutBuffer); MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("[PMF]%s - Send SA Query Response to STA(%02x:%02x:%02x:%02x:%02x:%02x)\n", __FUNCTION__, PRINT_MAC(SAQRspHdr.Addr1))); }
VOID ap_cmm_peer_assoc_req_action( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem, IN BOOLEAN isReassoc) { IE_LISTS *ie_list = NULL; HEADER_802_11 AssocRspHdr; USHORT CapabilityInfoForAssocResp; USHORT StatusCode = MLME_SUCCESS; USHORT Aid; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; UCHAR MaxSupportedRate = 0; UCHAR SupRateLen, PhyMode, FlgIs11bSta; UCHAR i; MAC_TABLE_ENTRY *pEntry; #ifdef DBG UCHAR *sAssoc = isReassoc ? (PUCHAR)"ReASSOC" : (PUCHAR)"ASSOC"; #endif /* DBG */ UCHAR SubType; BOOLEAN bACLReject = FALSE; #ifdef DOT1X_SUPPORT PUINT8 pPmkid = NULL; UINT8 pmkid_count = 0; #endif /* DOT1X_SUPPORT */ MULTISSID_STRUCT *wdev; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(IE_LISTS)); if (ie_list == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s(): mem alloc failed\n", __FUNCTION__)); return; } NdisZeroMemory(ie_list, sizeof(IE_LISTS)); if (!PeerAssocReqCmmSanity(pAd, isReassoc, Elem->Msg, Elem->MsgLen, ie_list)) goto LabelOK; /* check if AP address is same as us */ /* TODO */ /* goto label_err; */ pEntry = MacTableLookup(pAd, ie_list->Addr2); if (!pEntry) { DBGPRINT(RT_DEBUG_ERROR, ("NoAuth MAC - %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(ie_list->Addr2))); goto LabelOK; } if (!VALID_MBSS(pAd, pEntry->apidx)) { DBGPRINT(RT_DEBUG_ERROR, ("%s():pEntry bounding invalid wdev(apidx=%d)\n", __FUNCTION__, pEntry->apidx)); goto LabelOK; } wdev = &pAd->ApCfg.MBSSID[pEntry->apidx]; PhyMode = wdev->PhyMode; FlgIs11bSta = 1; for(i=0; i<ie_list->SupportedRatesLen; i++) { if (((ie_list->SupportedRates[i] & 0x7F) != 2) && ((ie_list->SupportedRates[i] & 0x7F) != 4) && ((ie_list->SupportedRates[i] & 0x7F) != 11) && ((ie_list->SupportedRates[i] & 0x7F) != 22)) { FlgIs11bSta = 0; break; } } /* clear the previous Pairwise key table */ if(pEntry->Aid != 0 && (pEntry->WepStatus >= Ndis802_11Encryption2Enabled #ifdef DOT1X_SUPPORT || wdev->IEEE8021X #endif /* DOT1X_SUPPORT */ )) { /* clear GTK state */ pEntry->GTKState = REKEY_NEGOTIATING; NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY)); /* clear this entry as no-security mode */ AsicRemovePairwiseKeyEntry(pAd, pEntry->Aid); #ifdef DOT1X_SUPPORT /* Notify 802.1x daemon to clear this sta info */ if (pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPA2 || wdev->IEEE8021X) DOT1X_InternalCmdAction(pAd, pEntry, DOT1X_DISCONNECT_ENTRY); #endif /* DOT1X_SUPPORT */ } /* for hidden SSID sake, SSID in AssociateRequest should be fully verified */ if ((ie_list->SsidLen != wdev->SsidLen) || (NdisEqualMemory(ie_list->Ssid, wdev->Ssid, ie_list->SsidLen)==0)) goto LabelOK; /* set a flag for sending Assoc-Fail response to unwanted STA later. */ if (! ApCheckAccessControlList(pAd, ie_list->Addr2, pEntry->apidx)) bACLReject = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("%s - MBSS(%d), receive %s request from %02x:%02x:%02x:%02x:%02x:%02x\n", sAssoc, pEntry->apidx, sAssoc, PRINT_MAC(ie_list->Addr2))); /* supported rates array may not be sorted. sort it and find the maximum rate */ for (i=0; i<ie_list->SupportedRatesLen; i++) { if (MaxSupportedRate < (ie_list->SupportedRates[i] & 0x7f)) MaxSupportedRate = ie_list->SupportedRates[i] & 0x7f; } /* Assign RateLen here or we will select wrong rate table in APBuildAssociation() when 11N compile option is disabled. */ pEntry->RateLen = ie_list->SupportedRatesLen; RTMPSetSupportMCS(pAd, OPMODE_AP, pEntry, ie_list->SupportedRates, ie_list->SupportedRatesLen, NULL, 0, #ifdef DOT11_VHT_AC ie_list->vht_cap_len, &ie_list->vht_cap, #endif /* DOT11_VHT_AC */ &ie_list->HTCapability, ie_list->ht_cap_len); /* 2. qualify this STA's auth_asoc status in the MAC table, decide StatusCode */ StatusCode = APBuildAssociation(pAd, pEntry, ie_list, MaxSupportedRate, &Aid); #ifdef DOT11_VHT_AC if (ie_list->vht_cap_len) { VHT_CAP_INFO *vht_cap = &ie_list->vht_cap.vht_cap; //+++Add by shiang for debug if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode)) { DBGPRINT(RT_DEBUG_TRACE, ("%s():Peer is VHT capable device!\n", __FUNCTION__)); //dump_vht_cap(pAd, &ie_list->vht_cap); } //---Add by shiang for debug } #endif /* DOT11_VHT_AC */ if (StatusCode == MLME_ASSOC_REJ_DATA_RATE) RTMPSendWirelessEvent(pAd, IW_STA_MODE_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); /* 3. send Association Response */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) goto LabelOK; DBGPRINT(RT_DEBUG_TRACE, ("%s - Send %s response (Status=%d)...\n", sAssoc, sAssoc, StatusCode)); Aid |= 0xc000; /* 2 most significant bits should be ON */ SubType = isReassoc ? SUBTYPE_REASSOC_RSP : SUBTYPE_ASSOC_RSP; CapabilityInfoForAssocResp = wdev->CapabilityInfo; /*use AP's cability */ /* fail in ACL checking => send an Assoc-Fail resp. */ SupRateLen = pAd->CommonCfg.SupRateLen; /* TODO: need to check rate in support rate element, not number */ if (FlgIs11bSta == 1) SupRateLen = 4; if (bACLReject == TRUE) { MgtMacHeaderInit(pAd, &AssocRspHdr, SubType, 0, ie_list->Addr2, wdev->Bssid); StatusCode = MLME_UNSPECIFY_FAIL; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AssocRspHdr, 2, &CapabilityInfoForAssocResp, 2, &StatusCode, 2, &Aid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, (PVOID) pOutBuffer); RTMPSendWirelessEvent(pAd, IW_MAC_FILTER_LIST_EVENT_FLAG, ie_list->Addr2, pEntry->apidx, 0); goto LabelOK; } MgtMacHeaderInit(pAd, &AssocRspHdr, SubType, 0, ie_list->Addr2, wdev->Bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &AssocRspHdr, 2, &CapabilityInfoForAssocResp, 2, &StatusCode, 2, &Aid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, END_OF_ARGS); if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B) && (FlgIs11bSta == 0)) { ULONG TmpLen; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } /* add WMM IE here */ if (wdev->bWmmCapable && CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) { ULONG TmpLen; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &wdev->UapsdInfo); #endif /* UAPSD_SUPPORT */ for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; }
BOOLEAN PeerAssocReqCmmSanity( IN PRTMP_ADAPTER pAd, IN BOOLEAN isReassoc, IN VOID *Msg, IN ULONG MsgLen, OUT PUCHAR pAddr2, OUT USHORT *pCapabilityInfo, OUT USHORT *pListenInterval, OUT PUCHAR pApAddr, OUT UCHAR *pSsidLen, OUT char *Ssid, OUT UCHAR *pRatesLen, OUT UCHAR Rates[], OUT UCHAR *RSN, OUT UCHAR *pRSNLen, OUT BOOLEAN *pbWmmCapable, #ifdef WSC_AP_SUPPORT OUT BOOLEAN *pWscCapable, #endif /* WSC_AP_SUPPORT */ OUT ULONG *pRalinkIe, OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, #ifdef P2P_SUPPORT OUT ULONG *P2PSubelementLen, OUT PUCHAR pP2pSubelement, #endif /* P2P_SUPPORT */ OUT UCHAR *pHtCapabilityLen, OUT HT_CAPABILITY_IE *pHtCapability) { CHAR *Ptr; PFRAME_802_11 Fr = (PFRAME_802_11)Msg; PEID_STRUCT eid_ptr; UCHAR Sanity = 0; UCHAR WPA1_OUI[4] = { 0x00, 0x50, 0xF2, 0x01 }; UCHAR WPA2_OUI[3] = { 0x00, 0x0F, 0xAC }; MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)NULL; #ifdef P2P_SUPPORT PRT_P2P_CONFIG pP2PCtrl = &pAd->P2pCfg; UCHAR P2POUIBYTE[4] = {0x50, 0x6f, 0x9a, 0x9}; #endif /* P2P_SUPPORT */ /* to prevent caller from using garbage output value */ *pSsidLen = 0; *pRatesLen = 0; *pRSNLen = 0; *pbWmmCapable = FALSE; *pRalinkIe = 0; *pHtCapabilityLen= 0; COPY_MAC_ADDR(pAddr2, &Fr->Hdr.Addr2); pEntry = MacTableLookup(pAd, pAddr2); if (pEntry == NULL) return FALSE; Ptr = (PCHAR)Fr->Octet; NdisMoveMemory(pCapabilityInfo, &Fr->Octet[0], 2); NdisMoveMemory(pListenInterval, &Fr->Octet[2], 2); if (isReassoc) { NdisMoveMemory(pApAddr, &Fr->Octet[4], 6); eid_ptr = (PEID_STRUCT) &Fr->Octet[10]; } else { eid_ptr = (PEID_STRUCT) &Fr->Octet[4]; } /* get variable fields from payload and advance the pointer */ while (((UCHAR *)eid_ptr + eid_ptr->Len + 1) < ((UCHAR *)Fr + MsgLen)) { switch(eid_ptr->Eid) { case IE_SSID: if (((Sanity&0x1) == 1)) break; if ((eid_ptr->Len <= MAX_LEN_OF_SSID)) { Sanity |= 0x01; NdisMoveMemory(Ssid, eid_ptr->Octet, eid_ptr->Len); *pSsidLen = eid_ptr->Len; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - SsidLen = %d \n", *pSsidLen)); } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SSID\n")); return FALSE; } break; case IE_SUPP_RATES: if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0)) { Sanity |= 0x02; NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len); DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - IE_SUPP_RATES., Len=%d. " "Rates[0]=%x\n", eid_ptr->Len, Rates[0])); DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7])); *pRatesLen = eid_ptr->Len; } else { UCHAR RateDefault[8] = \ { 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c }; /* HT rate not ready yet. return true temporarily. rt2860c */ /*DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES\n")); */ Sanity |= 0x02; *pRatesLen = 8; NdisMoveMemory(Rates, RateDefault, 8); DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES., Len=%d\n", eid_ptr->Len)); } break; case IE_EXT_SUPP_RATES: if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES) { NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len); *pRatesLen = (*pRatesLen) + eid_ptr->Len; } else { NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen)); *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES; } break; case IE_HT_CAP: if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE)) { NdisMoveMemory(pHtCapability, eid_ptr->Octet, SIZE_HT_CAP_IE); *(USHORT *)(&pHtCapability->HtCapInfo) = \ cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&pHtCapability->ExtHtCapInfo) = \ cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ *pHtCapabilityLen = SIZE_HT_CAP_IE; Sanity |= 0x10; DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_HT_CAP\n")); } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len)); } break; case IE_EXT_CAPABILITY: if (eid_ptr->Len >= sizeof(EXT_CAP_INFO_ELEMENT)) { NdisMoveMemory(pExtCapInfo, eid_ptr->Octet, sizeof(EXT_CAP_INFO_ELEMENT)); DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_EXT_CAPABILITY!\n")); } break; case IE_WPA: /* same as IE_VENDOR_SPECIFIC */ case IE_WPA2: #ifdef P2P_SUPPORT if (NdisEqualMemory(eid_ptr->Octet, P2POUIBYTE, sizeof(P2POUIBYTE)) && (eid_ptr->Len >= 4)) { if (*P2PSubelementLen == 0) { RTMPMoveMemory(pP2pSubelement, &eid_ptr->Eid, (eid_ptr->Len+2)); *P2PSubelementLen = (eid_ptr->Len+2); } else if (*P2PSubelementLen > 0) { if (((*P2PSubelementLen) + (eid_ptr->Len+2)) <= MAX_VIE_LEN) { RTMPMoveMemory(pP2pSubelement + *P2PSubelementLen, &eid_ptr->Eid, (eid_ptr->Len+2)); *P2PSubelementLen += (eid_ptr->Len+2); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s: ERROR!! 111 Sum of P2PSubelementLen= %lu, > MAX_VIE_LEN !!\n", __FUNCTION__ ,((*P2PSubelementLen) + (eid_ptr->Len+2)))); return FALSE; } } DBGPRINT(RT_DEBUG_TRACE, (" ! ===>P2P - PeerAssocReqSanity P2P IE Len becomes = %d. %s\n", *P2PSubelementLen, decodeP2PState(pP2PCtrl->P2PConnectState))); break; } #endif /* P2P_SUPPORT */ if (NdisEqualMemory(eid_ptr->Octet, WPS_OUI, 4)) { #ifdef WSC_AP_SUPPORT #ifdef WSC_V2_SUPPORT if ((pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscV2Info.bWpsEnable) || (pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscV2Info.bEnableWpsV2 == FALSE)) #endif /* WSC_V2_SUPPORT */ *pWscCapable = TRUE; #endif /* WSC_AP_SUPPORT */ break; } /* Handle Atheros and Broadcom draft 11n STAs */ if (NdisEqualMemory(eid_ptr->Octet, BROADCOM_OUI, 3)) { switch (eid_ptr->Octet[3]) { case 0x33: if ((eid_ptr->Len-4) == sizeof(HT_CAPABILITY_IE)) { NdisMoveMemory(pHtCapability, &eid_ptr->Octet[4], SIZE_HT_CAP_IE); *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ *pHtCapabilityLen = SIZE_HT_CAP_IE; } break; default: /* ignore other cases */ break; } } if (NdisEqualMemory(eid_ptr->Octet, RALINK_OUI, 3) && (eid_ptr->Len == 7)) { /**pRalinkIe = eid_ptr->Octet[3]; */ if (eid_ptr->Octet[3] != 0) *pRalinkIe = eid_ptr->Octet[3]; else *pRalinkIe = 0xf0000000; /* Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. */ break; } /* WMM_IE */ if (NdisEqualMemory(eid_ptr->Octet, WME_INFO_ELEM, 6) && (eid_ptr->Len == 7)) { *pbWmmCapable = TRUE; #ifdef UAPSD_SUPPORT if (pEntry) { UAPSD_AssocParse(pAd, pEntry, (UINT8 *)&eid_ptr->Octet[6], pAd->ApCfg.MBSSID[\ pEntry->apidx].UapsdInfo.bAPSDCapable); } #endif /* UAPSD_SUPPORT */ break; } if (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode < Ndis802_11AuthModeWPA) break; /* If this IE did not begins with 00:0x50:0xf2:0x01, it would be proprietary. So we ignore it. */ if (!NdisEqualMemory(eid_ptr->Octet, WPA1_OUI, sizeof(WPA1_OUI)) && !NdisEqualMemory(&eid_ptr->Octet[2], WPA2_OUI, sizeof(WPA2_OUI))) { DBGPRINT(RT_DEBUG_TRACE, ("Not RSN IE, maybe WMM IE!!!\n")); break; } if (/*(eid_ptr->Len <= MAX_LEN_OF_RSNIE) &&*/ (eid_ptr->Len >= MIN_LEN_OF_RSNIE)) { hex_dump("Received RSNIE in Assoc-Req", (UCHAR *)eid_ptr, eid_ptr->Len + 2); /* Copy whole RSNIE context */ NdisMoveMemory(RSN, eid_ptr, eid_ptr->Len + 2); *pRSNLen=eid_ptr->Len + 2; } else { *pRSNLen=0; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - missing IE_WPA(%d)\n",eid_ptr->Len)); return FALSE; } break; #ifdef WAPI_SUPPORT case IE_WAPI: if ((pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode != Ndis802_11AuthModeWAICERT) && (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode != Ndis802_11AuthModeWAIPSK)) break; /* Sanity check the validity of WIE */ /* Todo - AlbertY */ /* Copy whole WAPI-IE context */ NdisMoveMemory(RSN, eid_ptr, eid_ptr->Len + 2); *pRSNLen=eid_ptr->Len + 2; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - IE_WAPI(%d)\n",eid_ptr->Len)); break; #endif /* WAPI_SUPPORT */ default: break; } eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); } if ((Sanity&0x3) != 0x03) { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - missing mandatory field\n")); return FALSE; } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - success\n")); return TRUE; } }
/* ========================================================================== Description: Process the received ProbeRequest from clients Parameters: Elem - msg containing the ProbeReq frame ========================================================================== */ VOID APPeerProbeReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Addr2[MAC_ADDR_LEN]; CHAR Ssid[MAX_LEN_OF_SSID]; UCHAR SsidLen; /*, Rates[MAX_LEN_OF_SUPPORTED_RATES], RatesLen; */ HEADER_802_11 ProbeRspHdr; NDIS_STATUS NStatus; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0, TmpLen; LARGE_INTEGER FakeTimestamp; UCHAR DsLen = 1;/*, IbssLen = 2, TimLen=1, */ /*BitmapControl=0, VirtualBitmap=0; */ UCHAR ErpIeLen = 1; UCHAR apidx = 0, PhyMode, SupRateLen; UCHAR RSNIe=IE_WPA, RSNIe2=IE_WPA2;/*, RSN_Len=22; */ BOOLEAN bRequestRssi=FALSE; #ifdef WDS_SUPPORT /* if in bridge mode, no need to reply probe req. */ if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE) return; #endif /* WDS_SUPPORT */ if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen, &bRequestRssi)) return; for(apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++) { RSNIe = IE_WPA; if ((pAd->ApCfg.MBSSID[apidx].MSSIDDev != NULL) && !(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].MSSIDDev))) { /* the interface is down, so we can not send probe response */ continue; } /* End of if */ PhyMode = pAd->ApCfg.MBSSID[apidx].PhyMode; if (((SsidLen == 0) && (! pAd->ApCfg.MBSSID[apidx].bHideSsid)) || ((SsidLen == pAd->ApCfg.MBSSID[apidx].SsidLen) && NdisEqualMemory(Ssid, pAd->ApCfg.MBSSID[apidx].Ssid, (ULONG) SsidLen))) ; else continue; /* check next BSS */ /* allocate and send out ProbeRsp frame */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) return; MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, pAd->ApCfg.MBSSID[apidx].Bssid); if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSK)) RSNIe = IE_WPA; else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2PSK)) RSNIe = IE_WPA2; { SupRateLen = pAd->CommonCfg.SupRateLen; if (PhyMode == PHY_11B) SupRateLen = 4; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &ProbeRspHdr, TIMESTAMP_LEN, &FakeTimestamp, 2, &pAd->CommonCfg.BeaconPeriod, 2, &pAd->ApCfg.MBSSID[apidx].CapabilityInfo, 1, &SsidIe, 1, &pAd->ApCfg.MBSSID[apidx].SsidLen, pAd->ApCfg.MBSSID[apidx].SsidLen, pAd->ApCfg.MBSSID[apidx].Ssid, 1, &SupRateIe, 1, &SupRateLen, SupRateLen, pAd->CommonCfg.SupRate, 1, &DsIe, 1, &DsLen, 1, &pAd->CommonCfg.Channel, END_OF_ARGS); } if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != PHY_11B)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ErpIe, 1, &ErpIeLen, 1, &pAd->ApCfg.ErpIeContent, 1, &ExtRateIe, 1, &pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate, END_OF_ARGS); FrameLen += TmpLen; } #ifdef A_BAND_SUPPORT /* add Channel switch announcement IE */ if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->Dot11_H.CSCount, END_OF_ARGS); FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ #ifdef DOT11_N_SUPPORT if ((PhyMode >= PHY_11ABGN_MIXED) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen, NewExtLen; #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif #ifdef A_BAND_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement && (pAd->CommonCfg.Channel > 14)) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); NewExtLen = 1; /*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */ #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability, 1, &AddHtInfoIe, 1, &AddHtLen, sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &HtCapIe, 1, &HtLen, HtLen, &HtCapabilityTmp, 1, &AddHtInfoIe, 1, &AddHtLen, AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } #endif /* DOT11_N_SUPPORT */ /* Append RSN_IE when WPA OR WPAPSK, */ if (pAd->ApCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA) ; /* enough information */ else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0], 1, &RSNIe2, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1], pAd->ApCfg.MBSSID[apidx].RSN_IE[1], END_OF_ARGS); FrameLen += TmpLen; } else { MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &RSNIe, 1, &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0], pAd->ApCfg.MBSSID[apidx].RSN_IE[0], END_OF_ARGS); FrameLen += TmpLen; } /* add WMM IE here */ if (pAd->ApCfg.MBSSID[apidx].bWmmCapable) { UCHAR i; UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f; #ifdef UAPSD_SUPPORT UAPSD_MR_IE_FILL(WmeParmIe[8], &pAd->ApCfg.MBSSID[apidx].UapsdInfo); #endif /* UAPSD_SUPPORT */ for (i=QID_AC_BE; i<=QID_AC_VO; i++) { WmeParmIe[10+ (i*4)] = (i << 5) + /* b5-6 is ACI */ ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4) + /* b4 is ACM */ (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f); /* b0-3 is AIFSN */ WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4) + /* b5-8 is CWMAX */ (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f); /* b0-3 is CWMIN */ WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff); /* low byte of TXOP */ WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8); /* high byte of TXOP */ } MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 26, WmeParmIe, END_OF_ARGS); FrameLen += TmpLen; } #ifdef AP_QLOAD_SUPPORT if (pAd->FlgQloadEnable != 0) { FrameLen += QBSS_LoadElementAppend(pAd, pOutBuffer+FrameLen); } #endif /* AP_QLOAD_SUPPORT */ #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 /* P802.11n_D3.03, 7.3.2.60 Overlapping BSS Scan Parameters IE */ if ((PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1)) { OVERLAP_BSS_SCAN_IE OverlapScanParam; ULONG TmpLen; UCHAR OverlapScanIE, ScanIELen; OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM; ScanIELen = 14; OverlapScanParam.ScanPassiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveDwell); OverlapScanParam.ScanActiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveDwell); OverlapScanParam.TriggerScanInt = cpu2le16(pAd->CommonCfg.Dot11BssWidthTriggerScanInt); OverlapScanParam.PassiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel); OverlapScanParam.ActiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel); OverlapScanParam.DelayFactor = cpu2le16(pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); OverlapScanParam.ScanActThre = cpu2le16(pAd->CommonCfg.Dot11OBssScanActivityThre); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &OverlapScanIE, 1, &ScanIELen, ScanIELen, &OverlapScanParam, END_OF_ARGS); FrameLen += TmpLen; } /* 7.3.2.27 Extended Capabilities IE */ { ULONG TmpLen; EXT_CAP_INFO_ELEMENT extCapInfo; UCHAR extInfoLen; extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT); NdisZeroMemory(&extCapInfo, extInfoLen); /* P802.11n_D1.10, HT Information Exchange Support */ if ((PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.Channel <= 14) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) && (pAd->CommonCfg.bBssCoexEnable == TRUE)) { extCapInfo.BssCoexistMgmtSupport = 1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &ExtCapIe, 1, &extInfoLen, extInfoLen, &extCapInfo, END_OF_ARGS); FrameLen += TmpLen; } } #endif /* DOT11N_DRAFT3 */ #endif /* DOT11_N_SUPPORT */ #ifdef A_BAND_SUPPORT /* add Channel switch announcement IE */ if ((pAd->CommonCfg.Channel > 14) && (pAd->CommonCfg.bIEEE80211H == 1) && (pAd->Dot11_H.RDMode == RD_SWITCHING_MODE)) { UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT; UCHAR CSALen=3; UCHAR CSAMode=1; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CSAIe, 1, &CSALen, 1, &CSAMode, 1, &pAd->CommonCfg.Channel, 1, &pAd->Dot11_H.CSCount, END_OF_ARGS); FrameLen += TmpLen; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bExtChannelSwitchAnnouncement) { HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE HtExtChannelSwitchIe; build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE), &HtExtChannelSwitchIe, END_OF_ARGS); } #endif /* DOT11_N_SUPPORT */ FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ /* add country IE, power constraint IE */ if (pAd->CommonCfg.bCountryFlag) { ULONG TmpLen2=0; UCHAR TmpFrame[256]; UCHAR CountryIe = IE_COUNTRY; UCHAR MaxTxPower=16; #ifdef A_BAND_SUPPORT /* Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32) in beacons and probe response frames */ if (pAd->CommonCfg.Channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE) { /* prepare power constraint IE */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 3, PowerConstraintIE, END_OF_ARGS); FrameLen += TmpLen; } #endif /* A_BAND_SUPPORT */ NdisZeroMemory(TmpFrame, sizeof(TmpFrame)); /* prepare channel information */ MakeOutgoingFrame(TmpFrame+TmpLen2, &TmpLen, 1, &pAd->ChannelList[0].Channel, 1, &pAd->ChannelListNum, 1, &MaxTxPower, END_OF_ARGS); TmpLen2 += TmpLen; /* need to do the padding bit check, and concatenate it */ if ((TmpLen2%2) == 0) { UCHAR TmpLen3 = TmpLen2+4; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2+1, TmpFrame, END_OF_ARGS); } else { UCHAR TmpLen3 = TmpLen2+3; MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 1, &CountryIe, 1, &TmpLen3, 3, pAd->CommonCfg.CountryCode, TmpLen2, TmpFrame, END_OF_ARGS); } FrameLen += TmpLen; }/* Country IE - */ #ifdef DOT11_N_SUPPORT if ((PhyMode >= PHY_11ABGN_MIXED) && (pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable)) { ULONG TmpLen; UCHAR HtLen, AddHtLen;/*, NewExtLen; */ #ifdef RT_BIG_ENDIAN HT_CAPABILITY_IE HtCapabilityTmp; ADD_HT_INFO_IE addHTInfoTmp; #endif HtLen = sizeof(pAd->CommonCfg.HtCapability); AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo); if (pAd->bBroadComHT == TRUE) { UCHAR epigram_ie_len; UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33}; UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34}; epigram_ie_len = HtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &pAd->CommonCfg.HtCapability, END_OF_ARGS); #else NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen); *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_HTC[0], HtLen, &HtCapabilityTmp, END_OF_ARGS); #endif FrameLen += TmpLen; epigram_ie_len = AddHtLen + 4; #ifndef RT_BIG_ENDIAN MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &pAd->CommonCfg.AddHTInfo, END_OF_ARGS); #else NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen); *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2)); *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3)); MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 1, &WpaIe, 1, &epigram_ie_len, 4, &BROADCOM_AHTINFO[0], AddHtLen, &addHTInfoTmp, END_OF_ARGS); #endif FrameLen += TmpLen; } } #endif /* DOT11_N_SUPPORT */ //move Ralink-specific IE to last for Omipeek parse fine! /* add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back Byte0.b3=1 for rssi-feedback */ { ULONG TmpLen; UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00}; if (pAd->CommonCfg.bAggregationCapable) RalinkSpecificIe[5] |= 0x1; if (pAd->CommonCfg.bPiggyBackCapable) RalinkSpecificIe[5] |= 0x2; #ifdef DOT11_N_SUPPORT if (pAd->CommonCfg.bRdg) RalinkSpecificIe[5] |= 0x4; #endif /* DOT11_N_SUPPORT */ #ifdef RSSI_FEEDBACK if (bRequestRssi == TRUE) { MAC_TABLE_ENTRY *pEntry=NULL; DBGPRINT(RT_DEBUG_ERROR, ("SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5] )); RalinkSpecificIe[5] |= 0x8; pEntry = MacTableLookup(pAd, Addr2); if (pEntry != NULL) { RalinkSpecificIe[6] = (UCHAR)pEntry->RssiSample.AvgRssi0; RalinkSpecificIe[7] = (UCHAR)pEntry->RssiSample.AvgRssi1; RalinkSpecificIe[8] = (UCHAR)pEntry->RssiSample.AvgRssi2; } } #endif /* RSSI_FEEDBACK */ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen, 9, RalinkSpecificIe, END_OF_ARGS); FrameLen += TmpLen; } /* 802.11n 11.1.3.2.2 active scanning. sending probe response with MCS rate is */ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); }
/* ======================================================================== Routine Description: Send a traffic response frame. Arguments: pAd - WLAN control block pointer pTDLS - the peer entry Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_FAILURE Note: ======================================================================== */ static NDIS_STATUS TDLS_UAPSD_TrafficRspSend( IN PRTMP_ADAPTER pAd, IN UCHAR *pPeerMac, IN UCHAR PeerToken) { MAC_TABLE_ENTRY *pMacEntry; RT_802_11_TDLS *pTDLS = NULL; UCHAR TDLS_ETHERTYPE[] = {0x89, 0x0d}; UCHAR Header802_3[14]; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; ULONG TempLen; INT32 LinkId; UCHAR RemoteFrameType = PROTO_NAME_TDLS; NDIS_STATUS NStatus = NDIS_STATUS_FAILURE; DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__)); /* search TDLS entry */ LinkId = TDLS_SearchLinkId(pAd, pPeerMac); if (TDLS_UAPSD_IS_LINK_INVALID(LinkId)) { DBGPRINT(RT_DEBUG_TRACE, ("%s: can not find the LinkId!\n", __FUNCTION__)); TDLS_UAPSD_REBUILD_LINK(pAd, pPeerMac); goto LabelExit; } DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> LinkId = %d\n", LinkId)); pTDLS = TDLS_UAPSD_ENTRY_GET(pAd, LinkId); /* sanity check */ if (TDLS_UAPSD_IS_CONN_NOT_BUILT(pTDLS)) { DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> link is not yet built " "so we can not send a traffic ind to the peer!!!")); goto LabelExit; } /* init */ MAKE_802_3_HEADER(Header802_3, pTDLS->MacAddr, pAd->CurrentAddress, TDLS_ETHERTYPE); /* allocate buffer for transmitting message */ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) goto LabelExit; /* build the frame */ MakeOutgoingFrame(pOutBuffer, &TempLen, 1, &RemoteFrameType, END_OF_ARGS); FrameLen = FrameLen + TempLen; TDLS_UAPSD_TrafficRspBuild(pAd, pOutBuffer, &FrameLen, pTDLS, PeerToken); hex_dump("TDLS UAPSD Peer Traffic Response sending packet", pOutBuffer, FrameLen); /* need to set the power save mode of the peer to ACTIVE */ /* we will recover its mode after EOSP frame is received */ pMacEntry = MacTableLookup(pAd, pTDLS->MacAddr); if (pMacEntry == NULL) goto LabelExit; /* peer can not sleep for a while */ RTMP_PS_VIRTUAL_WAKEUP_PEER(pMacEntry); /* send the frame to the peer without AP's help */ TDLS_UAPSD_PKT_SEND_TO_PEER(pAd, Header802_3, pOutBuffer, FrameLen, pTDLS); /* hex_dump("TDLS traffic response send pack", pOutBuffer, FrameLen); */ NStatus = NDIS_STATUS_SUCCESS; /* free resources */ LabelExit: if (pOutBuffer != NULL) MlmeFreeMemory(pAd, pOutBuffer); return NStatus; }
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; STA_TR_ENTRY *tr_entry = NULL; MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, (" %s.\n", __FUNCTION__)); pMacEntry = MacTableLookup(pAd, pAddr); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry)) { tr_entry = &pAd->MacTab.tr_entry[pMacEntry->wcid]; if (tr_entry && tr_entry->PortSecured == WPA_802_1X_PORT_NOT_SECURED) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" wireless client is not ready !!!\n")); return ; } } NdisAcquireSpinLock(&pAd->ApCfg.ReptCliEntryLock); if (pAd->ApCfg.RepeaterCliSize >= MAX_EXT_MAC_ADDR_SIZE) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" Repeater Client Full !!!\n")); NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return ; } if (pAd->ApCfg.ApCliTab[apidx].Enable == FALSE) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" ApCli Interface is Down !!!\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))) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("\n receive mac :%02x:%02x:%02x:%02x:%02x:%02x !!!\n", pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5])); MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, (" duplicate Insert !!!\n")); NdisReleaseSpinLock(&pAd->ApCfg.ReptCliEntryLock); return ; } if (pReptCliEntry->CliEnable == FALSE) break; } if (CliIdx >= MAX_EXT_MAC_ADDR_SIZE) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_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); if (pAd->ApCfg.MACRepeaterOuiMode == 1) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_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); } 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); AsicInsertRepeaterEntry(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); }
/*! \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 == FC_TYPE_DATA) { #ifdef WSC_AP_SUPPORT WSC_CTRL *wsc_ctrl; /*WSC EAPOL PACKET */ pEntry = MacTableLookup(pAd, pFrame->Hdr.Addr2); if (pEntry && ((pEntry->bWscCapable) || (pAd->ApCfg.MBSSID[pEntry->func_tb_idx].wdev.AuthMode < Ndis802_11AuthModeWPA))) { /* WSC AP only can service one WSC STA in one WPS session. Forward this EAP packet to WSC SM if this EAP packets is from WSC STA that WSC AP services or WSC AP doesn't service any WSC STA now. */ wsc_ctrl = &pAd->ApCfg.MBSSID[pEntry->func_tb_idx].WscControl; if ((MAC_ADDR_EQUAL(wsc_ctrl->EntryAddr, pEntry->Addr) || MAC_ADDR_EQUAL(wsc_ctrl->EntryAddr, ZERO_MAC_ADDR)) && IS_ENTRY_CLIENT(pEntry) && (wsc_ctrl->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 != FC_TYPE_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; /* 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 */ 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; }
/* ======================================================================== 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); } }
/* ======================================================================== Routine Description: Handle peer DLS Request action frame. Arguments: pAd points to our adapter *pElem action frame Return Value: None Note: ======================================================================== */ VOID APPeerDlsReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *pElem) { PMAC_TABLE_ENTRY pDAEntry, pSAEntry; UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; UINT16 CapabilityInfo; UINT16 DLSTimeout; PUCHAR pOutBuffer = NULL; PFRAME_802_11 Fr; UINT16 Status; UINT32 FrameLen = 0; HEADER_802_11 DlsRspHdr; UCHAR Category = CATEGORY_DLS; UCHAR Action = ACTION_DLS_RESPONSE; UCHAR SupportedRatesLen = 0; UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES]; HT_CAPABILITY_IE HtCapability; UCHAR HtCapabilityLen; /* frame sanity check */ if (!PeerDlsReqSanity(pAd, pElem->Msg, pElem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeout, &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability)) { return; } /* check whether the source station is legal */ pSAEntry = MacTableLookup(pAd, SA); if (!pSAEntry) return; pSAEntry->bDlsInit = FALSE; /* check whether the destination station exists in our associated table */ pDAEntry = MacTableLookup(pAd, DA); if (!pDAEntry) Status = MLME_DEST_STA_NOT_IN_QBSS; else if (pDAEntry && (pDAEntry->apidx != pSAEntry->apidx)) Status = MLME_DEST_STA_NOT_IN_QBSS; else if (pDAEntry && !CLIENT_STATUS_TEST_FLAG(pDAEntry, fCLIENT_STATUS_WMM_CAPABLE)) Status = MLME_DEST_STA_IS_NOT_A_QSTA; else if (pDAEntry->WepStatus != pSAEntry->WepStatus) Status = MLME_QOS_UNSPECIFY; /* different security algorithm */ else if (!pAd->ApCfg.MBSSID[pSAEntry->apidx].bDLSCapable) Status = MLME_DLS_NOT_ALLOW_IN_QBSS; else Status = MLME_SUCCESS; if (pDAEntry) pDAEntry->bDlsInit = FALSE; /* forward DLS-Request to real destination */ Fr = (PFRAME_802_11)pElem->Msg; os_alloc_mem(pAd, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER); if(pOutBuffer == NULL) return; #ifdef CONFIG_HOTSPOT if (pAd->ApCfg.MBSSID[pSAEntry->apidx].HotSpotCtrl.L2Filter) Status = MLME_DLS_NOT_ALLOW_IN_QBSS; #endif /* If status is successful, forward DLS-Request frame to destination otherwise send DLS-Response with reason code to originator. */ #if 1 if (Status == MLME_SUCCESS) { NdisMoveMemory(Fr->Hdr.Addr1, DA, MAC_ADDR_LEN); NdisMoveMemory(Fr->Hdr.Addr2, pAd->ApCfg.MBSSID[pSAEntry->apidx].wdev.bssid, MAC_ADDR_LEN); NdisMoveMemory(Fr->Hdr.Addr3, SA, MAC_ADDR_LEN); NdisMoveMemory(pOutBuffer, pElem->Msg, pElem->MsgLen); FrameLen = pElem->MsgLen; } else { #else { Status = 0; /* for test */ #endif /* response error to source station */ MgtMacHeaderInit(pAd, &DlsRspHdr, SUBTYPE_ACTION, 0, SA, pAd->ApCfg.MBSSID[pSAEntry->apidx].wdev.if_addr, pAd->ApCfg.MBSSID[pSAEntry->apidx].wdev.bssid); /* Capability information and supported rate field are present only when status code is zero. */ MakeOutgoingFrame(pOutBuffer, (ULONG *) &FrameLen, sizeof(HEADER_802_11), &DlsRspHdr, 1, &Category, 1, &Action, 2, &Status, 6, SA, 6, DA, END_OF_ARGS); } /* transmit the frame */ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); os_free_mem(NULL, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("DLS - APPeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x " "with Status=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], Status)); } /* ======================================================================== Routine Description: Handle peer DLS Response action frame. Arguments: pAd points to our adapter *pElem action frame Return Value: None Note: ======================================================================== */ VOID APPeerDlsRspAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *pElem) { PMAC_TABLE_ENTRY pDAEntry, pSAEntry; UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; UINT16 CapabilityInfo; UINT16 StatusCode; PUCHAR pOutBuffer = NULL; PFRAME_802_11 Fr; UINT32 FrameLen = 0; UCHAR SupportedRatesLen = 0; UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR HtCapabilityLen; HT_CAPABILITY_IE HtCapability; /* frame sanity check */ if (! PeerDlsRspSanity(pAd, pElem->Msg, pElem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode, &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability)) { return; } DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x " "with StatusCode=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode)); /* check whether the source station is legal */ pSAEntry = MacTableLookup(pAd, SA); if (!pSAEntry) return; pDAEntry = MacTableLookup(pAd, DA); if (!pDAEntry) { DBGPRINT(RT_DEBUG_TRACE, ("Destination station does not exist!\n")); return; } pSAEntry->bDlsInit = FALSE; /* forward DLS-Request to real destination */ Fr = (PFRAME_802_11)pElem->Msg; os_alloc_mem(pAd, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER); if (pOutBuffer == NULL) return; /* fatal error, no available memory */ NdisMoveMemory(Fr->Hdr.Addr1, DA, MAC_ADDR_LEN); NdisMoveMemory(Fr->Hdr.Addr2, pAd->ApCfg.MBSSID[pSAEntry->apidx].wdev.bssid, MAC_ADDR_LEN); NdisMoveMemory(Fr->Hdr.Addr3, SA, MAC_ADDR_LEN); NdisMoveMemory(pOutBuffer, pElem->Msg, pElem->MsgLen); FrameLen = pElem->MsgLen; /* transmit the response frame */ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); os_free_mem(NULL, pOutBuffer); }
BOOLEAN PeerAssocReqCmmSanity( RTMP_ADAPTER *pAd, BOOLEAN isReassoc, VOID *Msg, int MsgLen, IE_LISTS *ie_lists) { CHAR *Ptr; PFRAME_802_11 Fr = (PFRAME_802_11)Msg; PEID_STRUCT eid_ptr; UCHAR Sanity = 0; UCHAR WPA1_OUI[4] = { 0x00, 0x50, 0xF2, 0x01 }; UCHAR WPA2_OUI[3] = { 0x00, 0x0F, 0xAC }; MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)NULL; HT_CAPABILITY_IE *pHtCapability = &ie_lists->HTCapability; pEntry = MacTableLookup(pAd, &Fr->Hdr.Addr2[0]); if (pEntry == NULL) return FALSE; COPY_MAC_ADDR(&ie_lists->Addr2[0], &Fr->Hdr.Addr2[0]); Ptr = (PCHAR)Fr->Octet; NdisMoveMemory(&ie_lists->CapabilityInfo, &Fr->Octet[0], 2); NdisMoveMemory(&ie_lists->ListenInterval, &Fr->Octet[2], 2); if (isReassoc) { NdisMoveMemory(&ie_lists->ApAddr[0], &Fr->Octet[4], 6); eid_ptr = (PEID_STRUCT) &Fr->Octet[10]; } else { eid_ptr = (PEID_STRUCT) &Fr->Octet[4]; } /* get variable fields from payload and advance the pointer */ while (((UCHAR *)eid_ptr + eid_ptr->Len + 1) < ((UCHAR *)Fr + MsgLen)) { switch(eid_ptr->Eid) { case IE_SSID: if (((Sanity&0x1) == 1)) break; if ((eid_ptr->Len <= MAX_LEN_OF_SSID)) { Sanity |= 0x01; NdisMoveMemory(&ie_lists->Ssid[0], eid_ptr->Octet, eid_ptr->Len); ie_lists->SsidLen = eid_ptr->Len; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - SsidLen = %d \n", ie_lists->SsidLen)); } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SSID\n")); return FALSE; } break; case IE_SUPP_RATES: if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0)) { Sanity |= 0x02; NdisMoveMemory(&ie_lists->SupportedRates[0], eid_ptr->Octet, eid_ptr->Len); DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - IE_SUPP_RATES., Len=%d. " "Rates[0]=%x\n", eid_ptr->Len, ie_lists->SupportedRates[0])); DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", ie_lists->SupportedRates[1], ie_lists->SupportedRates[2], ie_lists->SupportedRates[3], ie_lists->SupportedRates[4], ie_lists->SupportedRates[5], ie_lists->SupportedRates[6], ie_lists->SupportedRates[7])); ie_lists->SupportedRatesLen = eid_ptr->Len; } else { UCHAR RateDefault[8] = \ { 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c }; /* HT rate not ready yet. return true temporarily. rt2860c */ /*DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES\n")); */ Sanity |= 0x02; ie_lists->SupportedRatesLen = 8; NdisMoveMemory(&ie_lists->SupportedRates[0], RateDefault, 8); DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES., Len=%d\n", eid_ptr->Len)); } break; case IE_EXT_SUPP_RATES: if (eid_ptr->Len + ie_lists->SupportedRatesLen <= MAX_LEN_OF_SUPPORTED_RATES) { NdisMoveMemory(&ie_lists->SupportedRates[ie_lists->SupportedRatesLen], eid_ptr->Octet, eid_ptr->Len); ie_lists->SupportedRatesLen += eid_ptr->Len; } else { NdisMoveMemory(&ie_lists->SupportedRates[ie_lists->SupportedRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (ie_lists->SupportedRatesLen)); ie_lists->SupportedRatesLen = MAX_LEN_OF_SUPPORTED_RATES; } break; case IE_HT_CAP: if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE)) { NdisMoveMemory(pHtCapability, eid_ptr->Octet, SIZE_HT_CAP_IE); *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ ie_lists->ht_cap_len = SIZE_HT_CAP_IE; Sanity |= 0x10; DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_HT_CAP\n")); } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len)); } break; case IE_EXT_CAPABILITY: if (eid_ptr->Len >= sizeof(EXT_CAP_INFO_ELEMENT)) { NdisMoveMemory(&ie_lists->ExtCapInfo, eid_ptr->Octet, sizeof(EXT_CAP_INFO_ELEMENT)); DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_EXT_CAPABILITY!\n")); } break; case IE_WPA: /* same as IE_VENDOR_SPECIFIC */ case IE_WPA2: if (NdisEqualMemory(eid_ptr->Octet, WPS_OUI, 4)) { break; } /* Handle Atheros and Broadcom draft 11n STAs */ if (NdisEqualMemory(eid_ptr->Octet, BROADCOM_OUI, 3)) { switch (eid_ptr->Octet[3]) { case 0x33: if ((eid_ptr->Len-4) == sizeof(HT_CAPABILITY_IE)) { NdisMoveMemory(pHtCapability, &eid_ptr->Octet[4], SIZE_HT_CAP_IE); *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); #endif /* UNALIGNMENT_SUPPORT */ ie_lists->ht_cap_len = SIZE_HT_CAP_IE; } break; default: /* ignore other cases */ break; } } if (NdisEqualMemory(eid_ptr->Octet, RALINK_OUI, 3) && (eid_ptr->Len == 7)) { if (eid_ptr->Octet[3] != 0) ie_lists->RalinkIe = eid_ptr->Octet[3]; else ie_lists->RalinkIe = 0xf0000000; /* Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. */ break; } /* WMM_IE */ if (NdisEqualMemory(eid_ptr->Octet, WME_INFO_ELEM, 6) && (eid_ptr->Len == 7)) { ie_lists->bWmmCapable = TRUE; #ifdef UAPSD_SUPPORT if (pEntry) { UAPSD_AssocParse(pAd, pEntry, (UINT8 *)&eid_ptr->Octet[6], pAd->ApCfg.MBSSID[\ pEntry->apidx].UapsdInfo.bAPSDCapable); } #endif /* UAPSD_SUPPORT */ break; } if (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode < Ndis802_11AuthModeWPA) break; /* If this IE did not begins with 00:0x50:0xf2:0x01, it would be proprietary. So we ignore it. */ if (!NdisEqualMemory(eid_ptr->Octet, WPA1_OUI, sizeof(WPA1_OUI)) && !NdisEqualMemory(&eid_ptr->Octet[2], WPA2_OUI, sizeof(WPA2_OUI))) { DBGPRINT(RT_DEBUG_TRACE, ("Not RSN IE, maybe WMM IE!!!\n")); break; } if (/*(eid_ptr->Len <= MAX_LEN_OF_RSNIE) &&*/ (eid_ptr->Len >= MIN_LEN_OF_RSNIE)) { hex_dump("Received RSNIE in Assoc-Req", (UCHAR *)eid_ptr, eid_ptr->Len + 2); /* Copy whole RSNIE context */ NdisMoveMemory(&ie_lists->RSN_IE[0], eid_ptr, eid_ptr->Len + 2); ie_lists->RSNIE_Len =eid_ptr->Len + 2; } else { ie_lists->RSNIE_Len = 0; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - missing IE_WPA(%d)\n",eid_ptr->Len)); return FALSE; } break; #ifdef DOT11_VHT_AC case IE_VHT_CAP: if (eid_ptr->Len == sizeof(VHT_CAP_IE)) { NdisMoveMemory(&ie_lists->vht_cap, eid_ptr->Octet, sizeof(VHT_CAP_IE)); ie_lists->vht_cap_len = eid_ptr->Len; DBGPRINT(RT_DEBUG_TRACE, ("%s():IE_VHT_CAP\n", __FUNCTION__)); } else { DBGPRINT(RT_DEBUG_WARN, ("%s():wrong IE_VHT_CAP, eid->Len = %d\n", __FUNCTION__, eid_ptr->Len)); } #endif /* DOT11_VHT_AC */ default: break; } eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); } if ((Sanity&0x3) != 0x03) { DBGPRINT(RT_DEBUG_WARN, ("%s(): - missing mandatory field\n", __FUNCTION__)); return FALSE; } else { DBGPRINT(RT_DEBUG_TRACE, ("%s() - success\n", __FUNCTION__)); return TRUE; } }
/* ======================================================================== Routine Description: Handle peer DLS Response action frame. Arguments: pAd points to our adapter *pElem action frame Return Value: None Note: ======================================================================== */ VOID APPeerDlsRspAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *pElem) { PMAC_TABLE_ENTRY pDAEntry, pSAEntry; UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; UINT16 CapabilityInfo; UINT16 StatusCode; PUCHAR pOutBuffer = NULL; PFRAME_802_11 Fr; UINT32 FrameLen = 0; UCHAR SupportedRatesLen; UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR HtCapabilityLen; HT_CAPABILITY_IE HtCapability; /* frame sanity check */ if (! PeerDlsRspSanity(pAd, pElem->Msg, pElem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode, &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability)) { return; } DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x " "with StatusCode=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode)); /* check whether the source station is legal */ pSAEntry = MacTableLookup(pAd, SA); if (!pSAEntry) return; pDAEntry = MacTableLookup(pAd, DA); if (!pDAEntry) { DBGPRINT(RT_DEBUG_TRACE, ("Destination station does not exist!\n")); return; } pSAEntry->bDlsInit = FALSE; /* forward DLS-Request to real destination */ Fr = (PFRAME_802_11)pElem->Msg; pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); if (pOutBuffer == NULL) return; /* fatal error, no available memory */ NdisMoveMemory(Fr->Hdr.Addr1, DA, MAC_ADDR_LEN); NdisMoveMemory(Fr->Hdr.Addr2, pAd->ApCfg.MBSSID[pSAEntry->apidx].Bssid, MAC_ADDR_LEN); NdisMoveMemory(Fr->Hdr.Addr3, SA, MAC_ADDR_LEN); NdisMoveMemory(pOutBuffer, pElem->Msg, pElem->MsgLen); FrameLen = pElem->MsgLen; /* transmit the response frame */ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); kfree(pOutBuffer); }
BOOLEAN PMF_PerformTxFrameAction( IN PRTMP_ADAPTER pAd, OUT PNDIS_PACKET pPacket) { PHEADER_802_11 pHeader_802_11; PACKET_INFO PacketInfo; PUCHAR pSrcBufVA; UINT SrcBufLen; UINT8 TXWISize = pAd->chipCap.TXWISize; INT FrameType; INT ret; PMAC_TABLE_ENTRY pEntry = NULL; RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); if (pSrcBufVA == NULL) return NORMAL_FRAME; pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWISize); #ifdef CONFIG_AP_SUPPORT pEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); #endif /* CONFIG_AP_SUPPORT */ FrameType = PMF_RobustFrameClassify( (PHEADER_802_11)pHeader_802_11, (PUCHAR)( ((PUCHAR) pHeader_802_11) + LENGTH_802_11), (SrcBufLen - LENGTH_802_11 - TXINFO_SIZE - TXWISize), (PUCHAR) pEntry, FALSE); switch (FrameType) { case ERROR_FRAME: DBGPRINT(RT_DEBUG_ERROR, ("[PMF]%s: ERROR FRAME\n", __FUNCTION__)); return FALSE; case NORMAL_FRAME: case NOT_ROBUST_GROUP_FRAME: case NOT_ROBUST_UNICAST_FRAME: break; case UNICAST_ROBUST_FRAME: { pHeader_802_11->FC.Wep = 1; /* Format: Mac header|CCMP header|Data|MIC|FCS */ skb_put(GET_OS_PKT_TYPE(pPacket), LEN_CCMP_HDR + LEN_CCMP_MIC); RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); if (pSrcBufVA == NULL) return NORMAL_FRAME; pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWISize); ret = PMF_EncryptUniRobustFrameAction(pAd, pHeader_802_11, (SrcBufLen - TXINFO_SIZE - TXWISize)); break; } case GROUP_ROBUST_FRAME: { ret = PMF_EncapBIPAction(pAd, pHeader_802_11, (SrcBufLen - TXINFO_SIZE - TXWISize)); break; } } if (ret == PMF_STATUS_SUCCESS) return TRUE; else return FALSE; }