📄 mac_au1000.c
字号:
* 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 + -