📄 hal.c
字号:
paucPayloadBuf,
psPktDesc
);
// Adjust the payload length.
ulLength -= (DAT_SIZE_ETHERNET_HDR - DAT_SIZE_LLC_AND_SNAP_HDR);
// Set UMI_DATA structure.
psData->u32MSDUtag = ulAddrTarget + sizeof(UMI_DATA);
psData->u16MSDUlength = (uint16)ulLength;
psData->u16AccessProtocol = (uint16)ulPriority;
psData->sWDSA.au8Addr[0] = 0;
psData->sWDSA.au8Addr[1] = 0;
psData->sWDSA.au8Addr[2] = 0;
psData->sWDSA.au8Addr[3] = 0;
psData->sWDSA.au8Addr[4] = 0;
psData->sWDSA.au8Addr[5] = 0;
// Adjust Target address.
ulAddrTarget += HAL_IMEM_BASE;
// Write Tx buffer (UMI_DATA + payload) to the IMEM.
vHALwriteIMem( psHAL, ulAddrTarget, (PULONG)psData, ulLength + sizeof(UMI_DATA) );
// Tx ready, generate interrupt to Target.
vHALinterruptDevice( psHAL, 1, HAL_BIT_interrupt_tx_data0 + ulBufferIndex );
DBG_LEV3(("Send packet, buffer = 0x%lx, index = %lu\n", (ULONG)psData, ulBufferIndex));
iStatus = 1;
}
}
return( iStatus );
}
//-----------------------------------------------------------------------------
//
// NAME vHALsendComplete
//
// PARAMETERS psHAL Pointer to HAL context.
// ulBitmapTxBuf Bitmap of Tx buffers.
// bit0 - Tx buffer 0, bit1 - Tx buffer 1, ..
// 1: Tx data done.
//
// DESCRIPTION Process Tx complete, set buffer available bit.
//
//-----------------------------------------------------------------------------
VOID
vHALsendComplete( IN PHAL_CONTEXT psHAL, IN ULONG ulBitmapTxBuf )
{
PEND_CONTEXT psAdapter = psHAL->psAdapter;
ULONG ulBufferIndex;
static ULONG ulExpIdx = 0;
DBG_LEV3(("Process Tx complete, buffer bitmap = 0x%02x\n", ulBitmapTxBuf));
TRACE(TRACE_CFSD_NDHAL, ulBitmapTxBuf);
// Set Tx buffer available flag.
for ( ulBufferIndex = 0; ulBufferIndex < psHAL->ulTxBufNum; ulBufferIndex++ )
{
if ( (ulBitmapTxBuf >> ulBufferIndex) & 0x1 )
{
TRACE(TRACE_CFSD_NDHAL, ulBufferIndex);
psHAL->sTxBuf[ulBufferIndex].boBufAvail = TRUE;
ulExpIdx = (ulExpIdx + 1) % psHAL->ulTxBufNum;
}
}
if ( psAdapter->boSendNoResourcesFlag )
{
TRACE(TRACE_CFSD_NDHAL, 0);
psAdapter->boSendNoResourcesFlag = FALSE;
// refill imem
// push to imem as many as possible
while (bHAL_PickAndSendPacket(psAdapter) == TRUE);
}
// MIC error handling, disassociate after sending the next 802.1X EAPOL packet.
if ( psAdapter->sWlan.eMicErrorState == MICERR_TXEAPOL )
{
psAdapter->sWlan.eMicErrorState = MICERR_DISASSOC;
psAdapter->sWlan.ulMicErrorTimer = 0;
psAdapter->sWlan.boNonEAPOLPktFilter = FALSE;
// Set a timer (50ms) to disconnect after transmitting the MIC failure indication
NdisMSetTimer( &psAdapter->sMicFailTimer, 50 );
}
}
//-----------------------------------------------------------------------------
//
// NAME vHALreceivePacket
//
// PARAMETERS psHAL Pointer to HAL context.
// ulBitmapRxBuf Bitmap of Rx buffers.
// bit0 - Rx buffer 0, bit1 - Rx buffer 1, ..
// 1: Rx data ready.
//
// DESCRIPTION Process Rx packet.
//
//-----------------------------------------------------------------------------
VOID
vHALreceivePacket( IN PHAL_CONTEXT psHAL, IN ULONG ulBitmapRxBuf )
{
PEND_CONTEXT psAdapter = psHAL->psAdapter;
PDAT_STATISTICS psStats = &psAdapter->sStats;
ULONG ulBufferIndex, ulLoopIndex;
PUCHAR pucDataBuffer;
PUCHAR pucDataBuffer_align;
ULONG ulAddrTarget;
ULONG bufsize = psHAL->ulTxRxBufSize + 31;
PUCHAR pucPayload = NULL;
UMI_DATA *psData;
ULONG ulLength;
int iStatus;
PNDIS_PACKET psPacket;
PNDIS_BUFFER psBuffer;
ULONG ulAccept;
DBG_LEV3(("Process Rx packet, buffer bitmap = 0x%02x\n", ulBitmapRxBuf));
TRACE(TRACE_CFSD_NDHAL, ulBitmapRxBuf);
for ( ulLoopIndex = 0, ulBufferIndex = psHAL->ulRxBufferIndex;
ulLoopIndex < psHAL->ulRxBufNum;
ulLoopIndex++, ulBufferIndex = (ulBufferIndex + 1) % psHAL->ulRxBufNum )
{
if ( psHAL->eState != HAL_RUNNING )
{
DBG_LEV0(("ERROR: Attempt to receive packet in invalid state, %d.\n", psHAL->eState));
break;
}
if ( (ulBitmapRxBuf >> ulBufferIndex) & 0x1 )
{
// Allocate memory for Rx packet.
iStatus = NdisAllocateMemoryWithTag( &pucDataBuffer, psHAL->ulTxRxBufSize + 31, 'brAC' );
pucDataBuffer_align = (PUCHAR)(((ULONG)pucDataBuffer + 31) & (~31));
if ( iStatus != NDIS_STATUS_SUCCESS )
{
DBG_LEV1(("Ran out of memory resources.\n"));
psStats->ulRxResourceError++;
ASSERT (FALSE);
}
else
{
ulAddrTarget = psHAL->aulRxBufferAddr[ulBufferIndex];
// Adjust Target address.
ulAddrTarget += HAL_IMEM_BASE;
// Read the Rx data header.
vHALreadIMem( psHAL, ulAddrTarget, (PULONG)pucDataBuffer_align, HAL_IMEM_RX_BUFFER_HEAD );
// Get the payload length.
psData = (UMI_DATA *)pucDataBuffer_align;
ulLength = psData->u16MSDUlength;
// Check the status and length.
if ( psData->u16Status != UMI_OK || ulLength > psHAL->ulTxRxBufSize - sizeof(UMI_DATA) )
{
ulAccept = 0;
psStats->ulTotalPktsRxedError++;
DBG_LEV0(("status or length bad! status = %u, length = %lu\n",
psData->u16Status,
ulLength));
}
else
{
// Read the payload.
pucPayload = pucDataBuffer_align + sizeof(UMI_DATA);
pucPayload += psData->u32AlignmentOffset;
// Check whether the filter is set to receive this type of packet.
if ( DAT_IS_DIRECTED_PKT( psData->sDA.au8Addr ) )
{
psStats->ulDirectedPktsRxed++;
psStats->ullDirectedBytesRxed += ulLength;
psStats->ullDirectedBytesRxed -= DAT_SIZE_LLC_AND_SNAP_HDR;
ulAccept = psAdapter->ulPacketFilter & NDIS_PACKET_TYPE_DIRECTED;
DBG_LEV3(("Directed pkt filter result = %lu, filter = %lu\n",
ulAccept, psAdapter->ulPacketFilter));
}
else if ( DAT_IS_BROADCAST_PKT( psData->sDA.au8Addr ) )
{
psStats->ulBroadcastPktsRxed++;
psStats->ullBroadcastBytesRxed += ulLength;
psStats->ullBroadcastBytesRxed -= DAT_SIZE_LLC_AND_SNAP_HDR;
ulAccept = psAdapter->ulPacketFilter & NDIS_PACKET_TYPE_BROADCAST;
DBG_LEV3(("Broadcast pkt filter result = %lu, filter = %lu\n",
ulAccept, psAdapter->ulPacketFilter));
}
else
{
psStats->ulMulticastPktsRxed++;
psStats->ullMulticastBytesRxed += ulLength;
psStats->ullMulticastBytesRxed -= DAT_SIZE_LLC_AND_SNAP_HDR;
// Check for both multicast bits
ulAccept = psAdapter->ulPacketFilter &
(NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_MULTICAST);
DBG_LEV3(("Multicast pkt filter result = %lu, filter = %lu\n",
ulAccept, psAdapter->ulPacketFilter));
}
}
if ( !ulAccept )
{
// Filter the packet.
DBG_LEV1(("Filter this packet.\n"));
NdisFreeMemory( pucDataBuffer, bufsize, 0 );
//NdisFreeMemory( pucDataBuffer, psHAL->ulTxRxBufSize , 0 );
}
else
{
// Allocate NDIS packet.
NdisAllocatePacket( &iStatus, &psPacket, psAdapter->hRxPacketPool );
if ( iStatus != NDIS_STATUS_SUCCESS )
{
DBG_LEV1(("Ran out of NDIS packet resources.\n"));
psStats->ulRxResourceError++;
NdisFreeMemory( pucDataBuffer, bufsize , 0 );
}
else
{
// Save the memory base to psPacket->MiniportReserved.
*(PULONG)(psPacket->MiniportReserved) = (ULONG)pucDataBuffer;
// Set Ethernet header.
NDIS_SET_PACKET_HEADER_SIZE( psPacket, DAT_SIZE_ETHERNET_HDR );
// Adjust the Rx packet base and length.
pucPayload -= (DAT_SIZE_ETHERNET_HDR - DAT_SIZE_LLC_AND_SNAP_HDR);
ulLength += (DAT_SIZE_ETHERNET_HDR - DAT_SIZE_LLC_AND_SNAP_HDR);
ETH_COPY_NETWORK_ADDRESS( DAT_ETHERNET_DEST(pucPayload), psData->sDA.au8Addr );
ETH_COPY_NETWORK_ADDRESS( DAT_ETHERNET_SRC(pucPayload), psData->sSA.au8Addr );
// Allocate NDIS buffer.
NdisAllocateBuffer( &iStatus, &psBuffer, psAdapter->hRxBufferPool, pucPayload, ulLength );
if ( iStatus != NDIS_STATUS_SUCCESS )
{
DBG_LEV1(("Ran out of NDIS buffer resources.\n"));
psStats->ulRxResourceError++;
NdisFreePacket( psPacket );
NdisFreeMemory( pucDataBuffer, bufsize , 0 );
}
else
{
UINT uiPriority;
// Link the buffer to packet.
NdisChainBufferAtBack( psPacket, psBuffer );
NDIS_SET_PACKET_STATUS( psPacket, NDIS_STATUS_SUCCESS );
uiPriority = psData->u16AccessProtocol;
NDIS_PER_PACKET_INFO_FROM_PACKET(psPacket, Ieee8021pPriority) =
(PVOID)(ULONG_PTR)uiPriority;
// Indicate the packet to NDIS.
NdisMIndicateReceivePacket( psAdapter->hMiniportAdapterHandle, &psPacket, 1 );
psStats->ulTotalPktsRxedOk++;
iStatus = NDIS_GET_PACKET_STATUS( psPacket );
// If NDIS set pending flag, we will get the packet in MiniportReturnPacket.
if ( iStatus != NDIS_STATUS_PENDING )
{
NdisFreeBuffer( psBuffer );
NdisFreePacket( psPacket );
NdisFreeMemory( pucDataBuffer, bufsize, 0 );
}
else
psAdapter->ulRxIndicatedPending ++;
DBG_LEV3(("Indicate Rx packet, buffer = 0x%lx, index = %d\n", pucPayload, ulBufferIndex));
}
}
}
}
// Adjust Rx buffer index.
psHAL->ulRxBufferIndex = (ulBufferIndex + 1) % psHAL->ulRxBufNum;
// Rx done, generate interrupt to Target.
vHALinterruptDevice( psHAL, 1, HAL_BIT_interrupt_rx_data0 + ulBufferIndex );
}
}
}
//-----------------------------------------------------------------------------
//
// NAME vHALIsr
//
// PARAMETERS InterruptRecognized - TRUE if our interrupt.
// QueueMiniportHandleInterrupt - TRUE if we need the DPC.
// MiniportAdapterContext - Pointer to the Adapter context.
//
// DESCRIPTION This handler is interrupt service routine.
// Check whether it's our interrupt and need a DPC.
//
//-----------------------------------------------------------------------------
VOID
vHALIsr(
OUT PBOOLEAN InterruptRecognized,
OUT PBOOLEAN QueueMiniportHandleInterrupt,
IN NDIS_HANDLE MiniportAdapterContext)
{
PEND_CONTEXT psAdapter = (PEND_CONTEXT)MiniportAdapterContext;
PHAL_CONTEXT psHAL = &psAdapter->sHAL;
ULONG ulValue = 0;
// set clock rate back to max when receive interrupt from GPIO4
if (psHAL->ePowerState != HAL_PS_AWAKE)
{
// set clock rate back to max
vHALSetMaxClockRate(psHAL, HAL_SDIO_MAX_CLOCK);
psHAL->ePowerState = HAL_PS_AWAKE;
}
// Read interrupt status.
vHALreadRegister( psHAL, HAL_ADDR_interrput_arm_to_host, &ulValue );
TRACE(TRACE_CFSD_NDHAL, ulValue);
if ( (ulValue & HAL_MASK_interrupt_arm_to_host) == 0 || psHAL->eState != HAL_RUNNING )
{
// Not our interrupt, just ignore it.
*InterruptRecognized = FALSE;
*QueueMiniportHandleInterrupt = FALSE;
}
else
{
// Disable interrupt and save the interrupt status.
vHALdisableInterrupt( psHAL );
psHAL->ulInterruptStatus = ulValue;
// schedule backend
*InterruptRecognized = TRUE;
*QueueMiniportHandleInterrupt = TRUE;
}
}
//-----------------------------------------------------------------------------
//
// NAME vHALhandleInterrupt
//
// PARAMETERS MiniportAdapterContext - Pointer to the Adapter context.
//
// DESCRIPTION This handler is interrupt DPC routine.
// Dispatch to handle device interrupt.
//
//-----------------------------------------------------------------------------
VOID
vHALhandleInterrupt(
I
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -