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

📄 csl_emac.c

📁 这是测试SEED-VPM642系统中网络的接口的测试的程序。(闭环)
💻 C
📖 第 1 页 / 共 4 页
字号:
    if( localDev.Config.ModeFlags & EMAC_CONFIG_MODEFLG_PASSCONTROL )
        EMAC_FSETS( RXMBPENABLE, RXCMFEN, ENABLE );

    /* Set the channel configuration to priority if requested */
    if( localDev.Config.ModeFlags & EMAC_CONFIG_MODEFLG_CHPRIORITY )
        EMAC_FSETS( MACCONTROL, TXPTYPE, CHANNELPRI );

    /* Set MAC loopback if requested */
    if( localDev.Config.ModeFlags & EMAC_CONFIG_MODEFLG_MACLOOPBACK )
        EMAC_FSETS( MACCONTROL, LOOPBACK, ENABLE );

    /*
    // Enable TX and RX channel interrupts (set mask bits)
    // Enable Host interrupts
    */
    EMAC_RSET( RXINTMASKCLEAR, 0xFF );
    EMAC_RSET( TXINTMASKCLEAR, 0xFF );
    EMAC_RSET( RXINTMASKSET, 1 );
    for(i=0; i<localDev.Config.TxChannels; i++)
        EMAC_RSET( TXINTMASKSET, (1<<i) );
    EMAC_RSET( MACINTMASKSET, EMAC_FMK(MACINTMASKSET,HOSTERRINT,1) |
                              EMAC_FMK(MACINTMASKSET,STATINT,1) );


    /*
    // Setup Receive Buffers
    */

    /*
    // We give the first descriptors to RX The rest of the descriptors
    // will be divided evenly among the TX channels. Odds are this
    // will leave TX with a very large number of TX descriptors, but
    // we'll only use what we need (driven from the application send
    // requests). The RX descriptors are always kept fully populated.
    */

    /* Pointer to first descriptor to use on RX */
    pDesc = (EMAC_Desc *)_EMAC_DSC_BASE_ADDR;

    /* Number of descriptors for RX channel */
    utemp1 = localDev.Config.RxMaxPktPool;

    /* Init Rx */
    localDev.RxCh.pd         = &localDev;
    localDev.RxCh.DescMax    = utemp1;
    localDev.RxCh.pDescFirst = pDesc;
    localDev.RxCh.pDescLast  = pDesc + (utemp1 - 1);
    localDev.RxCh.pDescRead  = pDesc;
    localDev.RxCh.pDescWrite = pDesc;

    /* Fill the descriptor table */
    emacEnqueueRx( &localDev.RxCh, 0 );

    /*
    // If we didn't get the number of descriptor buffers that the
    // application said we should, then the app lied to us. This is
    // bad because we'll be constantly calling to the app to fill
    // up our buffers. So we'll close now to make the problem
    // obvious.
    */
    if( localDev.RxCh.DescCount < utemp1 )
    {
        /* Free all RX descriptors */
        while( pPkt = pqPop( &localDev.RxCh.DescQueue ) )
            (*localDev.Config.pfcbFreePacket)(localDev.hApplication, pPkt);

        /* Close the MDIO Module */
        MDIO_close( localDev.hMDIO );

        /* Return the error condition */
        return( EMAC_ERROR_INVALID );
    }

    /*
    // Setup Transmit Buffers
    */

    /* Pointer to first descriptor to use on TX */
    pDesc += utemp1;

    /* Number of descriptors (max) per channel */
    utemp1 = (_EDMA_DSC_ENTRY_COUNT-utemp1)/localDev.Config.TxChannels;

    /* Init all TX channels in use */
    for( i=0; i<(int)localDev.Config.TxChannels; i++)
    {
        localDev.TxCh[i].pd         = &localDev;
        localDev.TxCh[i].DescMax    = utemp1;
        localDev.TxCh[i].pDescFirst = pDesc;
        localDev.TxCh[i].pDescLast  = pDesc + (utemp1 - 1);
        localDev.TxCh[i].pDescRead  = pDesc;
        localDev.TxCh[i].pDescWrite = pDesc;

        pDesc += utemp1;
    }


    /*
    // Enable RX, TX, and MII
    //
    // Note in full duplex mode we also need to set the FULLDUPLEX
    // bit in MACCRONTROL. However, we don't know what to set until
    // we have a link. Also, we must be able to dynamically change
    // this bit if the cable is unplugged and re-linked with a different
    // duplex.
    */
    EMAC_FSETS( TXCONTROL, TXEN, ENABLE );
    EMAC_FSETS( RXCONTROL, RXEN, ENABLE );
    EMAC_FSETS( MACCONTROL, MIIEN, ENABLE );

    /* Startup RX */
    EMAC_RSET( RX0HDP, (Uint32)localDev.RxCh.pDescRead );

    /* Validate the device handle */
    localDev.DevMagic = EMAC_DEVMAGIC;

    /* Set the open flag */
    openFlag = 1;

    /* Give a handle back to the caller */
    *phEMAC = &localDev;

    /* Enable global interrupt in wrapper */
    EMAC_FSETS( EWCTL, INTEN, ENABLE );

    /* Return Success */
    return( 0 );
}


/*-----------------------------------------------------------------------*\
* EMAC_close()
*
* Closed the EMAC peripheral indicated by the supplied instance handle.
* When called, the EMAC device will shutdown both send and receive
* operations, and free all pending transmit and receive packets.
*
* The function returns zero on success, or an error code on failure.
*
* Possible error code include:
*   EMAC_ERROR_INVALID   - A calling parameter is invalid
*
\*-----------------------------------------------------------------------*/
uint EMAC_close( Handle hEMAC )
{
    EMAC_Device  *pd = (EMAC_Device *)hEMAC;
    Uint32      i,tmp;
    EMAC_Pkt     *pPkt;

    /* Validate our handle */
    if( !pd || pd->DevMagic != EMAC_DEVMAGIC )
        return( EMAC_ERROR_INVALID );

    /* Disable EMAC/MDIO interrupts in wrapper */
    EMAC_FSETS( EWCTL, INTEN, DISABLE );

    /*
    // The close process consists of tearing down all the active
    // channels (RX and TX) and then waiting for the teardown
    // complete indication from the MAC. Then, all queued packets
    // will be returned.
    */

        /* Teardown RX */
        EMAC_RSET( RXTEARDOWN, 0 );

        /* Teardown TX channels in use */
    for( i=0; i<pd->Config.TxChannels; i++)
        EMAC_RSET( TXTEARDOWN, i );

    /* Only check teardown status if there was no fatal error         */
    /* Otherwise; the EMAC is halted and can抰 be shutdown gracefully */
    if( !pd->FatalError )
        {
        /* Wait for the teardown to complete */
        for( tmp=0; tmp!=0xFFFFFFFC; tmp=EMAC_RGET(RX0INTACK) );
        EMAC_RSET( RX0INTACK, tmp );

            for( i=0; i<pd->Config.TxChannels; i++ )
        {
            for( tmp=0; tmp!=0xFFFFFFFC; tmp=EMAC_RGETI(TXINTACK,i) );
            EMAC_RSETI( TXINTACK, i, tmp );
        }
    }

    /* Disable RX, TX, and Clear MACCONTROL */
    EMAC_FSETS( TXCONTROL, TXEN, DISABLE );
    EMAC_FSETS( RXCONTROL, RXEN, DISABLE );
    EMAC_RSET( MACCONTROL, 0 );

    /* Free all RX buffers */
    while( pPkt = pqPop( &pd->RxCh.DescQueue ) )
        (*pd->Config.pfcbFreePacket)(localDev.hApplication, pPkt);

    /* Free all TX buffers */
    for( i=0; i<pd->Config.TxChannels; i++)
    {
        while( pPkt = pqPop( &pd->TxCh[i].DescQueue ) )
            (*pd->Config.pfcbFreePacket)(localDev.hApplication, pPkt);
        while( pPkt = pqPop( &pd->TxCh[i].WaitQueue ) )
            (*pd->Config.pfcbFreePacket)(localDev.hApplication, pPkt);
    }

    /* Close the MDIO Module */
    MDIO_close( pd->hMDIO );

    /* Invalidate the EMAC handle */
    pd->DevMagic = 0;

    /* Clear the open flag */
    openFlag = 0;

    /* Exit with interrupts still disabled in the wrapper */
    return(0);
}


/*-----------------------------------------------------------------------*\
* EMAC_getStatus()
*
* Called to get the current status of the device. The device status
* is copied into the supplied data structure.
*
* The function returns zero on success, or an error code on failure.
*
* Possible error code include:
*   EMAC_ERROR_INVALID   - A calling parameter is invalid
*
\*-----------------------------------------------------------------------*/
uint EMAC_getStatus( Handle hEMAC, EMAC_Status *pStatus )
{
    EMAC_Device  *pd = (EMAC_Device *)hEMAC;
    uint        i,tmp;

    /* Validate our handle */
    if( !pd || pd->DevMagic != EMAC_DEVMAGIC || !pStatus )
        return( EMAC_ERROR_INVALID );

    /* Get the MDIO status */
    MDIO_getStatus(pd->hMDIO, &pStatus->PhyDev, &pStatus->MdioLinkStatus );

    /* Number of rx packets held */
    pStatus->RxPktHeld = pd->RxCh.DescCount;

    /* Number of tx packets held */
    tmp = 0;
    for( i=0; i<pd->Config.TxChannels; i++)
    {
        tmp += pd->TxCh[i].DescCount;
        tmp += pd->TxCh[i].WaitQueue.Count;
    }
    pStatus->TxPktHeld = tmp;

    /* Fatal error value */
    pStatus->FatalError = pd->FatalError;

    return(0);
}


/*-----------------------------------------------------------------------*\
* EMAC_setReceiveFilter()
*
* Called to set the packet filter for received packets. The filtering
* level is inclusive, so BROADCAST would include both BROADCAST and
* DIRECTED (UNICAST) packets.
*
* Available filtering modes include the following:
*  EMAC_RXFILTER_NOTHING      - Receive nothing
*  EMAC_RXFILTER_DIRECT       - Receive only Unicast to local MAC addr
*  EMAC_RXFILTER_BROADCAST    - Receive direct and Broadcast
*  EMAC_RXFILTER_MULTICAST    - Receive above plus multicast in mcast list
*  EMAC_RXFILTER_ALLMULTICAST - Receive above plus all multicast
*  EMAC_RXFILTER_ALL          - Receive all packets
*
* Note that if error frames and control frames are desired, reception of
* these must be specified in the device configuration.
*
* The function returns zero on success, or an error code on failure.
*
* Possible error code include:
*   EMAC_ERROR_INVALID   - A calling parameter is invalid
*
\*-----------------------------------------------------------------------*/
uint EMAC_setReceiveFilter( Handle hEMAC, uint ReceiveFilter )
{
    EMAC_Device  *pd = (EMAC_Device *)hEMAC;

    /* Validate our handle */
    if( !pd || pd->DevMagic != EMAC_DEVMAGIC || ReceiveFilter > EMAC_RXFILTER_ALL )
        return( EMAC_ERROR_INVALID );

    /*
    // The following code relies on the numberic relation of the filter
    // value such that the higher filter values receive more types of
    // packets.
    */

    /* Disable Section */
    if( ReceiveFilter < EMAC_RXFILTER_ALL )
        EMAC_FSETS( RXMBPENABLE, RXCAFEN, DISABLE );
    if( ReceiveFilter < EMAC_RXFILTER_ALLMULTICAST )
    {
        EMAC_RSET( MACHASH1, pd->MacHash1 );
        EMAC_RSET( MACHASH2, pd->MacHash2 );
    }
    if( ReceiveFilter < EMAC_RXFILTER_MULTICAST )
        EMAC_FSETS( RXMBPENABLE, MULTEN, DISABLE );
    if( ReceiveFilter < EMAC_RXFILTER_BROADCAST )
        EMAC_FSETS( RXMBPENABLE, BROADEN, DISABLE );
    if( ReceiveFilter < EMAC_RXFILTER_DIRECT )
        EMAC_RSET( RXUNICASTCLEAR, 1 );

    /* Enable Section */
    if( ReceiveFilter >= EMAC_RXFILTER_DIRECT )
        EMAC_RSET( RXUNICASTSET, 1 );
    if( ReceiveFilter >= EMAC_RXFILTER_BROADCAST )
        EMAC_FSETS( RXMBPENABLE, BROADEN, ENABLE );
    if( ReceiveFilter >= EMAC_RXFILTER_MULTICAST )
        EMAC_FSETS( RXMBPENABLE, MULTEN, ENABLE );
    if( ReceiveFilter >= EMAC_RXFILTER_ALLMULTICAST )
    {
        EMAC_RSET( MACHASH1, 0xffffffff );
        EMAC_RSET( MACHASH1, 0xffffffff );
    }
    if( ReceiveFilter == EMAC_RXFILTER_ALL )
        EMAC_FSETS( RXMBPENABLE, RXCAFEN, ENABLE );

    pd->RxFilter = ReceiveFilter;
    return(0);
}


/*-----------------------------------------------------------------------*\
* EMAC_getReceiveFilter()
*
* Called to get the current packet filter setting for received packets.
* The filter values are the same as those used in EMAC_setReceiveFilter().
*
* The current filter value is writter to the pointer supplied in
* pReceiveFilter.
*
* The function returns zero on success, or an error code on failure.
*
* Possible error code include:
*   EMAC_ERROR_INVALID   - A calling parameter is invalid
*
\*-----------------------------------------------------------------------*/
uint EMAC_getReceiveFilter( Handle hEMAC, uint *pReceiveFilter )
{
    EMAC_Device  *pd = (EMAC_Device *)hEMAC;

    /* Validate our handle */
    if( !pd || pd->DevMagic != EMAC_DEVMAGIC || !pReceiveFilter )
        return( EMAC_ERROR_INVALID );

    *pReceiveFilter = pd->RxFilter;
    return(0);
}


⌨️ 快捷键说明

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