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

📄 lan91c96.c

📁 Intel XScale PXA255 引导Linux的Redboot 版bootloader源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
            // Parse the transmit error bits.            //DisplayTxStatus(ctxP);            // Cleanup after the transmit error.            if (DeallocateTxPacket(ctxP))            {                return (ctxP->loggedError);            }            /*LOGERROR(ctxP->loggedError, ERR_L_LAN91C96, ERR_LAN91C96_TRANSMIT,                     ERR_T_TIMEOUT, intStatus, 0, 0);*/            /*DM_Printf("LAN91C96: Transmit timeout, ISR = %x", intStatus);*/						ctxP->packetSent = 1 ;						//printf("LAN91C96: Transmit FIFO not empty\n");            return (-1);        }    }    // Now check for transmit complete.    if (intStatus & LAN91C96_IST_TX_EMPTY_INT)    {        // Acknowledge Transmit Empty Interrupt.				//printf("Transmit was complete and successful\n") ;        WriteByte(LAN91C96_ACK_TX_EMPTY_INT, &ioRegsP[LAN91C96_INT_ACK]);    }    // Now check for transmit complete.    if (intStatus & LAN91C96_IST_TX_INT)    {        // Acknowledge the Transmit interrupt.				//printf("Transmit may have had erors\n") ;        WriteByte(LAN91C96_ACK_TX_INT, &ioRegsP[LAN91C96_INT_ACK]);    }    // Clear the collision count.    WriteWord(BANK0, &ioRegsP[LAN91C96_BANK_SELECT]);    ReadWord(&ioRegsP[LAN91C96_COUNTER]);    resultCode = ReadWord(&ioRegsP[LAN91C96_EPH_STATUS]);    // Get delta time reference.    GetDeltaTimeStamp(ctxP, "Tx");		ctxP->packetSent = 1 ;    return (ctxP->loggedError);}/********************************************************************************** FUNCTION:*    LAN91C96_Handler** DESCRIPTION:*    This routine handles the operations normally performed by an Interrupt*    Service Routine. Since we aren't using interrupts to drive transmit and*    receive, this routine is used in place of the ISR routine.** INPUT PARAMETERS:*    LAN91C96_ContextT *ctxP - Pointer to the LAN91C96 Device Context Structure** RETURNS:*    None** GLOBAL EFFECTS:*    The rxFlag in the DCS is set if a packet has been received.** ASSUMPTIONS:*    None.** CALLS:*    None.** CALLED BY:*    LAN91C96ReceivePacket - ** PROTOTYPE:*    static*    VOID LAN91C96_Handler(LAN91C96_ContextT *ctxP));*********************************************************************************/staticVOID LAN91C96_Handler(LAN91C96_ContextT *ctxP){    PVUINT32 ioRegsP = ctxP->LAN91C96IoP;     // Get pointer to I/O space    UCHAR intStatus, maskRegister;    UINT16 bankSelect;    // Save the current bank selection and switch to Bank 2.    bankSelect = ReadWord(&ioRegsP[LAN91C96_BANK_SELECT]);    // Select Bank 2    WriteByte(BANK2, &ioRegsP[LAN91C96_BANK_SELECT]);    // Get the Interrupt Status Register.    intStatus = ReadByte(&ioRegsP[LAN91C96_INT_STATS]);    // Get the Interrupt Mask Register.    maskRegister = ReadByte(&ioRegsP[LAN91C96_INT_MASK]);    // Disable interrupts.    WriteByte(0, &ioRegsP[LAN91C96_INT_MASK]);    // Check for receive overrun errors    if (intStatus & LAN91C96_IST_RX_OVRN_INT)    {        // Acknowledge the Receive Overrun interrupt.        WriteByte(LAN91C96_ACK_RX_OVRN_INT, &ioRegsP[LAN91C96_INT_ACK]);        /*LOGERROR(ctxP->loggedError, ERR_L_LAN91C96, ERR_LAN91C96_RECEIVE,                 ERR_T_NORECEIVE, intStatus, 0, 0);*///printf("LAN91C96: Receive overrun error, %x", intStatus);    }    // Check for receive interrupt.    if (intStatus & LAN91C96_IST_RCV_INT)    {        // Set the flag indicating a frame has been received.        ctxP->rxFlag = 1;        // Clear the Receive Interrupt bit mask.        maskRegister &= ~LAN91C96_MSK_RCV_INT;    }    // Update the Interrupt Mask Register.    WriteByte(maskRegister, &ioRegsP[LAN91C96_INT_MASK]);    // Restore the bank select register.    WriteByte(bankSelect, &ioRegsP[LAN91C96_BANK_SELECT]);	return ;}/********************************************************************************** FUNCTION:*    DeallocateRxPacket** DESCRIPTION:*    This routine will deallocate a receive buffer and clear any errors.** INPUT PARAMETERS:*    LAN91C96_ContextT *ctxP - Pointer to the LAN91C96 Device Context Structure** RETURNS:*    0 - Success*    non-zero - Error** GLOBAL EFFECTS:*    The receive buffer is returned to the LAN91C96.** ASSUMPTIONS:*    None.** CALLS:*    None.** CALLED BY:*    LAN91C96ReceivePacket - Receive a frame from the LAN91C96.** PROTOTYPE:*    static*    VOID DeallocateRxPacket(LAN91C96_ContextT *ctxP);*********************************************************************************/INT DeallocateRxPacket(LAN91C96_ContextT *ctxP){    PVUINT32 ioRegsP = ctxP->LAN91C96IoP;     // Get pointer to I/O space    UINT start, currTimerValue ;    UINT timeout = (UINT)((LAN91C96_TO_ALLOC * 3686400) >> 20) ;    UCHAR intStatus, maskRegister;    // Select Bank 2    WriteByte(BANK2, &ioRegsP[LAN91C96_BANK_SELECT]);    // Release the memory from the received Frame.    WriteWord(LAN91C96_MMUCR_RELEASE_RX, &ioRegsP[LAN91C96_MMU]);    // Prepare for timeout by getting the initial time interval.    hal_clock_read(&start) ;//ostCtxP->getTimer_fnp(ostCtxP);    while (ReadWord(&ioRegsP[LAN91C96_MMU]) & LAN91C96_MMUCR_NO_BUSY)    {        // Get the current time interval.				hal_clock_read(&currTimerValue) ;        if (hal_elapsed_ticks((unsigned long *)&start) > timeout)        {            // Report timeout error.            /*LOGERROR(ctxP->loggedError, ERR_L_LAN91C96,                     ERR_LAN91C96_RECEIVE, ERR_T_TIMEOUT, 0, 0, 0);*/   //printf("LAN91C96: Buffer deallocation timeout!");            return (ctxP->loggedError);        }    }    // Enable the receive interrupt and clear the receive flag.    intStatus = ReadByte(&ioRegsP[LAN91C96_INT_STATS]);    if (intStatus &  LAN91C96_IST_RCV_INT)    {        // Clear receive flag.        ctxP->rxFlag = 0;        // Read the Interrupt Mask Register.        maskRegister = ReadByte(&ioRegsP[LAN91C96_INT_MASK]);        // Set the Receive Interrupt bit.                    maskRegister |= LAN91C96_MSK_RCV_INT;        // Re-enable Receive interrupts.        WriteByte(maskRegister, &ioRegsP[LAN91C96_INT_MASK]);    }    return (ctxP->loggedError);}/********************************************************************************** FUNCTION:*    LAN91C96ReceiveStatus** DESCRIPTION:*    This routine returns the receive status of the LAN91C96.** INPUT PARAMETERS:*    LAN91C96_ContextT *ctxP - Pointer to the LAN91C96 Device Context Structure** RETURNS:*    0 = No pending receive packet.*    1 = Pending receive packet.** GLOBAL EFFECTS:*    None.** ASSUMPTIONS:*    None.** CALLS:*    WriteByte - To write a byte to either the attribute or I/O space.*    ReadByte - Read a byte from either the attribute or I/O space.*    ReadWord - Read a word from either the attribute or I/O space.*    GetTimeStamp - Get a tick count.*    GetDeltaTimeStamp - Get the time delta.** CALLED BY:*    Application or test code.** PROTOTYPE:*    INT LAN91C96ReceiveStatus(LAN91C96_ContextT *ctxP);*********************************************************************************/INT LAN91C96ReceiveStatus(LAN91C96_ContextT *ctxP){    PVUINT32 ioRegsP = ctxP->LAN91C96IoP;     // Get pointer to I/O space    UINT16 bankSelect, resultCode = 0;    UINT16 count ;    UCHAR intStatus;    UINT16 statusWord ;    // Get a time reference.    GetTimeStamp(ctxP);    // Save the current bank selection and switch to Bank 2.    bankSelect = ReadWord(&ioRegsP[LAN91C96_BANK_SELECT]);    // Select Bank 2    WriteByte(BANK2, &ioRegsP[LAN91C96_BANK_SELECT]);    // Get the Interrupt Status Register.    intStatus = ReadByte(&ioRegsP[LAN91C96_INT_STATS]);    // Check for receive overrun errors    if (intStatus & LAN91C96_IST_RX_OVRN_INT)    {        // Acknowledge the Receive Overrun interrupt.        WriteByte(LAN91C96_ACK_RX_OVRN_INT, &ioRegsP[LAN91C96_INT_ACK]);				//printf("Receive overrun occurred\n") ;				return(-1) ;    }    // Check the Receive Interrupt.    else if (intStatus & LAN91C96_IST_RCV_INT)    {      // Get the packet byte count, which is the byte count minus the      // status word, byte count and control byte.      // Get status word.      count = 0 ;      statusWord = ReadWord(&ioRegsP[LAN91C96_DATA_HIGH]);      if (statusWord & LAN91C96_ODD_FRM)      {                   count = 1 ;      }      ctxP->rxPacketLen = (UINT32)((0x7FF & statusWord) - 6) + count ;            // Indicate receive packet pending.        resultCode = 1 ;    }    // Restore the bank select register.    WriteByte(bankSelect, &ioRegsP[LAN91C96_BANK_SELECT]);    // Get delta time reference.    GetDeltaTimeStamp(ctxP, "Rx Status");    return (resultCode);}/********************************************************************************** FUNCTION:*    LAN91C96ReceivePacket** DESCRIPTION:*    This routine will read a single frame received by the LAN91C96.** INPUT PARAMETERS:*    LAN91C96_ContextT *ctxP - Pointer to the LAN91C96 Device Context Structure*    PUINT16 buffer - Pointer to the receive buffer to store the packet.  'buffer'*                     MUST BE allocated and validated by the calling entity*    INT length - Size of the receive buffer.  'length' is supplied by the caller*                 and must match the size of the received data.  *    PINT rxCountP - Number of bytes received.*    ** RETURNS:*    0 - Success*    non-zero - Error** GLOBAL EFFECTS:*    None.** ASSUMPTIONS:*    None.** CALLS:*    LAN91C96_Handler - LAN91C96 receive ISR handler (polled).*    DeallocateRxPacket - Return the receive packet back to the LAN91C96.*    WriteByte - To write a byte to either the attribute or I/O space.*    WriteWord - To write a word to either the attribute or I/O space.*    ReadWord - Read a word from either the attribute or I/O space.*    GetTimeStamp - Get a tick count.*    GetDeltaTimeStamp - Get the time delta.*    DM_CWDbgPrintf - Display debug messages for this device.*    DM_Printf - Display text string.*    DM_ErrPrintf - Display error string.*    LAN91C96DumpFrame - Display packet.*    DisplayTxStatus - Display the transmit status register.*    LOGERROR - Logs errors encountered.** CALLED BY:*    Application or test code.** PROTOTYPE:*    INT LAN91C96ReceivePacket(LAN91C96_ContextT *ctxP, PUINT16 buffer,*                              INT length, PINT rxCountP);*********************************************************************************/INT LAN91C96ReceivePacket(LAN91C96_ContextT *ctxP, PUINT16 bufferP,                          INT length, PINT rxCountP){    PVUINT32 ioRegsP = ctxP->LAN91C96IoP;     // Get pointer to I/O space    UINT16 statusWord, controlWord, frameType;    UINT16 x = 0;    PUINT16 dataP;    UINT16 data;    UINT16 count = 0;    // Get a time reference.    GetTimeStamp(ctxP);    // Clear the receive count.    *rxCountP = 0;    // Check for received frames.    LAN91C96_Handler(ctxP);    // Process all received frames.    if (ctxP->rxFlag)    {        // Select Bank 2        WriteByte(BANK2, &ioRegsP[LAN91C96_BANK_SELECT]);        // Setup for Receive, Auto Increment and Read access.        WriteWord(LAN91C96_PTR_RX_FRAME, &ioRegsP[LAN91C96_POINTER]);        // Get status word.        statusWord = ReadWord(&ioRegsP[LAN91C96_DATA_HIGH]);        // Check for broadcast frames.        if (0 /*statusWord & FRAME_FILTER*/)        {//printf("3.LAN91C96ReceivePacket\n") ;            // Now deallocate the page.            DeallocateRxPacket(ctxP);            // Filter this frame out by ignoring it.            return (0);        }        else        {            // Process the frame, get the pointer to the user buffer.            dataP = bufferP;            // Get the packet byte count, which is the byte count minus the            // status word, byte count and control byte.            count = (0x7FF & ReadWord(&ioRegsP[LAN91C96_DATA_HIGH])) - 6;            // Check we have enough room to store the receive packet.            if (count > length)            {//printf("5.LAN91C96ReceivePacket\n") ;                // Now deallocate the page.                DeallocateRxPacket(ctxP);                /*LOGERROR(ctxP->loggedError, ERR_L_LAN91C96,                         ERR_LAN91C96_RECEIVE, ERR_T_NOT_AVAIL, 0, 0, 0);                DM_ErrPrintf("LAN91C96: Receive frame too big (%u) for buffer (%u)",                             count, length);*/                return (-1);            }        }                // Initialize the initial count.        x = 0;        // Check filter flag.        if (!ctxP->filterFlag)        {            // Filter out all broadcast packets except ARPs and IPs.            if (statusWord & LAN91C96_BROD_CAST)            {                // Get the ethernet frame header                for ( ; x < sizeof(EthernetHeaderT); x++)                {                    *dataP++ = ReadWord(&ioRegsP[LAN91C96_DATA_HIGH]);                }                // Check the protocol type.                frameType = ntohs(((EthernetHeaderT *)bufferP)->frameType);                if ((frameType != ETHERTYPE_ARP) && (frameType != ETHERTYPE_IP))                {                    // Now deallocate the page.                    DeallocateRxPacket(ctxP);                    // Filter this frame out by ignoring it.                    return (0);                }            }        }        // Read the rest of the data packet except the last 2 words which        // contain the CRC.#define CRC_LEN 2        for ( ; x < ((count >> 1) - (CRC_LEN >> 1)); x++)        {            // Drain the Receive FIFO.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -