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

📄 c6455.c

📁 TI公司的NSP
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *  Copyright 2007 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *
 *  @(#) TCP/IP_Network_Developers_Kit 1.92.00.22 01-10-2007 (ndk-b22)
 */
/*
 *  ======== c6455.c ========
 *
 *
 */

//--------------------------------------------------------------------------
// IP Stack
//--------------------------------------------------------------------------
// C6455.c
//
// C6455 EMAC Packet Driver
//
// Author: Michael A. Denio
//                 Magdalena B. Iovescu
//
// Copyright 2006 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <std.h>
#include <sys.h>
#include <hwi.h>
#include <bcache.h>
#include <c64.h>

#include <stkmain.h>
#include "c6455_common.h"
#include "c6455_mdio.h"
#include "llpacket.h"

#define EXTMEM          0x80000000

//
// This single global can be checked via CCS if there's trouble
//
uint  C6455EMAC_FatalError = 0;

//
// Configuration (Obtained via callback)
//
extern void                             C6455EMAC_getConfig( UINT8 *pMacAddr, uint *pIntVector );
extern void                             C6455EMAC_linkStatus( uint phy, uint linkStatus );
extern Uint32                   macsel;
static UINT8                    bMacAddr[6];                                                                                    // MAC Address
static uint                             IntVector = 5;                                                  // Interrupt vector to use
static uint                     IntFlag;                                                                                        // Interrupt flag (1<<IntVector)

// Transmit/Receive Descriptor Channel Structure
// (One receive and one transmit in this driver)
typedef struct _EMAC_DescCh {
    PBMQ            DescQueue;    // Packets queued as desc
    uint            DescMax;      // Max number of desc (buffs)
    uint            DescCount;    // Current number of desc
    EMAC_Desc       *pDescFirst;  // First desc location
    EMAC_Desc       *pDescLast;   // Last desc location
    EMAC_Desc       *pDescRead;   // Location to read next desc
    EMAC_Desc       *pDescWrite;  // Location to write nest desc
} EMAC_DescCh;

static EMAC_DescCh chTx;
static EMAC_DescCh chRx;

static uint FlashActiveLED = 0;

#define EMAC_NUMSTATS   36         // The number of statistics regs

//
// RX Buffer Depth
//
// We set this to 32 by default. This is the max (typical) number
// of free buffers ready for rx packets.
//
// Note that this driver always assumes it can enqueue a new TX
// packet to the EMAC. It justifies this by assuming that the size of
// its transmit descriptor chain (512 - EMAC_MAX_RX) is greater than
// or equal to the size of the free packet buffer pool (defined by
// PKT_NUM_FRAMEBUF in pbm.c). Thus the value of EMAC_MAX_RX
// plus the size of PKT_NUM_FRAMEBUF (defaults to 48) must be less
// than or equal to 512 for the driver to work properly.
//
#define EMAC_MAX_RX     64

// Local instance information pointer for our single device instance
static PDINFO *pPDI = 0;
static Handle hMDIO = 0;

// Local Functions
void HwInt();
static uint emacInit();
static void emacDequeueTx( EMAC_Desc *pDescAck );
static void emacEnqueueRx( uint fRestart );
static void emacDequeueRx( EMAC_Desc *pDescAck );


//--------------------------------------------------------------------
// HwPktInit()
//
// Initialize Device environment and return instance count
//--------------------------------------------------------------------
uint HwPktInit()
{
    //
    // Get our MAC address and interrupt to use
    //
    C6455EMAC_getConfig( bMacAddr, &IntVector );
    IntFlag = 1<<IntVector;

    return(1);
}

//--------------------------------------------------------------------
// HwPktShutdown()
//
// Shutdown Device Environment
//--------------------------------------------------------------------
void HwPktShutdown()
{
}

//--------------------------------------------------------------------
// HwPktOpen()
//
// Open Device Instance
//--------------------------------------------------------------------
uint HwPktOpen( PDINFO *pi )
{
    uint        ReturnCode = 1;


    // We only have one device, so store off the PDINFO pointer as
    // global to this module. Otherwise; we'd pick an unclaimed device
    // and associate it with the PDINFO.

    // Disable our general purpose interrupt
    C64_disableIER( IntFlag );

    // If pPDI is already set, this is a restart.
    if( !pPDI )
    {
        //
        // Now initialize the EMAC device
        //
        pPDI = pi;

        HWI_eventMap( IntVector, 17 );

        // Hook our interrupt
        HWI_dispatchPlug( IntVector, (Fxn)HwInt, -1, 0 );

        /*
         *  The DSP/BIOS DDTS#26585 fix invalidates the cache
         *  as a part of HWI_dispatchPlug call. 
         *    
         */
        BCACHE_invL1pAll();

    }

    // Use the new PDINFO
    pPDI = pi;

    // Copy in the MAC address from the configuration
    mmCopy( pPDI->bMacAddr, bMacAddr, 6 );

    // Initialize the EMAC
    ReturnCode = emacInit();

    // Enable our general purpose interrupt
    C64_enableIER( IntFlag );

    // Say not ready to send (we wait for link)
    pi->TxFree = 0;

    return(ReturnCode);
}

//--------------------------------------------------------------------
// HwPktClose()
//
// Close Device Instance
//--------------------------------------------------------------------
void HwPktClose( PDINFO *pi )
{
    PBM_Handle  hPkt;

    (void)pi;

    // Disable the DSP interrupt
    C64_disableIER( IntFlag );

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

    // Teardown RX
    EMAC_REGS->RXTEARDOWN = 0;

    // Teardown TX
    EMAC_REGS->TXTEARDOWN = 0;

    // 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( hPkt = PBMQ_deq( &chRx.DescQueue ) )
        PBM_free( hPkt );

    // Free all TX buffers
    while( hPkt = PBMQ_deq( &chTx.DescQueue ) )
        PBM_free( hPkt );

    // Close the MDIO Module
    MDIO_close( hMDIO );
}

//--------------------------------------------------------------------
// HwPktSetRx()
//
// Update Rx Mode (Rx filter and multicast hash table)
//--------------------------------------------------------------------
void HwPktSetRx( PDINFO *pi )
{
    uint        tmp1,tmp2;
        int                     i;
    Uint8       HashVal,tmpval,*pMCastList;
    UINT32      temp,temp1,MacHash1,MacHash2;

        if ( RAM_MCAST && (PKT_MAX_MCAST < 32) )        // Use RAM multicast
        {

                // Clear the multicast list
                for (i = 1; i < 32; i++)
                {
                        EMAC_REGS->MACINDEX = i;
                        EMAC_REGS->MACADDRHI = 0;
                        EMAC_REGS->MACADDRLO = 0;
                }

                // For each address in the list, add it to the RAM
                pMCastList = pi->bMCast;
                for( tmp1=0; tmp1<pi->MCastCnt; tmp1++ )
                {
                        EMAC_REGS->MACINDEX = tmp1+1;

                        temp = 0;

                        for( i=3; i>=0; i-- )
                                temp = (temp<<8) | *(pMCastList+i);
                        EMAC_REGS->MACADDRHI = temp;

                        temp = *(pMCastList+4);
                        temp1 = *(pMCastList+5);
                        EMAC_REGS->MACADDRLO = CSL_FMKT( EMAC_MACADDRLO_VALID, VALID ) |
                                   CSL_FMKT( EMAC_MACADDRLO_MATCHFILT, MATCH ) |
                                   CSL_FMK( EMAC_MACADDRLO_CHANNEL, 0 ) |
                                   (temp1<<8) | temp ;
            pMCastList+=6;
                }

                // Disable Section
                if( pi->Filter < ETH_PKTFLT_ALL )
                        CSL_FINST( EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCAFEN, DISABLE );

                if( pi->Filter < ETH_PKTFLT_BROADCAST )
                        CSL_FINST( EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXBROADEN, DISABLE );

                if( pi->Filter < ETH_PKTFLT_DIRECT )
                        EMAC_REGS->RXUNICASTCLEAR = 1;


                // 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_ALLMULTICAST )
                {
                        EMAC_REGS->MACHASH1 = 0xffffffff;
                        EMAC_REGS->MACHASH1 = 0xffffffff;
                }

                if( pi->Filter == ETH_PKTFLT_ALL )
                        CSL_FINST( EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCAFEN, ENABLE );
        }

        if ( HASH_MCAST )       // Use hash tables multicast
        {
                // Clear the hash bits
                MacHash1 = 0;
                MacHash2 = 0;

                // For each address in the list, hash and set the bit
                pMCastList = pi->bMCast;
                for( tmp1=0; tmp1<pi->MCastCnt; tmp1++ )
                {
                        HashVal=0;

                        for( tmp2=0; tmp2<2; tmp2++ )
                        {
                                tmpval = *pMCastList++;
                                HashVal ^= (tmpval>>2)^(tmpval<<4);
                                tmpval = *pMCastList++;
                                HashVal ^= (tmpval>>4)^(tmpval<<2);
                                tmpval = *pMCastList++;
                                HashVal ^= (tmpval>>6)^(tmpval);
                        }

                        if( HashVal & 0x20 )
                                MacHash2 |= (1<<(HashVal&0x1f));
                        else
                                MacHash1 |= (1<<(HashVal&0x1f));
                }

                // 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( pi->Filter < ETH_PKTFLT_ALL )
                        CSL_FINST( EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXCAFEN, DISABLE );

                if( pi->Filter < ETH_PKTFLT_ALLMULTICAST )
                {
                        EMAC_REGS->MACHASH1 = MacHash1;
                        EMAC_REGS->MACHASH2 = MacHash2;
                }

                if( pi->Filter < ETH_PKTFLT_MULTICAST )
                        CSL_FINST( EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXMULTEN, DISABLE );

                if( pi->Filter < ETH_PKTFLT_BROADCAST )
                        CSL_FINST( EMAC_REGS->RXMBPENABLE, EMAC_RXMBPENABLE_RXBROADEN, DISABLE );

                if( pi->Filter < ETH_PKTFLT_DIRECT )
                        EMAC_REGS->RXUNICASTCLEAR = 1;


⌨️ 快捷键说明

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