📄 c6455.c
字号:
/*
* 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 + -