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

📄 mac_au1000.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 *  Description :
 *  -------------
 *  This service polls the specified LAN interface for any received frame.
 *  If any frame has been received, it will be read into the user allocated
 *  variable, *p_param; if none present, completion = 'ERROR_LAN_NO_FRAME'
 *  will be returned.
 *  
 *
 *  Parameters :
 *  ------------
 *
 *  'major',     IN,    major device number
 *  'minor',     IN,    minor device number for multi device drivers
 *  'p_param',   INOUT, LAN variable of type, t_LAN_IO_desc.
 *
 *
 *  Return values :
 *  ---------------
 *
 *  'OK'(=0)
 *  'ERROR_LAN_NO_FRAME':     no frame present on this LAN interface
 *  'ERROR_LAN_COMM_ERROR':   communication error detected
 *
 *
 ************************************************************************/
static
INT32 MAC_AU1000_read(
		  UINT32 major, 		 /* IN: major device number 			*/
		  UINT32 minor, 		 /* IN: minor device number 			*/
		  t_LAN_IO_desc *p_param )	 /* INOUT: LAN frame		   */
{
	int 				 BufferIndex;
	int 				 PacketIndex;
	UINT32				 status ;
	UINT32				 *pPacket;
	UINT32				 wBufLen ; 
	UINT8				 *address;
	t_MAC_AU1000_device *pdevice ;
	static int first = 1;

	UINT32 rc		= ERROR_LAN_NO_FRAME ;
	UINT8  *pbData	= p_param->data ;
	UINT32 dwLength = p_param->length ;


	if ( MAC_AU1000_state == MAC_AU1000_DRIVER_IS_STOPPED )
	{
		return( ERROR_LAN_NO_FRAME ) ;
	}


	/* get device context for this minor device */
	pdevice = &minor_device[minor] ;
		
	
	while (1) 
	{
		/* address next packet */

		BufferIndex = pdevice->NextRcvBufferIndex;


		if ( MACREG( pdevice->pAU1000DMARegs, 
			SETV(DMA_RECEIVE, MAC_DMA_TXRX) |		
			SETV(BufferIndex,MAC_DMA_BUF)  | /* BufferIndex picks correct DMA register */
			SETV(DMA_ADDRESS_EN ,MAC_DMA_REG))			
			& MAC_DMA_DONE_MASK )			 /* If DONE then a receive has taken place */
		{

			status = MACREG( pdevice->pAU1000DMARegs, 
							SETV(DMA_RECEIVE, MAC_DMA_TXRX) |		
							SETV(BufferIndex,MAC_DMA_BUF)  | /* BufferIndex picks correct DMA register */
							SETV(DMA_STATUS ,MAC_DMA_REG));
	 
			/* check for missed frame */
			if ( status & MAC_RECEIVE_MI_MASK )
			{
				/* received packet has	errors, drop this packet */
				pdevice->status.rx_errors++;
				if (status & MAC_RECEIVE_CR_MASK)
					 pdevice->status.rx_cr_errors++;

				if (status & MAC_RECEIVE_DB_MASK)
					 pdevice->status.rx_db_errors++;

				if (status & MAC_RECEIVE_FL_MASK)
					 pdevice->status.rx_fl_errors++;

				if (status & MAC_RECEIVE_MI_MASK)
					 pdevice->status.rx_mi_errors++;
			}
			else if( !(status & MAC_RECEIVE_PF_MASK))
			{
				/* Broadcast Frame ? */
				pdevice->status.rx_pf_errors++;
			}
			else  /* received packet is good */
			{

			   pPacket = (UINT32*)KSEG0(pdevice->RcvBuffer[BufferIndex]);

			   wBufLen = status & MAC_RECEIVE_L_MASK ;
			   
			   pdevice->status.rx_bytes += wBufLen;
			   
			   pdevice->status.rx_packets++;

			   if (usr_receive != NULL)
			   {
				   /* we have a registered receive handler */
				   if ( wBufLen == 0 )
				   {
					   /* drop the packet */
					   pdevice->status.rx_zero_length_errors++;
				   }
				   else
				   {
					   /* count any broadcast's */
					   if ( !memcmp( ((UINT8*)pPacket), mac_broadcast_adr, SYS_MAC_ADDR_SIZE ) )
					   {
						   pdevice->status.multicast++ ;
					   }

					   /* call the handler */
					   (*usr_receive)( wBufLen, ((UINT8*)pPacket)) ;

					   /* packet processed */
					   rc = OK;
				   }
			   }
			   else
			   {
				   /* we don't have a registered receive handler */

				   if ( wBufLen == 0 ) 
				   {
					   /* drop the packet */
					   pdevice->status.rx_zero_length_errors++;
				   }

				   if ( wBufLen > dwLength ) 
				   {
					   /* drop the packet */
					   pdevice->status.rx_buffer_length_errors++;
				   }
				   else
				   {
					   /* count any broadcast's */
					   if ( !memcmp( ((UINT8*)pPacket), mac_broadcast_adr, SYS_MAC_ADDR_SIZE ) )
					   {
						   pdevice->status.multicast++ ;
					   }
					   address = (UINT8* ) pPacket;
					   memcpy ( pbData, (UINT8* )address, wBufLen);

					   /* we got the packet, return */
					   rc = OK;
				   }
			   }
			   

			}
			
			/* Enable Current buffer again since we are done */

			MACREG( pdevice->pAU1000DMARegs, 
				SETV(DMA_RECEIVE, MAC_DMA_TXRX) |			
				SETV(BufferIndex,MAC_DMA_BUF)  |				/* i selects buffer */
				SETV(DMA_ADDRESS_EN ,MAC_DMA_REG)  )		
				= (pdevice->RcvBuffer[BufferIndex] & MAC_DMA_ADDR_MASK) | MAC_DMA_ENABLE_MASK;  /* only upper 27 bits are used */

			/* Increment Next Buffer */

			pdevice->NextRcvBufferIndex++;

			if ( pdevice->NextRcvBufferIndex >= MAC_AU1000_RX_BUFFERS )
			{
				pdevice->NextRcvBufferIndex = 0;
			}



			/* check for any received packet */
			if (rc == OK)
			{
				return(OK) ;
			}

		}
		else
		{
			/* no more packets - no need to increment 
			next buffer index  since buffer was not used */
			break;

		}
				   
	}
#if 0
	if ( ((poll_count++) % 100) == 0 )
	{
		
		/* Revise:	may want to include the following if there are receive errors */
		/* MAC_AU1000_init( major, minor, NULL ) ; */
		MAC_AU1000_MII_init( pdevice ) ;
	}
	return( ERROR_LAN_NO_FRAME ) ;

#endif
}

/************************************************************************
 *
 *                          MAC_AU1000_write
 *  Description :
 *  -------------
 *  This service requests transmission of a frame on the LAN interface. It is the caller's
 *  responsibility to fill in all information including the destination and source addresses and
 *  the frame type.  The length parameter gives the number of bytes in the ethernet frame.
 *  The routine will not return until the frame has been transmitted or an error has occured.  If
 *  the frame transmits successfully, OK is returned.  If an error occured, a message is sent to
 *  the serial port and the routine returns non-zero.
 *  
 *
 *  Parameters :
 *  ------------
 *
 *  'major',     IN,    major device number
 *  'minor',     IN,    minor device number for multi device drivers
 *  'p_param',   INOUT, LAN variable of type, t_LAN_IO_desc.
 *
 *
 *  Return values :
 *  ---------------
 *
 *  'OK'(=0)
 *  'ERROR_LAN_COMM_ERROR':   communication error detected
 *
 *
 ************************************************************************/
static
INT32 MAC_AU1000_write(
		  UINT32 major, 		 /* IN: major device number 			*/
		  UINT32 minor, 		 /* IN: minor device number 			*/
		  t_LAN_IO_desc *p_param )	 /* OUT: frame to transmit	   */
{
	UINT32 i;
	UINT32 status, temp, x;
	UINT8  *pbData	= p_param->data ;
	UINT32 dwLength = p_param->length ;

	UINT8						  *pbPacketData;
	UINT32						  *pPacket ;
	int 						  BufferIndex;
	t_MAC_AU1000_device 		 *pdevice ;

	if ( MAC_AU1000_state == MAC_AU1000_DRIVER_IS_STOPPED )
	{

#ifdef ETH_DEBUG
		printf("MAC_AU1000_state is stopped");
#endif
		return( ERROR_LAN_TXM_ERROR ) ;
	}

#ifdef ETH_DEBUG
		printf("MAC_AU1000_Write");
#endif

	/* get device context for this minor device */
	pdevice = &minor_device[minor] ;

	BufferIndex = (MACREG( pdevice->pAU1000DMARegs, 
									SETV(DMA_TRANSMIT, MAC_DMA_TXRX) |		
									SETV(DMA_ADDRESS_EN,MAC_DMA_REG)) & 
									MAC_DMA_NEXTBUF_MASK) >> MAC_DMA_NEXTBUF;


	pPacket = (UINT32*)KSEG1((pdevice->TxmBuffer[BufferIndex]));

	
   if ( MACREG( pdevice->pAU1000DMARegs, 
			SETV(DMA_TRANSMIT, MAC_DMA_TXRX) |		
			SETV(BufferIndex,MAC_DMA_BUF)  | /* BufferIndex picks correct DMA register */
			SETV(DMA_ADDRESS_EN ,MAC_DMA_REG)  )			

			& MAC_DMA_READY_MASK )			 /* If either DONE or ENABLE are not 0 then DMA 
			channel is not ready */
   {


#ifdef ETH_DEBUG
		printf("ERROR_LAN_NO_TXM_RESOURCES\n");
#endif
		return(ERROR_LAN_NO_TXM_RESOURCES);
	}


	pbPacketData = (UINT8* )pPacket ;
	
	/* copy the bits */
	memcpy( pbPacketData, pbData, dwLength);
	pdevice->status.tx_bytes += dwLength;
	pdevice->status.tx_packets++;

 
	/* check to PAD packet up to minimum size */
	if (dwLength < MAC_AU1000_MIN_PACKET_SIZE)
	{
		memset( (pbPacketData + dwLength), 0, (MAC_AU1000_MIN_PACKET_SIZE-dwLength) ) ;
		dwLength = MAC_AU1000_MIN_PACKET_SIZE ;
	}

	/* Set length register */

	MACREG( pdevice->pAU1000DMARegs, 
			SETV(DMA_TRANSMIT, MAC_DMA_TXRX) |			 
			SETV(BufferIndex,MAC_DMA_BUF)  | 
			SETV(DMA_LENGTH,MAC_DMA_REG)  ) = dwLength;

	/* Enable Rx */

/*	for (i=0; i< MAC_AU1000_RX_BUFFERS ; i++) {
		
		MACREG( minor_device[minor].pAU1000DMARegs, 
			SETV(DMA_RECEIVE, MAC_DMA_TXRX) |			
			SETV(i,MAC_DMA_BUF)  |			
			SETV(DMA_ADDRESS_EN ,MAC_DMA_REG)  )		
			|= MAC_DMA_ENABLE_MASK;
	}

	pdevice->NextRcvBufferIndex = (MACREG( pdevice->pAU1000DMARegs, 
									SETV(DMA_RECEIVE, MAC_DMA_TXRX) |		
									SETV(DMA_ADDRESS_EN,MAC_DMA_REG)) & 
									MAC_DMA_NEXTBUF_MASK) >> MAC_DMA_NEXTBUF;


*/

	/* Enable DMA */
	MACREG( pdevice->pAU1000DMARegs, 
			SETV(DMA_TRANSMIT, MAC_DMA_TXRX) |	
			SETV(BufferIndex,MAC_DMA_BUF)  |				/* i selects buffer */
			SETV(DMA_ADDRESS_EN ,MAC_DMA_REG)  )
			= (pdevice->TxmBuffer[BufferIndex] & MAC_DMA_ADDR_MASK) | /* only upper 27 bits are used */
			  SET(MAC_DMA_ENABLE); 							



	/* Now wait until either an error occurs or transmission completes successfully */
	i = 0 ;
	while( 1 ) 
	{
		  /* check DMA Done bit */
		  if ( MACREG( pdevice->pAU1000DMARegs, 
				SETV(DMA_TRANSMIT, MAC_DMA_TXRX) |			 
				SETV(BufferIndex,MAC_DMA_BUF)  | 
				SETV(DMA_ADDRESS_EN,MAC_DMA_REG) ) & MAC_DMA_DONE_MASK) 
		  {
			

			status = MACREG( pdevice->pAU1000DMARegs, 
						SETV(DMA_TRANSMIT, MAC_DMA_TXRX) |			 
						SETV(BufferIndex,MAC_DMA_BUF)  | 
						SETV(DMA_STATUS,MAC_DMA_REG) );

			/* Clear Done bit */

			MACREG( pdevice->pAU1000DMARegs, 
				SETV(DMA_TRANSMIT, MAC_DMA_TXRX) |			 
				SETV(BufferIndex,MAC_DMA_BUF)  | 
				SETV(DMA_ADDRESS_EN,MAC_DMA_REG) )

						&= ~MAC_DMA_DONE_MASK;

#ifdef ETH_DEBUG
		printf("Status = %08x\n", status);
#endif
					
			/* Check for frame abort */
			if (status & MAC_TRANSMIT_FA_MASK)
			{
				pdevice->status.tx_errors++;

				if (status & MAC_TRANSMIT_JT_MASK)
					pdevice->status.tx_jt_errors++;

				if (status & MAC_TRANSMIT_NC_MASK)
					pdevice->status.tx_nc_errors++;

				if (status & MAC_TRANSMIT_LS_MASK)
					pdevice->status.tx_ls_errors++;
			
				if (status & MAC_TRANSMIT_ED_MASK)

⌨️ 快捷键说明

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