⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
                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 + -