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

📄 mcf5xxx_fecbd.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 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 + -