rtmp_data.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,485 行 · 第 1/5 页
C
1,485 行
#define REPORT_MGMT_FRAME_TO_MLME(_pAd, _pFrame, _FrameSize, _Rssi, _Offset) \
{ \
ULONG High32TSF, Low32TSF; \
RTMP_IO_READ32(_pAd, TXRX_CSR13, &High32TSF); \
RTMP_IO_READ32(_pAd, TXRX_CSR12, &Low32TSF); \
MlmeEnqueueForRecv(_pAd, High32TSF, Low32TSF, (UCHAR)_Rssi, _FrameSize, _pFrame, _Offset); \
}
/*
========================================================================
Routine Description:
Process RxDone interrupt, running in DPC level
Arguments:
pAdapter Pointer to our adapter
Return Value:
None
Note:
This routine has to maintain Rx ring read pointer.
Need to consider QOS DATA format when converting to 802.3
========================================================================
*/
VOID RTMPHandleRxDoneInterrupt(
IN PRTMP_ADAPTER pAd)
{
PRXD_STRUC pRxD;
#ifdef BIG_ENDIAN
PRXD_STRUC pDestRxD;
RXD_STRUC RxD;
#endif
PHEADER_802_11 pHeader;
PUCHAR pData;
USHORT DataSize, Msdu2Size;
PUCHAR pDA, pSA;
UCHAR Header802_3[14];
INT Count, apidx = MAIN_MBSSID, i;
MAC_TABLE_ENTRY *pEntry = NULL;
NDIS_802_11_PRIVACY_FILTER Privacy;
WPA_STATE WpaState;
struct net_device *net_dev = pAd->net_dev;
BOOLEAN bWdsPacket = FALSE;
UCHAR Offset = 0;
ULONG IrqFlags;
BOOLEAN bQoS;
UCHAR OldPwrMgmt = PWR_ACTIVE;
#ifdef APCLI_SUPPORT
INT ApCliIdx = MAIN_MBSSID;
BOOLEAN bApCliPacket = FALSE;
#endif
// Make sure Rx ring resource won't be used by other threads
RTMP_SEM_LOCK(&pAd->RxRingLock, IrqFlags);
DBGPRINT(RT_DEBUG_INFO, "RTMPHandleRxDoneInterrupt --->\n");
for (Count=0; Count<MAX_RX_PROCESS; Count++)
{
#ifndef BIG_ENDIAN
// Point to Rx indexed rx ring descriptor
pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].AllocVa;
#else
pDestRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].AllocVa;
RxD = *pDestRxD;
pRxD = &RxD;
RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
#endif
// In case of false alarm or processed at last instance
if (pRxD->Owner != DESC_OWN_HOST)
break;
// beak out this "do {...} while FALSE" loop whenever RX frame error without indicating
// to upper layer
do
{
pci_unmap_single(pAd->pPci_Dev, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
pData = (PUCHAR) (pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa);
pHeader = (PHEADER_802_11) pData;
#ifdef BIG_ENDIAN
RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, FALSE);
#endif
// Increase Total receive byte counter after real data received no mater any error or not
pAd->RalinkCounters.ReceivedByteCount += pRxD->DataByteCnt;
pAd->RalinkCounters.RxCount ++;
// Check for all RxD errors
if (RTMPCheckRxError(pRxD) != NDIS_STATUS_SUCCESS)
{
if (pRxD->U2M && pRxD->CipherErr)
{
if ((pRxD->CipherAlg == CIPHER_TKIP) && (pRxD->CipherErr == 2)) //MIC error
{
pEntry = PACInquiry(pAd, pHeader->Addr2, &Privacy, &WpaState);
if (pEntry)
{
HandleCounterMeasure(pAd, pEntry);
}
}
DBGPRINT(RT_DEBUG_ERROR, "Rx u2me DATA Cipger Err(len=%d,Alg=%d,keyidx=%d,ciphererr=%d)\n",
pRxD->DataByteCnt, pRxD->CipherAlg, pRxD->KeyIndex, pRxD->CipherErr);
}
pAd->Counters8023.RxErrors++;
break; // give up this frame
}
pAd->WlanCounters.ReceivedFragmentCount++;
#ifdef RALINK_ATE
pAd->ate.RxCntPerSec++;
#endif
// All frames to AP are directed except probe_req. IEEE 802.11/1999 - p.463
// Do this before checking "duplicate frame".
// 2003-08-20 accept BEACON to decide if OLBC (Overlapping Legacy BSS Condition) happens
// TODO: consider move this code to be inside "APCheckRxError()"
if (pRxD->U2M)
{
if (pHeader->FC.Type == BTYPE_DATA)
{
CHAR RealRssi;
RealRssi = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpRssi, RSSI_NO_1);
pAd->PortCfg.LastRssi = RealRssi + pAd->BbpRssiToDbmDelta;
pAd->PortCfg.AvgRssiX8 = (pAd->PortCfg.AvgRssiX8 - pAd->PortCfg.AvgRssi) + pAd->PortCfg.LastRssi;
pAd->PortCfg.AvgRssi = pAd->PortCfg.AvgRssiX8 >> 3;
pAd->PortCfg.NumOfAvgRssiSample ++;
if ((pAd->RfIcType == RFIC_5325) || (pAd->RfIcType == RFIC_2529))
{
pAd->PortCfg.LastRssi2 = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpSignal, RSSI_NO_2) + pAd->BbpRssiToDbmDelta;
pAd->PortCfg.AvgRssi2X8 = (pAd->PortCfg.AvgRssi2X8 - pAd->PortCfg.AvgRssi2) + pAd->PortCfg.LastRssi2;
pAd->PortCfg.AvgRssi2 = pAd->PortCfg.AvgRssi2X8 >> 3;
}
// Gather PowerSave information from all valid DATA frames. IEEE 802.11/1999 p.461
if (pHeader->FC.PwrMgmt)
OldPwrMgmt = PsIndicate(pAd, pHeader->Addr2, pAd->PortCfg.LastRssi, PWR_SAVE);
else
OldPwrMgmt = PsIndicate(pAd, pHeader->Addr2, pAd->PortCfg.LastRssi, PWR_ACTIVE);
#ifdef APCLI_SUPPORT
// gather U2M data frame from ApCli interface to update AvgRSSI
if (pHeader->FC.FrDs == 1 && pHeader->FC.ToDs == 0)
{
for (i = 0; i < MAX_APCLI_ENTRY; i++)
{
//BSSID match the ApCliBssid ?(from a valid AP)
if ((pAd->ApCliTab.ApCliEntry[i].Valid== TRUE)
&& (MAC_ADDR_EQUAL(&pAd->ApCliTab.ApCliEntry[i].ApCliBssid, &pHeader->Addr2)))
{
pAd->ApCliTab.ApCliEntry[i].NumOfAvgRssiSample ++;
break;
}
}
}
#endif
}
// ignore all CNTL frames except PS-POLL
else if ((pHeader->FC.Type == BTYPE_CNTL) && (pHeader->FC.SubType != SUBTYPE_PS_POLL))
break;
}
else // B/M-cast frame
{
#ifdef RALINK_ATE
if(pAd->ate.Mode != ATE_APSTART)
{
CHAR RealRssi;
RealRssi = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpRssi, RSSI_NO_1);
pAd->PortCfg.LastRssi = RealRssi + pAd->BbpRssiToDbmDelta;
pAd->PortCfg.AvgRssiX8 = (pAd->PortCfg.AvgRssiX8 - pAd->PortCfg.AvgRssi) + pAd->PortCfg.LastRssi;
pAd->PortCfg.AvgRssi = pAd->PortCfg.AvgRssiX8 >> 3;
if ((pAd->RfIcType == RFIC_5325) || (pAd->RfIcType == RFIC_2529))
{
pAd->PortCfg.LastRssi2 = ConvertToRssi(pAd, (UCHAR)pRxD->PlcpSignal, RSSI_NO_2) + pAd->BbpRssiToDbmDelta;
pAd->PortCfg.AvgRssi2X8 = (pAd->PortCfg.AvgRssi2X8 - pAd->PortCfg.AvgRssi2) + pAd->PortCfg.LastRssi2;
pAd->PortCfg.AvgRssi2 = pAd->PortCfg.AvgRssi2X8 >> 3;
}
}
#endif // RALINK_ATE
if ((pHeader->FC.Type == BTYPE_MGMT) &&
((pHeader->FC.SubType == SUBTYPE_BEACON) || (pHeader->FC.SubType == SUBTYPE_PROBE_REQ)))
{
#ifdef APCLI_SUPPORT
// gather beacon from ApCli interface to update AvgRSSI
if (pHeader->FC.SubType == SUBTYPE_BEACON)
{
for (i = 0; i < MAX_APCLI_ENTRY; i++)
{
//BSSID match the ApCliBssid ?(from a valid AP)
if ((pAd->ApCliTab.ApCliEntry[i].Valid== TRUE)
&& (MAC_ADDR_EQUAL(&pAd->ApCliTab.ApCliEntry[i].ApCliBssid, &pHeader->Addr2)))
{
pAd->ApCliTab.ApCliEntry[i].NumOfAvgRssiSample ++;
break;
}
}
}
#endif
}
else
{
#ifndef APCLI_SUPPORT
break; // give up this frame
#else
// It is possible to receive the multicast packet when in AP Client mode
// Such as a broadcast from AP2 to AP1, address1 is ffffff, address2 is AP2 bssid, addr3 is sta4 mac address
PUCHAR pRemovedLLCSNAP;
for(i = 0; i < MAX_APCLI_ENTRY; i++)
{
//BSSID match the ApCliBssid ?(from a valid AP)
if((pAd->ApCliTab.ApCliEntry[i].Valid == TRUE)
&& (pAd->ApCliTab.ApCliEntry[i].Enable == TRUE)
&& (MAC_ADDR_EQUAL(&pAd->ApCliTab.ApCliEntry[i].ApCliBssid, &pHeader->Addr2)))
{
net_dev = pAd->ApCliTab.ApCliEntry[i].dev;
DBGPRINT(RT_DEBUG_INFO, "APCLI Multicast packet from (apcli%d)!!!\n", i);
break;
}
}
if (i == MAX_APCLI_ENTRY)
{
DBGPRINT(RT_DEBUG_INFO, "APCLI packet, but not our APCLI group, give it up!!!\n");
break;// give up this frame
}
// Filter out Bcast frame which AP relayed for us
// Multicast packet send from AP1 , received by AP2 and send back to AP1, drop this frame
if (MAC_ADDR_EQUAL(pHeader->Addr3, pAd->ApCliTab.ApCliEntry[i].CurrentAddress))
break;// give up this frame
// This frame must be from DS when in AP Client mode
if (pHeader->FC.FrDs == 0)
break;// give up this frame
// Use software to decrypt the encrypted frame
// Because this received frame isn't my BSS frame, Asic passed to driver without decrypting it.
// Then its "CipherAlg" in RxD would be marked as "NONE".
if ((pRxD->MyBss == 0) && (pRxD->CipherAlg == CIPHER_NONE) && (pHeader->FC.Wep == 1))
{
// handle WEP decryption
if(pAd->PortCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11WEPEnabled)
{
UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
if (RTMPDecryptData(pAd, pPayload, pRxD->DataByteCnt - LENGTH_802_11) == FALSE)
{
printk("ERROR : Software decrypt WEP data fails.\n");
break;// give up this frame
}
else
pRxD->DataByteCnt -= 8; //Minus IV[4] & ICV[4]
#ifdef RTL865X_SOC
//printk("RTMPDecryptData WEP data Complete \n");
#else
DBGPRINT(RT_DEBUG_INFO, "RTMPDecryptData WEP data Complete \n");
#endif
}
// handle TKIP decryption
else if(pAd->PortCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11Encryption2Enabled)
{
if (RTMPSoftDecryptTKIP(pAd, pData, pRxD->DataByteCnt, 0, pAd->ApCliTab.ApCliEntry[i].SharedKey))
{
#ifdef RTL865X_SOC
//printk("RTMPSoftDecryptTKIP Complete \n");
#else
DBGPRINT(RT_DEBUG_INFO, "RTMPSoftDecryptTKIP Complete \n");
#endif
pRxD->DataByteCnt -= 20; //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
}
else
{
printk("ERROR : RTMPSoftDecryptTKIP Failed\n");
break; // give up this frame
}
}
// handle AES decryption
else if(pAd->PortCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11Encryption3Enabled)
{
if (RTMPSoftDecryptAES(pAd, pData, pRxD->DataByteCnt , pAd->ApCliTab.ApCliEntry[i].SharedKey))
{
#ifdef RTL865X_SOC
//printk("RTMPSoftDecryptAES Complete \n");
#else
DBGPRINT(RT_DEBUG_INFO, "RTMPSoftDecryptAES Complete \n");
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?