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

📄 mcf5xxx_fecx.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
📖 第 1 页 / 共 3 页
字号:
 *  src     Source MAC Address
 *  type    Ethernet Frame Type
 *  length  Number of bytes to be transmitted (doesn't include type, 
 *          src, or dest byte count)
 *  pkt     Pointer packet network buffer
 *
 * Return Value:
 *  1       success
 *  0       otherwise
 */
int
fec_send (NIF *nif, uint8 *dst, uint8 *src, uint16 type, NBUF *nbuf)
{
    FECBD *pTxBD;
    uint8 ch = (uint8)nif->ch;
    (void) nif;

    #if (FEC_NUM_CH == 1)
        ch = 0;
    #else
        ASSERT(ch < FEC_NUM_CH);
    #endif

    /* Check the length */
    if ((nbuf->length + ETH_HDR_LEN) > ETH_MTU)
        return 0;

    /* 
     * Copy the destination address, source address, and Ethernet 
     * type into the packet 
     */
    memcpy(&nbuf->data[0],  dst,   6);
    memcpy(&nbuf->data[6],  src,   6);
    memcpy(&nbuf->data[12], &type, 2);

    /*
     * Grab the next available Tx Buffer Descriptor
     */
    if ((pTxBD = fecbd_tx_alloc()) == NULL)
        return 0;

    /*
     * Put the network buffer into the Tx waiting queue
     */
    nbuf_add(NBUF_TX_RING, nbuf);

    /* 
     * Setup the buffer descriptor for transmission
     */
    pTxBD->data = nbuf->data;
    pTxBD->length = nbuf->length + ETH_HDR_LEN;
    pTxBD->status |= (TX_BD_R | TX_BD_L | TX_BD_TC);

    /*
     * Continue the Tx DMA task (in case it was waiting for a new
     * TxBD to be ready)
     */
    fec_tx_continue(ch);

    return 1;
}
/********************************************************************/
/* 
 * Resend the last packet that was already prepared and sent
 *
 * Parameters:
 *  ch      FEC channel
 */
void
fec_resend (uint8 ch)
{
    FECBD *pTxBD;
    NBUF *pNbuf;

    #if (FEC_NUM_CH == 1)
        ch = 0;
    #else
        ASSERT(ch < FEC_NUM_CH);
    #endif

    /*
     * Grab the most recently sent TxBD
     */
    pTxBD = fecbd_tx_free();
    ASSERT(pTxBD != NULL);

    /*
     * Grab the network buffer associated with this buffer descriptor
     */
    pNbuf = nbuf_remove(NBUF_TX_RING);
    ASSERT(pNbuf);
    ASSERT(pNbuf->data == pTxBD->data);

    /*
     * Grab the next available Tx Buffer Descriptor
     */
    while ((pTxBD = fecbd_tx_alloc()) == NULL) 
        ;

    /*
     * Put the network buffer back into the Tx waiting queue
     */
    nbuf_add(NBUF_TX_RING, pNbuf);

    /*
     * Reset the TxBD status flags
     */
    pTxBD->data = pNbuf->data;
    pTxBD->length = pNbuf->length + ETH_HDR_LEN;
    pTxBD->status |= (TX_BD_R | TX_BD_L | TX_BD_TC);

    /*
     * Continue the Tx DMA task (in case it was waiting for a new
     * TxBD to be ready)
     */
    fec_tx_continue(ch);
}
/********************************************************************/
/*
 * Enable interrupts from the FEC
 *
 * Parameters:
 *  ch      FEC channel
 */
void
fec_irq_enable(uint8 ch)
{
    #if (FEC_NUM_CH == 1)
        ch = 0;
    #else
        ASSERT(ch < FEC_NUM_CH);
    #endif

    /*
     * Clear any pending FEC interrupt events
     */
    MCF_FEC_EIR(ch) = MCF_FEC_EIR_CLEAR_ALL;

    /*
     * Unmask all FEC interrupts
     */
    MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_UNMASK_ALL;
}
/********************************************************************/
/*
 * Disable interrupts from the FEC
 *
 * Parameters:
 *  ch      FEC channel
 */
void
fec_irq_disable(uint8 ch)
{
    #if (FEC_NUM_CH == 1)
        ch = 0;
    #else
        ASSERT(ch < FEC_NUM_CH);
    #endif

    /*
     * Mask all FEC interrupts
     */
    MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_MASK_ALL;
}
/********************************************************************/
/*
 * FEC interrupt handler
 *
 * Parameters:
 *  arg1    NIF structure
 *  arg2    NULL  
 *
 * Return Value:
 *  Always TRUE (1)
 */
int
fec_irq_handler(void* arg1, void* arg2)
{
    uint32 event, eir;
    uint8 ch = (uint8)((NIF *)arg1)->ch;
    (void) arg2;
    
    /*
     * Determine which interrupt(s) asserted by AND'ing the
     * pending interrupts with those that aren't masked.
     */
    eir = MCF_FEC_EIR(ch);
    event = eir & MCF_FEC_EIMR(ch);

    #ifdef DEBUG
    if (event != eir)
        printf("Pending but not enabled: 0x%08X\n",(event ^ eir));
    #endif

    /*
     * Clear the event(s) in the EIR immediately
     */
    MCF_FEC_EIR(ch) = event;

    if (event & MCF_FEC_EIR_UN)
    {
        fec_log[ch].errors++;
        fec_log[ch].un++;
        #ifdef DEBUG
        printf("FEC Tx FIFO Underflow\n");
        #endif
    }
    if (event & MCF_FEC_EIR_RL)
    {
        fec_log[ch].errors++;
        fec_log[ch].rl++;
        #ifdef DEBUG
        printf("FEC Collision Retry Limit\n");
        #endif
        fec_resend(ch);
    }
    if (event & MCF_FEC_EIR_LC)
    {
        fec_log[ch].errors++;
        fec_log[ch].lc++;
        #ifdef DEBUG
        printf("FEC Late Collision\n");
        #endif
        fec_resend(ch);
    }
    if (event & MCF_FEC_EIR_EBERR)
    {
        fec_log[ch].errors++;
        fec_log[ch].eberr++;
        #ifdef DEBUG
        printf("FEC/DMA fatal bus error!\n");
        #endif
        fec_eth_stop(ch);
    }
    if (event & MCF_FEC_EIR_MII)
    {
        fec_log[ch].mii++;
    }
    if (event & MCF_FEC_EIR_RXB || event & MCF_FEC_EIR_RXF)
    {
        fec_rx_handler((NIF *)arg1);
    }
    if (event & MCF_FEC_EIR_TXB || event & MCF_FEC_EIR_TXF)
    {
        fec_tx_handler((NIF *)arg1);
    }
    if (event & MCF_FEC_EIR_GRA)
    {
        fec_log[ch].gra++;
    }
    if (event & MCF_FEC_EIR_BABT)
    {
        fec_log[ch].errors++;
        fec_log[ch].babt++;
        #ifdef DEBUG
        printf("FEC Babbling transmit error\n");
        #endif
    }
    if (event & MCF_FEC_EIR_BABR)
    {
        fec_log[ch].errors++;
        fec_log[ch].babr++;
        #ifdef DEBUG
        printf("FEC Babbling receive error\n");
        #endif
    }
    if (event & MCF_FEC_EIR_HBERR)
    {
        fec_log[ch].errors++;
        fec_log[ch].hberr++;
        #ifdef DEBUG
        printf("HBERR\n");
        #endif
    }
    
    return TRUE;
}
/********************************************************************/
/*
 * Configure the selected Ethernet port and enable all operations
 *
 * Parameters:
 *  ch      FEC channel
 *  trcvr   Transceiver mode (MII, 7-Wire or internal loopback)
 *  mac     Physical (MAC) Address
 */
void
fec_eth_setup(uint8 ch, uint8 trcvr, const uint8 *mac)
{
    #if (FEC_NUM_CH == 1)
        ch = 0;
    #else
        ASSERT(ch < FEC_NUM_CH);
    #endif

    /*
     * Disable FEC interrupts
     */
    fec_irq_disable(ch);

    /*
     * Initialize the event log
     */
    fec_log_init(ch);

    /*
     * Initialize the network buffers and fec buffer descriptors
     */
    nbuf_init();
    fecbd_init();

    /*
     * Initialize the FEC
     */
    fec_reset(ch);
    fec_init(ch,trcvr,mac);

    if (trcvr == FEC_MODE_MII)
    {
        /*
         * Initialize the MII interface
         */
        fec_mii_init(ch, SYSTEM_CLOCK);
    }

    /*
     * Initialize and enable FEC interrupts
     */
    fec_irq_enable(ch);

    /*
     * Enable the FEC channel
     */
    MCF_FEC_ECR(ch) |= MCF_FEC_ECR_ETHER_EN;

    /*
     * Start the Rx FEC DMA 
     */
    fec_rx_continue(ch);
}
/********************************************************************/
/*
 * Reset the Ethernet port
 *
 * Parameters:
 *  ch      FEC channel
 */
void
fec_eth_reset(uint8 ch)
{
    #if (FEC_NUM_CH == 1)
        ch = 0;
    #else
        ASSERT(ch < FEC_NUM_CH);
    #endif

    fec_reset(ch);
}
/********************************************************************/
/*
 * Stop the selected Ethernet port
 *
 * Parameters:
 *  ch      FEC channel
 */
void
fec_eth_stop(uint8 ch)
{
    int level;
    
    #if (FEC_NUM_CH == 1)
        ch = 0;
    #else
        ASSERT(ch < FEC_NUM_CH);
    #endif

    /*
     * Disable interrupts
     */
    level = asm_set_ipl(7);

    /*
     * Gracefully disable the transmitter
     */
    fec_tx_stop(ch);

    /*
     * Disable FEC interrupts
     */
    fec_irq_disable(ch);

    /*
     * Disable the FEC channel
     */
    MCF_FEC_ECR(ch) &= ~MCF_FEC_ECR_ETHER_EN;

    #ifdef DEBUG
        nbuf_debug_dump();
        fecbd_dump();
        fec_log_dump(ch);
    #endif

    /* 
     * Flush the network buffers
     */
    nbuf_flush();

    /* 
     * Restore interrupt level
     */
    asm_set_ipl(level);
}
/********************************************************************/

#endif /* #ifdef DBUG_NETWORK */

⌨️ 快捷键说明

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