📄 mxf.c
字号:
EDMA_RSETH(hEDMA_rld,SRC,0xa0000000);
EDMA_RSETH(hEDMA_rld,CNT,0);
EDMA_RSETH(hEDMA_rld,DST,0xa0000000);
EDMA_RSETH(hEDMA_rld,IDX,0);
EDMA_RSETH(hEDMA_rld,RLD,0);
// Enable out general purpose interrupt
C62_enableIER( HW_IFLAG );
}
// Use the new PDINFO
pGMI = pi;
// Reset
gmReset();
// Read our MAC address
*(UINT32 *)pi->bMacAddr = READ32( GMAC_ADDR1 );
*(UINT16 *)(pi->bMacAddr+4) = (UINT16)(READ32( GMAC_ADDR2 ));
// Start
gmStart();
return(1);
}
//--------------------------------------------------------------------
// HwPktClose()
//
// Close Device Instance
//--------------------------------------------------------------------
void HwPktClose( PDINFO *pi )
{
(void)pi;
// Normally we'd shut off the part, but here we'll only
// stop it. This is because it can't handle a soft reset.
gmStop();
}
//--------------------------------------------------------------------
// gmHashIndex()
//
// Calculate the Hash table index for one 6 byte address
//--------------------------------------------------------------------
#define POLY32 0x04c11db7
static unsigned int gmHashIndex( UINT8 *Address )
{
unsigned int Crc = 0xffffffff;
unsigned int Msb;
unsigned char Byte;
int ByteLen, Bit;
for( ByteLen=0; ByteLen<6; ByteLen++ )
{
Byte = *Address++;
for (Bit=0; Bit<8 ; Bit++)
{
Msb = Crc >> 31;
Crc <<= 1;
if( (Msb ^ (Byte>>Bit)) & 1 )
Crc ^= POLY32;
}
}
return( Crc>>26 );
}
//--------------------------------------------------------------------
// HwPktSetRx()
//
// Update Rx Mode (Rx filter and multicast hash table)
//--------------------------------------------------------------------
void HwPktSetRx( PDINFO *pi )
{
UINT32 Addr[3];
UINT32 control;
uint i,idx;
//
// Setup Multicast Table
//
// Read what we want to preserve
Addr[0] = READ32( GMAC_ADDR2 );
Addr[2] = READ32( GMAC_ADDR4 );
// Clear all bits out of the hash table
Addr[0] &= 0xFFFF;
Addr[1] = 0;
Addr[2] &= 0xFFFF0000;
for( i=0; i<pi->MCastCnt; i++ )
{
idx = gmHashIndex( &(pi->bMCast[6*i]) );
// Set the bit
if( idx < 16 )
Addr[0] |= 1 << ( idx + 16 );
else if( idx < 48 )
Addr[1] |= 1 << ( idx - 16 );
else
Addr[2] |= 1 << ( idx - 48 );
}
// Write the table back out
WRITE32( GMAC_ADDR2, Addr[0] );
WRITE32( GMAC_ADDR3, Addr[1] );
WRITE32( GMAC_ADDR4, Addr[2] );
//
// Setup the Rx Filter
//
control = READ32( GMAC_CONTROL ) & 0xFFFF00FF;
switch( pi->Filter )
{
case ETH_PKTFLT_NOTHING:
case ETH_PKTFLT_DIRECT:
break;
case ETH_PKTFLT_BROADCAST:
case ETH_PKTFLT_MULTICAST:
control |= GM_AB;
break;
case ETH_PKTFLT_ALLMULTICAST:
control |= GM_AB | GM_PM;
break;
case ETH_PKTFLT_ALL:
control |= GM_PR;
break;
}
WRITE32( GMAC_CONTROL, control );
}
//--------------------------------------------------------------------
// HwPktTxNext()
//
// Transmit Next Packet on Tx Queue
//--------------------------------------------------------------------
void HwPktTxNext( PDINFO *pi )
{
PBM_Handle hPkt;
// If not idle, ignore this call
if( TxState != STATE_IDLE )
return;
// Make sure we have a packet to send
if( !(hPkt = PBMQ_deq(&pi->PBMQ_tx)) )
{
pi->TxFree = 1;
return;
}
// Mark as "not free"
pi->TxFree = 0;
// Send the packet
gmSendPacket( hPkt );
}
//--------------------------------------------------------------------
// _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 mask,flags,data1,data2;
if( fTimerTick )
{
LED_TOGGLE( USER_LED2 );
if( FlashActiveLED )
{
FlashActiveLED = 0;
LED_TOGGLE( USER_LED3 );
}
}
// Get into kernel mode to be safe
llEnter();
// We can't have our polling interfere with the ISR
// Disable GP and EDMA interrupts
mask = gmDisableIER( HW_IFLAG | HW_IEDMAFLAG );
if( FatalError )
{
FatalCount++;
gmStop();
gmStart();
}
// Ack any pending interrupt
flags = READ32( GMAC_ISR ) & 0xFF00;
if( flags )
{
ICR = HW_IFLAG;
WRITE32( GMAC_ISR, ( 0x00000000 | flags | INTMASK ) );
}
// Check for new Rx packet
while( !FatalError && RxState == STATE_IDLE )
{
data1 = READ32(GMAC_RXRING1) >> 16;
data2 = READ32(GMAC_RXRING2) & 0xFFFF;
if( data1 == data2 )
break;
RxState = STATE_DMA;
gmRxPacket();
}
// Check for Tx Complete
if( TxState==STATE_SEND && !(READ32(GMAC_CONTROL) & (GM_ST0|GM_ST1)) )
{
TxState = STATE_IDLE;
if( PBMQ_count(&pi->PBMQ_tx) )
HwPktTxNext( pi );
else
pi->TxFree = 1;
}
gmEnableIER( mask );
// Leave kernel mode
llExit();
}
//--------------------------------------------------------------------
// gmInitialize()
//
// Reset GMAC and clear its external memory
//--------------------------------------------------------------------
static void gmInitialize()
{
int i,j;
unsigned int page;
// EMIF control
*HW_CE_REG = HW_CE_VALUE;
Delay(4);
// Hard Reset
WRITE32( GMAC_RESET_ON, 0 );
Delay(4);
WRITE32( GMAC_RESET_OFF, 0 );
Delay(4);
// Soft Reset
WRITE32( GMAC_CONTROL, GM_RESET );
Delay(3);
WRITE32( GMAC_CONTROL, 0x0 );
// Reset the FIFO
WRITE32( GMAC_AUX2, 0xe800 );
Delay(2);
WRITE32( GMAC_AUX2, 0x2800 );
//
// Clear all internal memory
//
// Set BP = 0x1FF
WRITE32( GMAC_ISR, 0x01FF0000 );
// Set TWP
WRITE32( GMAC_TXRING1, 0x0 );
// Set TRP
WRITE32( GMAC_TXRING2, 0x0 );
j = 0;
page = 0;
for( i=0; i<32768; i++ )
{
WRITE32( GMAC_TWD, 0 );
j += 4;
if( !(j & 0xFF) )
{
page += 0x10000;
page &= 0xfff0000;
WRITE32( GMAC_TXRING1, page );
}
}
}
//--------------------------------------------------------------------
// gmReset()
//
// Reset GMAC, initialize, and prepare to start
//--------------------------------------------------------------------
static void gmReset()
{
// Hard Reset
WRITE32( GMAC_RESET_ON, 0 );
Delay(4);
WRITE32( GMAC_RESET_OFF, 0 );
Delay(4);
// Soft Reset
WRITE32( GMAC_CONTROL, GM_RESET );
Delay(2);
WRITE32( GMAC_CONTROL, 0x0 );
// Reset the FIFO
WRITE32( GMAC_AUX2, 0xe800 );
Delay(2);
WRITE32( GMAC_AUX2, 0x2800 );
// Set auto-recover on Rx DMA
WRITE32( GMAC_AUX3, GM_AUTORCVR );
// Set RRP and RHBP
WRITE32( GMAC_RXRING2, 0x01FF0000 );
// Set RWP
WRITE32( GMAC_RXRING1, 0x00000000 );
// Set TLBP and TWP
WRITE32( GMAC_TXRING1, 0x0 );
// Set TRP
WRITE32( GMAC_TXRING2, 0x0 );
// Enable Autoneg, linktest, 16 bit mode, and TX Fifo count registers
WRITE32( GMAC_CONFIG, GM_LTE|GM_ANE|GM_PBW|GM_TXFIFOCNTEN );
// Clear interrupt mask and set BP
WRITE32( GMAC_ISR, 0x00000000 );
// Reset the FIFO
WRITE32( GMAC_AUX2, 0xe800 );
Delay(2);
WRITE32( GMAC_AUX2, 0x2800 );
// Enable interrupts (and set BP)
WRITE32( GMAC_ISR, 0x00000000|INTMASK );
// Tansmitter is not free until we start
pGMI->TxFree = 0;
// Reset any pending error
FatalError = 0;
}
//--------------------------------------------------------------------
// gmStart()
//
// Start GMAC Rx and Tx state machines
//--------------------------------------------------------------------
static void gmStart()
{
UINT32 control;
// Initialize states
TxState = STATE_IDLE;
RxState = STATE_IDLE;
pGMI->TxFree = 1;
// Setup Rx Filter Mode
HwPktSetRx( pGMI );
// Start receive
control = READ32( GMAC_CONTROL ) & 0x0000FF00;
control |= GM_SR;
// Turn on local loopback if hEther is NULL
if( !pGMI->hEther )
control |= GM_LB0;
WRITE32( GMAC_CONTROL, control );
}
//--------------------------------------------------------------------
// gmStop()
//
// Stop GMAC, abort current Rx and Tx
//--------------------------------------------------------------------
static void gmStop()
{
uint mask;
// Disable GP and EDMA interrupts
mask = gmDisableIER( HW_IFLAG | HW_IEDMAFLAG );
// Stop anyone from entering HwPktTxNext()
pGMI->TxFree = 0;
// Disable new events from RX operation
EDMA_disableChannel(hEDMA_rxControl);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -