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

📄 c6455.c

📁 TI公司的NSP
💻 C
📖 第 1 页 / 共 3 页
字号:
                // Enable Section
                if( pi->Filter >= ETH_PKTFLT_DIRECT )
                        EMAC_REGS->RXUNICASTSET = 1;

                if( pi->Filter >= ETH_PKTFLT_BROADCAST )
                        CSL_FINST( EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXBROADEN, ENABLE );

                if( pi->Filter >= ETH_PKTFLT_MULTICAST )
                        CSL_FINST( EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXMULTEN, ENABLE );

                if( pi->Filter >= ETH_PKTFLT_ALLMULTICAST )
                {
                        EMAC_REGS->MACHASH1 = 0xffffffff;
                        EMAC_REGS->MACHASH1 = 0xffffffff;
                }
                if( pi->Filter == ETH_PKTFLT_ALL )
                        CSL_FINST( EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCAFEN, ENABLE );
        }
 }

//--------------------------------------------------------------------
// HwPktTxNext()
//
// Transmit Next Packet on Tx Queue
//--------------------------------------------------------------------
void HwPktTxNext( PDINFO *pi )
{
    register EMAC_Desc *pDescThis;
    register UINT8     *buffer;
    register uint      length;
    PBM_Handle         hPkt;
    uint               intmask;

    // Make sure we have a packet to send
    if( !(hPkt = PBMQ_deq(&pi->PBMQ_tx)) )
    {
        pi->TxFree = 1;
        return;
    }

    buffer = PBM_getDataBuffer(hPkt) + PBM_getDataOffset(hPkt);
    length = PBM_getValidLen(hPkt);

    // Clean the cache for external addesses
    if( (UINT32)buffer & EXTMEM )
        OEMCacheClean( (void *)buffer, length );

    // Disable our device interrupt
    intmask = C64_disableIER( IntFlag );

    // This can't happen, but check anyway
    if( chTx.DescCount == chTx.DescMax )
    {
        PBM_free( hPkt );
        goto send_exit;
    }

    // Assign the pointer to "this" desc
    pDescThis = chTx.pDescWrite;

    // Move the write pointer and bump count
    if( pDescThis == chTx.pDescLast )
        chTx.pDescWrite = chTx.pDescFirst;
    else
        chTx.pDescWrite++;
    chTx.DescCount++;

    // Fill out the descriptor
    pDescThis->pNext     = 0;
    pDescThis->pBuffer   = buffer;
    pDescThis->BufOffLen = length;
    pDescThis->PktFlgLen = EMAC_DSC_FLAG_SOP | EMAC_DSC_FLAG_EOP |
                           length | EMAC_DSC_FLAG_OWNER;

    // Enqueue this packet onto the desc queue
    PBMQ_enq( &chTx.DescQueue, hPkt );

    // Synch the cache
    if( (UINT32)buffer & EXTMEM )
        OEMCacheCleanSynch();

    // Start it sending
    if( chTx.DescCount > 1 )
    {
        // Transmitter is already running.
        // Make the previous buffer point to us
        if( pDescThis == chTx.pDescFirst )
             chTx.pDescLast->pNext = pDescThis;
        else
            (pDescThis-1)->pNext = pDescThis;
    }
    else
    {
        // Transmitter is not running, start it up
        EMAC_REGS->TX0HDP = (Uint32)pDescThis ;
    }

send_exit:
    C64_enableIER( intmask );
}

