?? lan91c96.c
字號:
// 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 + -