📄 rtmp_data.c
字号:
// 3. Order bit: A-Ralink or HTC+ if (pHeader->FC.Order) {#ifdef AGGREGATION_SUPPORT if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))) { RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK); } else#endif // AGGREGATION_SUPPORT // {#ifdef DOT11_N_SUPPORT RX_BLK_SET_FLAG(pRxBlk, fRX_HTC); // skip HTC contorl field pRxBlk->pData += 4; pRxBlk->DataSize -= 4;#endif // DOT11_N_SUPPORT // } } // 4. skip HW padding if (pRxD->L2PAD) { // just move pData pointer // because DataSize excluding HW padding RX_BLK_SET_FLAG(pRxBlk, fRX_PAD); pRxBlk->pData += 2; }#ifdef DOT11_N_SUPPORT if (pRxD->BA) { RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU); }#endif // DOT11_N_SUPPORT // // // Case I Process Broadcast & Multicast data frame // if (pRxD->Bcast || pRxD->Mcast) { INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount); // Drop Mcast/Bcast frame with fragment bit on if (pHeader->FC.MoreFrag) { // release packet RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); return; } // Filter out Bcast frame which AP relayed for us if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress)) { // release packet RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); return; } Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID); return; } else if (pRxD->U2M) { pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;#ifdef QOS_DLS_SUPPORT if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS)) { MAC_TABLE_ENTRY *pDlsEntry = NULL; pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE); if(pDlsEntry) Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI); } else#endif // QOS_DLS_SUPPORT // if (ADHOC_ON(pAd)) { pEntry = MacTableLookup(pAd, pHeader->Addr2); if (pEntry) Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI); } Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI); pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0); pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1); pAd->RalinkCounters.OneSecRxOkDataCnt++; if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0))) { // re-assemble the fragmented packets // return complete frame (pRxPacket) or NULL bFragment = TRUE; pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk); } if (pRxPacket) { pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID]; // process complete frame if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled)) { // Minus MIC length pRxBlk->DataSize -= 8; // For TKIP frame, calculate the MIC value if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE) { return; } } STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID); return; } else { // just return // because RTMPDeFragmentDataFrame() will release rx packet, // if packet is fragmented return; } } ASSERT(0); // release packet RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);}VOID STAHandleRxMgmtFrame( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk){ PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD); PRXWI_STRUC pRxWI = pRxBlk->pRxWI; PHEADER_802_11 pHeader = pRxBlk->pHeader; PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket; do { /* check if need to resend PS Poll when received packet with MoreData = 1 */ if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) { /* for UAPSD, all management frames will be VO priority */ if (pAd->CommonCfg.bAPSDAC_VO == 0) { /* non-UAPSD delivery-enabled AC */ RTMP_PS_POLL_ENQUEUE(pAd); } } /* TODO: if MoreData == 0, station can go to sleep */ // We should collect RSSI not only U2M data but also my beacon if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)) && (pAd->RxAnt.EvaluatePeriod == 0)) { Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI); pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0); pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1); } // First check the size, it MUST not exceed the mlme queue size if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) { DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount)); break; } REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal); } while (FALSE); RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);}VOID STAHandleRxControlFrame( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk){#ifdef DOT11_N_SUPPORT PRXWI_STRUC pRxWI = pRxBlk->pRxWI;#endif // DOT11_N_SUPPORT // PHEADER_802_11 pHeader = pRxBlk->pHeader; PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket; switch (pHeader->FC.SubType) { case SUBTYPE_BLOCK_ACK_REQ:#ifdef DOT11_N_SUPPORT { CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader); } break;#endif // DOT11_N_SUPPORT // case SUBTYPE_BLOCK_ACK: case SUBTYPE_ACK: default: break; } RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);}/* ======================================================================== Routine Description: Process RxDone interrupt, running in DPC level Arguments: pAd Pointer to our adapter Return Value: None IRQL = DISPATCH_LEVEL Note: This routine has to maintain Rx ring read pointer. Need to consider QOS DATA format when converting to 802.3 ========================================================================*/BOOLEAN STARxDoneInterruptHandle( IN PRTMP_ADAPTER pAd, IN BOOLEAN argc){ NDIS_STATUS Status; UINT32 RxProcessed, RxPending; BOOLEAN bReschedule = FALSE; RT28XX_RXD_STRUC *pRxD; UCHAR *pData; PRXWI_STRUC pRxWI; PNDIS_PACKET pRxPacket; PHEADER_802_11 pHeader; RX_BLK RxCell; RxProcessed = RxPending = 0; // process whole rx ring while (1) { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST) || !RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP)) { break; } RxProcessed ++; // test // 1. allocate a new data packet into rx ring to replace received packet // then processing the received packet // 2. the callee must take charge of release of packet // 3. As far as driver is concerned , // the rx packet must // a. be indicated to upper layer or // b. be released if it is discarded pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending); if (pRxPacket == NULL) { // no more packet to process break; } // get rx ring descriptor pRxD = &(RxCell.RxD); // get rx data buffer pData = GET_OS_PKT_DATAPTR(pRxPacket); pRxWI = (PRXWI_STRUC) pData; pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;#ifdef RT_BIG_ENDIAN RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE); RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);#endif // build RxCell RxCell.pRxWI = pRxWI; RxCell.pHeader = pHeader; RxCell.pRxPacket = pRxPacket; RxCell.pData = (UCHAR *) pHeader; RxCell.DataSize = pRxWI->MPDUtotalByteCount; RxCell.Flags = 0; // Increase Total receive byte counter after real data received no mater any error or not pAd->RalinkCounters.ReceivedByteCount += pRxWI->MPDUtotalByteCount; pAd->RalinkCounters.OneSecReceivedByteCount += pRxWI->MPDUtotalByteCount; pAd->RalinkCounters.RxCount ++; INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount); if (pRxWI->MPDUtotalByteCount < 14) Status = NDIS_STATUS_FAILURE; if (MONITOR_ON(pAd)) { send_monitor_packets(pAd, &RxCell); break; } /* STARxDoneInterruptHandle() is called in rtusb_bulk.c */#ifdef RALINK_ATE if (ATE_ON(pAd)) { pAd->ate.RxCntPerSec++; ATESampleRssi(pAd, pRxWI);#ifdef RALINK_28xx_QA if (pAd->ate.bQARxStart == TRUE) { /* (*pRxD) has been swapped in GetPacketFromRxRing() */ ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader); }#endif // RALINK_28xx_QA // RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS); continue; }#endif // RALINK_ATE // // Check for all RxD errors Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD); // Handle the received frame if (Status == NDIS_STATUS_SUCCESS) { switch (pHeader->FC.Type) { // CASE I, receive a DATA frame case BTYPE_DATA: { // process DATA frame STAHandleRxDataFrame(pAd, &RxCell); } break; // CASE II, receive a MGMT frame case BTYPE_MGMT: { STAHandleRxMgmtFrame(pAd, &RxCell); } break; // CASE III. receive a CNTL frame case BTYPE_CNTL: { STAHandleRxControlFrame(pAd, &RxCell); } break; // discard other type default: RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); break; } } else { pAd->Counters8023.RxErrors++; // discard this frame RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE); } } return bReschedule;}/* ======================================================================== Routine Description: Arguments: pAd Pointer to our adapter IRQL = DISPATCH_LEVEL ========================================================================*/VOID RTMPHandleTwakeupInterrupt( IN PRTMP_ADAPTER pAd){ AsicForceWakeup(pAd, FALSE);}/*========================================================================Routine Description: Early checking and OS-depened parsing for Tx packet send to our STA driver.Arguments: NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd. PPNDIS_PACKET ppPacketArray The packet array need to do transmission. UINT NumberOfPackets Number of packet in packet array. Return Value: NONE Note: This function do early checking and classification for send-out packet. You only can put OS-depened & STA related code in here.========================================================================*/VOID STASendPackets( IN NDIS_HANDLE MiniportAdapterContext, IN PPNDIS_PACKET ppPacketArray, IN UINT NumberOfPackets){ UINT Index; PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) MiniportAdapterContext; PNDIS_PACKET pPacket; BOOLEAN allowToSend = FALSE; for (Index = 0; Index < NumberOfPackets; Index++) { pPacket = ppPacketArray[Index]; do { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) { // Drop send request since hardware is in reset state break; } else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) { // Drop send request since there are no physical connection yet break; } else { // Record that orignal packet source is from NDIS layer,so that // later on driver knows how to release this NDIS PACKET#ifdef QOS_DLS_SUPPORT MAC_TABLE_ENTRY *pEntry; PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket); pEntry = MacTableLookup(pAd, pSrcBufVA); if (pEntry && (pEntry->ValidAsDls == TRUE)) { RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid); } else#endif // QOS_DLS_SUPPORT // RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING); pAd->RalinkCounters.PendingNdisPacketCount++; allowToSend = TRUE; } } while(FALSE); if (allowToSend == TRUE) STASendPacket(pAd, pPacket); else RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -