fec.c
来自「opentcp_mcf5282原代码」· C语言 代码 · 共 196 行
C
196 行
/*
* File: fec.c
* Purpose: Device driver for the MCF5282 FEC
*
*
*/
#include "src/common/m5282evb.h"
#include "src/ethernet/nif.h"
#include "src/ethernet/fec.h"
/********************************************************************/
static int
fec_reset(NIF *nif)
{
/* Reset the FEC - equivalent to a hard reset */
MCF5282_FEC_ECR = MCF5282_FEC_ECR_RESET;
/* Wait for the reset sequence to complete */
while (MCF5282_FEC_ECR & MCF5282_FEC_ECR_RESET)
;
/* Disable all FEC interrupts by clearing the EIMR register */
MCF5282_FEC_EIMR = 0;
/* Clear any interrupts by setting all bits in the EIR register */
MCF5282_FEC_EIR = 0xFFFFFFFF;
/* Set the source address for the controller */
MCF5282_FEC_PALR = (0
| (nif->hwa[0] <<24)
| (nif->hwa[1] <<16)
| (nif->hwa[2] <<8)
| (nif->hwa[3] <<0));
MCF5282_FEC_PAUR = (0
| (nif->hwa[4] <<24)
| (nif->hwa[5] <<16));
/* Initialize the hash table registers */
MCF5282_FEC_IAUR = 0;
MCF5282_FEC_IALR = 0;
/* Set Receive Buffer Size */
MCF5282_FEC_EMRBR = (uint16)RX_BUFFER_SIZE;
/* Point to the start of the circular Rx buffer descriptor queue */
MCF5282_FEC_ERDSR = nbuf_get_start(Rx);
/* Point to the start of the circular Tx buffer descriptor queue */
MCF5282_FEC_ETDSR = nbuf_get_start(Tx);
/* Set the tranceiver interface to MII mode */
MCF5282_FEC_RCR = (0
| MCF5282_FEC_RCR_MII_MODE);
/* | MCF5282_FEC_RCR_DRT); */ /* half duplex */
/* Only operate in half-duplex, no heart beat control */
MCF5282_FEC_TCR = 0;
return TRUE;
}
/********************************************************************/
static void
fec_start(NIF *nif)
{
(void) nif;
/* Enable FEC */
MCF5282_FEC_ECR = MCF5282_FEC_ECR_ETHER_EN;
/* Allow interrupts by setting IMR register */
MCF5282_FEC_EIMR = MCF5282_FEC_EIMR_RXF;
/* Indicate that there have been empty receive buffers produced */
MCF5282_FEC_RDAR = 1;
}
/********************************************************************/
static void
fec_stop (NIF *nif)
{
(void) nif;
/* Set the Graceful Transmit Stop bit */
MCF5282_FEC_TCR = (MCF5282_FEC_TCR
| MCF5282_FEC_TCR_GTS);
/* Wait for the current transmission to complete */
while ( !(MCF5282_FEC_EIR & MCF5282_FEC_EIR_GRA))
;
/* Clear the GRA event */
MCF5282_FEC_EIR = MCF5282_FEC_EIR_GRA;
/* Disable the FEC */
MCF5282_FEC_ECR = 0;
/* Disable all FEC interrupts by clearing the IMR register */
MCF5282_FEC_EIMR = 0;
/* Clear the GTS bit so frames can be tranmitted when restarted */
MCF5282_FEC_TCR = (MCF5282_FEC_TCR
& ~MCF5282_FEC_TCR_GTS);
}
/********************************************************************/
static int
fec_send (NIF *nif, NBUF *pNbuf)
{
/* If data length of the frame is too long or short, reject */
if ((pNbuf->length > nif->mtu) || (pNbuf->length <= 0))
return FALSE;
/* Adjust the length by the ethernet header size */
//pNbuf->length += ETH_HDR_SIZE;
/* Set Frame ready for transmit */
pNbuf->status |= TX_BD_R;
/* Mark the buffer as not in use */
nif->tx_free(pNbuf);
/* Indicate that there has been a transmit buffer produced */
MCF5282_FEC_TDAR = 1;
/* The hardware will mark the buffer as empty once it's transmitted */
nif->f_tx++;
return TRUE;
}
/********************************************************************/
static void
fec_receive(NIF *nif)
{
nif_protocol_handler(nif);
return;
}
/********************************************************************/
void
fec_rx_release(NBUF* pNbuf)
{
/* Mark the buffer as empty */
nbuf_rx_release(pNbuf);
/* Tell the HW that there has been an empty Rx buffer produced */
MCF5282_FEC_RDAR = 1;
}
/********************************************************************/
int
fec_handler (NIF *nif)
{ /* This is the Interrupt Service Routine for the FEC receiver */
int old_ipl = asm_set_ipl(6);
/* Clear FEC RX Event from the Event Register (by writing 1) */
if (MCF5282_FEC_EIR & (MCF5282_FEC_EIR_RXB | MCF5282_FEC_EIR_RXF))
{
/* Clear interrupt from EIR register immediately */
MCF5282_FEC_EIR = (MCF5282_FEC_EIR_RXB | MCF5282_FEC_EIR_RXF);
fec_receive(nif);
}
asm_set_ipl(old_ipl);
return TRUE;
}
/********************************************************************/
int
fec_init (NIF *nif)
{
nif_init(nif, "mcf5282_fec");
nif->hwa_size = 6;
nif->mtu = ETH_MAX_SIZE;
nif->reset = fec_reset;
nif->start = fec_start;
nif->stop = fec_stop;
nif->send = fec_send;
nif->receive = (void *)&fec_receive;
nif->rx_alloc = nbuf_rx_allocate;
nif->tx_alloc = nbuf_tx_allocate;
nif->rx_free = fec_rx_release;
nif->tx_free = nbuf_tx_release;
return TRUE;
}
/********************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?