📄 mcf5xxx_fecbd.c
字号:
/*
* File: fecbd.c
* Purpose: Provide a simple buffer management driver for a single
* FEC
*
* Notes:
*/
#include "src/include/dbug.h"
#include "src/cpu/coldfire/mcf5xxx/mcf5xxx_fecbd.h"
#include "src/uif/net/nbuf.h"
#include "src/uif/net/eth.h"
#ifdef DBUG_NETWORK
/*
* This implements a simple static buffer descriptor
* ring for each channel and each direction
*
* Buffer descriptors must be aligned on a 4-byte boundary but a
* 16-byte boundary is recommended. To avoid playing games with the
* various compilers and their different extension to ANSI C, these
* buffers are aligned by allocating an extra line of data and
* adjusting the pointers in fecbd_init().
*/
uint8 unaligned_txbd[(sizeof(FECBD) * NTXBD) + 16];
uint8 unaligned_rxbd[(sizeof(FECBD) * NRXBD) + 16];
FECBD *RxBD;
FECBD *TxBD;
/*
* Buffer descriptor indexes
*/
static uint8 iTxbd_head;
static uint8 iTxbd_tail;
static uint8 iRxbd;
/********************************************************************/
/*
* Initialize the FEC Buffer Descriptor ring
* Buffer Descriptor format is defined by the MCDAPI
*/
void
fecbd_init(void)
{
NBUF *nbuf;
int i;
TxBD = (FECBD *)((uint32)(unaligned_txbd + 16) & 0xFFFFFFF0);
RxBD = (FECBD *)((uint32)(unaligned_rxbd + 16) & 0xFFFFFFF0);
/*
* Initialize the Rx Buffer Descriptor ring
*/
for (i = 0; i < NRXBD; ++i)
{
/* Grab a network buffer from the free list */
nbuf = nbuf_alloc();
ASSERT(nbuf);
/* Initialize the BD */
RxBD[i].status = RX_BD_E | RX_BD_INTERRUPT;
RxBD[i].length = RX_BUF_SZ;
RxBD[i].data = nbuf->data;
/* Add the network buffer to the Rx queue */
nbuf_add(NBUF_RX_RING, nbuf);
}
/*
* Set the WRAP bit on the last one
*/
RxBD[i-1].status |= RX_BD_W;
/*
* Initialize the Tx Buffer Descriptor ring
*/
for (i = 0; i < NTXBD; ++i)
{
TxBD[i].status = TX_BD_INTERRUPT;
TxBD[i].length = 0;
TxBD[i].data = NULL;
}
/*
* Set the WRAP bit on the last one
*/
TxBD[i-1].status |= TX_BD_W;
/*
* Initialize the buffer descriptor indexes
*/
iTxbd_head = iTxbd_tail = iRxbd = 0;
#ifdef DEBUG_PRINT
fecbd_dump();
#endif
}
/********************************************************************/
/*
* Return the address of the first buffer descriptor in the ring.
*
* Parameters:
* direction Rx or Tx Macro
*
* Return Value:
* The start address of the selected Buffer Descriptor ring
*/
uint32
fecbd_get_start(uint8 direction)
{
switch (direction)
{
case Rx:
return (uint32)(RxBD);
case Tx:
default:
return (uint32)(TxBD);
}
}
/********************************************************************/
/*
* This function keeps track of the Rx BD that was next to be modified
* by the FEC
*
* Return Value:
* Pointer to next available buffer descriptor.
* NULL if the BD ring is full
*/
FECBD *
fecbd_rx_alloc(void)
{
int i = iRxbd;
/* Check to see if the ring of BDs is full */
if (RxBD[i].status & RX_BD_E)
return NULL;
/* Increment the circular index */
iRxbd = (uint8)((iRxbd + 1) % NRXBD);
return &RxBD[i];
}
/********************************************************************/
/*
* This function keeps track of the next available Tx BD in the ring
*
* Return Value:
* Pointer to next available buffer descriptor.
* NULL if the BD ring is full
*/
FECBD *
fecbd_tx_alloc(void)
{
int i = iTxbd_head;
/* Check to see if the ring of BDs is full */
if (TxBD[i].status & TX_BD_R)
return NULL;
/* Increment the circular index */
iTxbd_head = (uint8)((iTxbd_head + 1) % NTXBD);
return &TxBD[i];
}
/********************************************************************/
/*
* This function keeps track of the Tx BDs that have already been
* processed by the FEC
*
* Return Value:
* Pointer to the oldest buffer descriptor that has already been sent
* by the FEC, NULL if the BD ring is full
*/
FECBD *
fecbd_tx_free(void)
{
int i = iTxbd_tail;
/* Check to see if the ring of BDs is full */
// if ((TxBD[i].data == NULL) || TxBD[i].status & TX_BD_R)
if (iTxbd_tail == iTxbd_head)
return NULL;
ASSERT((TxBD[i].status & TX_BD_R) == 0);
/* Increment the circular index */
iTxbd_tail = (uint8)((iTxbd_tail + 1) % NTXBD);
return &TxBD[i];
}
/********************************************************************/
/*
* This function dumps the Rx and Tx buffer descriptor rings
*/
void
fecbd_dump(void)
{
#ifdef DEBUG_PRINT
int i;
printf("\nRxBD Ring:\n");
for (i = 0; i < NRXBD; ++i)
{
printf("%d\t0x%04x\t0x%04x\t0x%08x\n",i,
RxBD[i].status,
RxBD[i].length,
RxBD[i].data);
}
printf("\nTxBD Ring:\n");
for (i = 0; i < NTXBD; ++i)
{
printf("%d\t0x%04x\t0x%04x\t0x%08x\n",i,
TxBD[i].status,
TxBD[i].length,
TxBD[i].data);
}
#endif
}
/********************************************************************/
#endif /* #ifdef DBUG_NETWORK */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -