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

📄 c6455_emac.c

📁 ti的TMS320C64XEMAC应用源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    {
        CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCEFEN, ENABLE );
        CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCSFEN, ENABLE );
    }

    /* If PASSCONTROL is set, enable control frames */
    if( localDev.Config.ModeFlags & EMAC_CONFIG_MODEFLG_PASSCONTROL )
        CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCMFEN, ENABLE );

    /* Set the channel configuration to priority if requested */
    if( localDev.Config.ModeFlags & EMAC_CONFIG_MODEFLG_CHPRIORITY )
        CSL_FINST(EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_TXPTYPE, CHANNELPRI );

    /* Set MAC loopback if requested */
    if( localDev.Config.ModeFlags & EMAC_CONFIG_MODEFLG_MACLOOPBACK )
        CSL_FINST(EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_LOOPBACK, ENABLE );

    /*
    // Enable TX and RX channel interrupts (set mask bits)
    // Enable Host interrupts
    */
    EMAC_REGS->RXINTMASKCLEAR = 0xFF;
    EMAC_REGS->TXINTMASKCLEAR, 0xFF;
    EMAC_REGS->RXINTMASKSET = 1;
    for(i=0; i<localDev.Config.TxChannels; i++)
        EMAC_REGS->TXINTMASKSET = (1<<i);
    EMAC_REGS->MACINTMASKSET = CSL_FMK(EMAC_MACINTMASKSET_HOSTMASK, 1) |
                               CSL_FMK(EMAC_MACINTMASKSET_STATMASK, 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 GMII
    //
    // 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.
    */
    CSL_FINST( EMAC_REGS->TXCONTROL, EMAC_TXCONTROL_TXEN, ENABLE );
    CSL_FINST( EMAC_REGS->RXCONTROL, EMAC_RXCONTROL_RXEN, ENABLE );

#if USE_EMAC_OPT
    CSL_FINST( EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_RXOWNERSHIP, ONE );
    CSL_FINST( EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_RXOFFLENBLOCK, BLOCK );
#endif

    CSL_FINST( EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_GMIIEN, ENABLE );

    /* Startup RX */
    EMAC_REGS->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 */
    CSL_FINST( ECTL_REGS->EWCTL, ECTL_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;
    volatile Uint32 *pRegAddr;

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

    /* Disable EMAC/MDIO interrupts in wrapper */
    CSL_FINST(ECTL_REGS->EWCTL, ECTL_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_REGS->RXTEARDOWN = 0 ;

        /* Teardown TX channels in use */
    for( i=0; i<pd->Config.TxChannels; i++)
        EMAC_REGS->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_REGS->RX0CP );
        EMAC_REGS->RX0CP = tmp;

		pRegAddr = &EMAC_REGS->TX0CP;
		for( i=0; i<pd->Config.TxChannels; i++ )
		{
			for( tmp=0; tmp!=0xFFFFFFFC; tmp=*(pRegAddr + i) );
			*(pRegAddr + i) = tmp;
		}
    }

    /* Disable RX, TX, and Clear MACCONTROL */
    CSL_FINST(EMAC_REGS->TXCONTROL, EMAC_TXCONTROL_TXEN, DISABLE );
    CSL_FINST(EMAC_REGS->RXCONTROL, EMAC_RXCONTROL_RXEN, DISABLE );
    EMAC_REGS->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 numeric relation of the filter
    // value such that the higher filter values receive more types of
    // packets.
    */

    /* Disable Section */
    if( ReceiveFilter < EMAC_RXFILTER_ALL )
        CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCAFEN, DISABLE );

    if( ReceiveFilter < EMAC_RXFILTER_ALLMULTICAST )
    {
#if !RAM_MCAST
        EMAC_REGS->MACHASH1 = pd->MacHash1;
        EMAC_REGS->MACHASH2 = pd->MacHash2;
#else
        /* Don't set any hash bits - we handle them in the MACADDR table */
        EMAC_REGS->MACHASH1 = 0 ;
        EMAC_REGS->MACHASH2 = 0 ;
#endif
    }

    if( ReceiveFilter < EMAC_RXFILTER_MULTICAST )
        CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXMULTEN, DISABLE );

    if( ReceiveFilter < EMAC_RXFILTER_BROADCAST )
        CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXBROADEN, DISABLE );

    if( ReceiveFilter < EMAC_RXFILTER_DIRECT )
        EMAC_REGS->RXUNICASTCLEAR = 1;

    /* Enable Section */
    if( ReceiveFilter >= EMAC_RXFILTER_DIRECT )
        EMAC_REGS->RXUNICASTSET = 1;
    if( ReceiveFilter >= EMAC_RXFILTER_BROADCAST )
        CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXBROADEN, ENABLE );

#if !RAM_MCAST
    if( ReceiveFilter >= EMAC_RXFILTER_MULTICAST )
        CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXMULTEN, ENABLE );
#endif

    if( ReceiveFilter >= EMAC_RXFILTER_ALLMULTICAST )
    {
        EMAC_REGS->MACHASH1 = 0xffffffff;
        EMAC_REGS->MACHASH1 = 0xffffffff;
    }
    if( ReceiveFilter == EMAC_RXFILTER_ALL )
        CSL_FINST(EMAC_REGS->RXMBPENABLE, EMAC_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);
}


/*-----------------------------------------------------------------------*\
* EMAC_getStatistics()
*
* Called to get the current device statistics. The statistics structure
* contains a collection of event counts for various packet sent and
* receive properties. Reading the statistics also clears the current
* statistic counters, so the values read represent a delta from the last
* call.
*
* The statistics information is copied into the structure pointed to
* by the pStatistics argument.
*
* The function returns zero on success, or an error code on failure.
*
* Possible error code include:
*   EMAC_ERROR_INVALID   - A calling parameter is invalid
*
\*-----------------------------------------------------------------------*/

⌨️ 快捷键说明

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