//--------------------------------------------------------------------
// _HwPktPoll()
//
// Poll routine - CALLED OUTSIDE OF KERNEL MODE
//
// This function is called at least every 100ms, faster in a
// polling environment. The fTimerTick flag is set only when
// called on a 100ms event.
//--------------------------------------------------------------------
void _HwPktPoll( PDINFO *pi, uint fTimerTick )
{
    uint intmask;
    uint mdioStatus,phy,linkStatus;

    (void)pi;

    if( fTimerTick && hMDIO )
    {
        LED_TOGGLE( USER_LED2 );
        if( FlashActiveLED )
        {
            FlashActiveLED = 0;
        LED_TOGGLE( USER_LED3 );
        }

        llEnter();
        intmask = C64_disableIER( IntFlag );

        // Signal the MDIO
        mdioStatus = MDIO_timerTick( hMDIO );

        // Track new or lost link
        if( mdioStatus == MDIO_EVENT_LINKDOWN ||
            mdioStatus == MDIO_EVENT_LINKUP )
        {
            MDIO_getStatus( hMDIO, &phy, &linkStatus );

            // On a new link, set the EMAC duplex
            if( mdioStatus == MDIO_EVENT_LINKUP )
            {
                if( linkStatus == MDIO_LINKSTATUS_FD10 ||
                    linkStatus == MDIO_LINKSTATUS_FD100 ||
                    linkStatus == MDIO_LINKSTATUS_FD1000 )
                {
                    CSL_FINST( EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_FULLDUPLEX, ENABLE );

                                        if ( macsel == CSL_DEV_DEVSTAT_MACSEL_RMII )
                                                CSL_FINST(EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_RMIIDUPLEXMODE, FULLDUPLEX );
                }
                else
                {
                    CSL_FINST( EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_FULLDUPLEX, DISABLE );
                                        if ( macsel == CSL_DEV_DEVSTAT_MACSEL_RMII )
                                                CSL_FINST(EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_RMIIDUPLEXMODE, HALFDUPLEX );
                }

                                if( linkStatus == MDIO_LINKSTATUS_FD1000 )
                                                CSL_FINST(EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_GIG, ENABLE );

                                if(( (linkStatus == MDIO_LINKSTATUS_HD10 ) ||
                                        ( linkStatus == MDIO_LINKSTATUS_FD10 )) &&
                                        ( macsel == CSL_DEV_DEVSTAT_MACSEL_RMII ))
                                                CSL_FINST(EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_RMIISPEED, 2_5MHZ );

                                if(( (linkStatus == MDIO_LINKSTATUS_HD100 ) ||
                                        ( linkStatus == MDIO_LINKSTATUS_FD100 )) &&
                                        ( macsel == CSL_DEV_DEVSTAT_MACSEL_RMII ))
                                                CSL_FINST(EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_RMIISPEED, 25MHZ );

                                //The following 2 settings apply only to PG 2.0
                                if ( macsel == CSL_DEV_DEVSTAT_MACSEL_RMII )            // Take RMII out of reset
                                        CSL_FINST(DEV_REGS->EMACCFG, DEV_EMACCFG_RMIIRST, RELEASE );

                                if ( macsel == CSL_DEV_DEVSTAT_MACSEL_RGMII )           // Put RGMII in forced link mode
                                        CSL_FINST(EMAC_REGS->MACCONTROL, EMAC_MACCONTROL_RGMIIEN, DISABLE );

                // Now that we have a link, send any queued packets
                while( !pi->TxFree )
                    HwPktTxNext( pi );
            }

            // Tell application
            C6455EMAC_linkStatus( phy, linkStatus );
        }

        // Re-fill Rx buffer queue if needed
        if( chRx.DescCount != chRx.DescMax )
            emacEnqueueRx( 1 );

        C64_enableIER( intmask );
        llExit();
    }
}

//--------------------------------------------------------------------
// HwInt()
//
// EMAC Hardware Interrupt
//--------------------------------------------------------------------
void HwInt(void)
{
    Uint32      intflags,Desc;
    uint        tmp;

    // Disable EMAC/MDIO interrupts in wrapper
    CSL_FINST( ECTL_REGS->EWCTL, ECTL_EWCTL_INTEN, DISABLE );

    // Read the interrupt cause
    intflags = EMAC_REGS->MACINVECTOR ;

    // Look for fatal errors first
    if( intflags & CSL_FMK( EMAC_MACINVECTOR_HOSTPEND, 1 ) )
    {
        // A fatal error can only be caused by a software
        // logic error. We'll read the fatal error code
        // and exit with the EMAC interrupt still disabled.
        // This will halt all network functionality. The
        // application programmer can manually check the
        // status of C6455EMAC_FatalError if the network
        // stops working.
        C6455EMAC_FatalError = EMAC_REGS->MACSTATUS ;
        return;
    }

    // Look for statistics interrupt
    if( intflags & CSL_FMK( EMAC_MACINVECTOR_STATPEND, 1 ) )
    {
        volatile Uint32 *pRegAddr;
        Uint32 statval;

        pRegAddr = &EMAC_REGS->RXGOODFRAMES ;

        /*
        // There are "EMAC_NUMSTATS" statistics registers
        // Note that when MIIEN is set in MACCONTROL, these registers
        // are "write to decrement".
        */
        for( tmp=0; tmp<EMAC_NUMSTATS; tmp++ )
        {
            statval = *pRegAddr;
            *pRegAddr++ = statval;
        }
    }

    // Look for TX interrupt (channel 0)
    if( intflags & CSL_FMK( EMAC_MACINVECTOR_TXPEND, 1<<0 ) )
    {
        Desc = EMAC_REGS->TX0CP;
        EMAC_REGS->TX0CP = Desc ;

        emacDequeueTx( (EMAC_Desc *)Desc );
    }

    // Look for RX interrupt (channel 0)
    if( intflags & CSL_FMK( EMAC_MACINVECTOR_RXPEND, 1<<0 ) )
    {
        Desc = EMAC_REGS->RX0CP ;
        EMAC_REGS->RX0CP = Desc ;

        emacDequeueRx( (EMAC_Desc *)Desc );
    }

    // Enable EMAC/MDIO interrupts in wrapper
    CSL_FINST( ECTL_REGS->EWCTL, ECTL_EWCTL_INTEN, ENABLE );
}

/*--------------------------------------------------------------------*\
* emacInit()
*
* Initialize EMAC. Return "1" if all is OK
\*--------------------------------------------------------------------*/
static uint emacInit()
{
    Uint32          tmpval;
    int             i;
    volatile Uint32 *pRegAddr;
    uint            utemp1;
    EMAC_Desc       *pDesc;
    PBM_Handle      hPkt;

    /*
    //  Initialize the EMAC and MDIO devices
    */

    ECTL_REGS->EWCTL = CSL_FMKT(ECTL_EWCTL_INTEN, DISABLE );

        /* Reset EMAC */
        EMAC_REGS->SOFTRESET = 0x1;
        while (EMAC_REGS->SOFTRESET != 0x0);

    /* Program the interrupt pacer */
    ECTL_REGS->EWINTTCNT = 4000;

    /* Start the MII Configuration */
    hMDIO = MDIO_open( MDIO_MODEFLG_AUTONEG );

    /*
    //  Setup the EMAC
    */

    /* Reset MAC Control */
    EMAC_REGS->MACCONTROL = 0 ;

    /* Must manually init HDPs to NULL */
    pRegAddr = &EMAC_REGS->TX0HDP;
    for( i=0; i<8; i++ )
        *pRegAddr++ = 0;
    pRegAddr = &EMAC_REGS->RX0HDP;
    for( i=0; i<8; i++ )
        *pRegAddr++ = 0;

    /*
    // While GMIIEN is clear in MACCONTROL, we can write directly to
    // the statistics registers (there are "EMAC_NUMSTATS" of them).
    */
    pRegAddr = &EMAC_REGS->RXGOODFRAMES;
    for( i=0; i<EMAC_NUMSTATS; i++ )
        *pRegAddr++ = 0;

        /* Initialize the RAM locations */
        for (i = 0; i < 32; i++)
        {
                EMAC_REGS->MACINDEX = i;
                EMAC_REGS->MACADDRHI = 0;
                EMAC_REGS->MACADDRLO = 0;
        }

    /* Setup device MAC address */
    EMAC_REGS->MACINDEX = 0x0;

    tmpval = 0;
    for( i=3; i>=0; i-- )
        tmpval = (tmpval<<8) | *(pPDI->bMacAddr+i);
    EMAC_REGS->MACADDRHI = tmpval;

    tmpval = *(pPDI->bMacAddr+5);
    EMAC_REGS->MACADDRLO =      CSL_FMKT( EMAC_MACADDRLO_VALID, VALID ) |
                                                CSL_FMKT( EMAC_MACADDRLO_MATCHFILT, MATCH ) |
                                                CSL_FMK( EMAC_MACADDRLO_CHANNEL, 0 ) |
                                                (tmpval<<8) |
                                                *(pPDI->bMacAddr+4) ;

    /* For us buffer offset will always be zero */
    EMAC_REGS->RXBUFFEROFFSET = 0;

    /* Reset RX (M)ulticast (B)roadcast (P)romiscuous Enable register */

⌨️ 快捷键说明

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