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

📄 rtl8019.c

📁 This module contains the code needed to test the RealTek Ethernet Controller.
💻 C
字号:
//***********************************************************************
//**
//**  Project:        Hush
//**  Module:         RTL8019.C
//**
//**  Description:    This module contains the code needed to test
//**                  the RealTek Ethernet Controller
//**
//**  Date            Rev    Eng    Description
//**  --------        ----   ---    ------------
//**  12/28/00               ERS    Chip Specific Functions
//**
//***********************************************************************
//**
//**  (c) Copyright Inari Inc.  All rights reserved.
//**
//***********************************************************************

//======================================================================
//      Include Files
//======================================================================
#ifdef  _IPL0201_
    #include <Reg0201.h>            // special function register declarations
#else   //(_IPL0202_)
    #include <Reg0202.h>            // special function register declarations
#endif  //(_IPL0201_/_IPL0202_)

#include <STDIO.h>
#include "PLX020X.h"            // PLX Library defines & memory
#include "Global.h"             // PC Interface project defines & memory
#include "RTL8019.h"            // RealTek 8019AS chip defines

//Memory
xdata volatile chipctrl ChipCtrl         _at_   CONTROL_BASE;        // GLOBAL Chip Control Registers
//xdata volatile unsigned char DataPort    _at_   (CONTROL_BASE+0x10);   // GLOBAL DMA Read/Write port
xdata volatile unsigned char ResetPort   _at_   (CONTROL_BASE+0x18);   // GLOBAL ChipReset Port

//*********************************
//* Global Variables
//*********************************
static unsigned char bWait;                    
bit NICTxInProgress;                    // transmit currently operating?
bit bEthOverflow = 0;
data unsigned char NextRxPage;      // Hold the RxPage untilthe next DMARead operation

//define Macro
#define INSERT_WAIT_STATE() \
    bWait = CKCON;\
    CKCON |= 0x02;   //Add 2 wait state to Movx Commands
#define REMOVE_WAIT_STATE() CKCON = bWait; 
#define MIN_ETH_SIZE    60  //PAD packets smaller than this #

#define XBYTEDUMP ((unsigned char volatile xdata*) 0)

#if (HARDWARE == HDKREV12)
    #if (JAM_BOTH == ON)
        #define INIT_HOLDOFF        (DDR2=DDR2|0x03)
        #define START_HOLDOFF       (P2=(P2&0xFC))
        #define STOP_HOLDOFF        (P2=(P2|0x03))
    #else   //(JAM_BOTH == OFF)
        #define INIT_HOLDOFF        (DDR2=DDR2|0x02)
        #define START_HOLDOFF       (P2=(P2&0xFD))
        #define STOP_HOLDOFF        (P2=(P2|0x02))
    #endif   //(JAM_BOTH == OFF)
#else    //(HARDWARE == HDKREV20)
    #define INIT_HOLDOFF        (DDR2=DDR2|0x01)
    #define START_HOLDOFF       (P2=(P2&0xFE))
    #define STOP_HOLDOFF        (P2=(P2|0x01))
#endif //(HARDWARE == HDKREV12/HDKREV20)

//bit bStartHoldOff;
extern void ProgramEprom ();

void delay (unsigned int i)
{
    while(i !=0)
        i --;
}

void EthInit (void)
{
    unsigned char   temp;

    NICTxInProgress = 0;    // Not transmit currently operating

//Use the Totem PeripheralChipSelect0 to Drive the AEN line on the RTL8019
    PCSMIN0L = LSB(CONTROL_BASE);           //Select IO Space
    PCSMIN0H = MSB(CONTROL_BASE);           // from 0x0300

    PCSMAX0L = LSB((CONTROL_BASE+0x1F));    // to   0x031F
    PCSMAX0H = MSB((CONTROL_BASE+0x1F));

//    NICTxPendingLen = 0;    // No transmit currently waiting

    IT0 = 1;        // External0 on Falling Edge
//    IT0 = 0;        // External0 on LowLevel
    IE0 = 0;        // clear External0 ISR Flag
    EX0 = 0;        // Disable While Configuring External0 Interrupt

//    ChipCtrl.page0_wr.cr = USE_PAGE0;                  // move to page 0
//    ChipCtrl.page0_wr.imr = 0x0F;//INTERRUPT_MASK;
//       ChipCtrl.page0_wr.cr = USE_PAGE2;
//    if (0x0F != (ChipCtrl.page2_rd.imr&0x7F))
//        EdtLog ('I');
    INSERT_WAIT_STATE();    //save current CKCON & add wait states for Chip access.

//Reset the Chip & Wait 2ms(min)
    temp =  ResetPort;      // Read the port
    ResetPort = temp;       // write it back again

    //Delay for some time!!!!!!
    delay(0x1000);          //Stall after Reset

//Double check the jumpered values for I/O, IRQ, etc
    ChipCtrl.page0_wr.cr = STOP_CHIP;       // Make sure the chip is stopped
    ChipCtrl.page0_wr.cr = USE_PAGE3;       // move to page 3

//This should have been done by jumpers upon bootup, but just to make sure... do it again!!!!
//    ChipCtrl.page3_wr.config1 = 0x00 ;      // Enable Interrupts (INT0 =IRQ2/09)

    ChipCtrl.page3_wr.n9346cr = 0xC0;   // Enable writes to configuration
#if (SEND_HEARTBEAT == ON)
    ChipCtrl.page3_wr.config2 = 0x20;   // 10baseT with LinkTest Enabled (Auto-Select), No BootROM
#else   //(SEND_HEARTBEAT == OFF)
    ChipCtrl.page3_wr.config2 = 0x60;   // 10baseT with LinkTest Disabled, No BootROM
#endif  //(SEND_HEARTBEAT == ON/OFF)

    ChipCtrl.page3_wr.config3 = 0x00;   // 
    ChipCtrl.page3_wr.n9346cr = 0x00;   // Back to normal

//Setup Ethernet Device Address (Shouldn't matter because we need to run in Promiscuous mode anyway)
    ChipCtrl.page3_wr.cr = USE_PAGE1;       // move to page 1

    ChipCtrl.page1.par0 = 0xBA ;         // Address = BA DD EA DD 0C 11
    ChipCtrl.page1.par1 = 0xDD ;         // 
    ChipCtrl.page1.par2 = 0xEA ;         // 
    ChipCtrl.page1.par3 = 0xDD ;         // 
    ChipCtrl.page1.par4 = 0x0C ;         // 
    ChipCtrl.page1.par5 = 0x11 ;         // 

    ChipCtrl.page1.mar0 = 0xFF ;         // MultiCast Hash = ffffffffffffffff= all
    ChipCtrl.page1.mar1 = 0xFF ;         //
    ChipCtrl.page1.mar2 = 0xFF ;         //
    ChipCtrl.page1.mar3 = 0xFF ;         //
    ChipCtrl.page1.mar4 = 0xFF ;         //
    ChipCtrl.page1.mar5 = 0xFF ;         //
    ChipCtrl.page1.mar6 = 0xFF ;         //
    ChipCtrl.page1.mar7 = 0xFF ;         //

// One Time Setup
    ChipCtrl.page1.curr = RECEIVE_PAGE_START;       // current Receive buffer to fill (Tail pointer)
    ChipCtrl.page1.cr = USE_PAGE0;                  // move to page 0
    ChipCtrl.page0_wr.bnry = RECEIVE_PAGE_START;    // current Receive buffer full upto (Head pointer)
           
    ChipCtrl.page0_wr.pstart= RECEIVE_PAGE_START;   // Start of receive Buffer Space
    NextRxPage = RECEIVE_PAGE_START;                // This is where we start to read
    ChipCtrl.page0_wr.pstop = RECEIVE_PAGE_STOP;    // End of Circular RxBuffer
    ChipCtrl.page0_wr.tpsr  = TX0_PAGE_START;       // Start of Transmit Buffer Space
    ChipCtrl.page0_wr.dcr = FIFO_THRESHOLD;         // Data Config Register (Fifo Threshold)
    ChipCtrl.page0_wr.tcr = INTERNAL_LOOPBACK;      // Transmit control (Temporarily in Loopback)
//    ChipCtrl.page0_wr.rcr = RECEIVE_ADDRESS;        // Receive Packet types (Direct & Broadcast)
    ChipCtrl.page0_wr.rcr = RECEIVE_ALL;            // Receive Packet types (Direct,Broadcast, Promiscuous)
//    ChipCtrl.page0_wr.rcr = RECEIVE_ANYTHING;            // Receive Packet types (Direct,Broadcast, Promiscuous)

//DMA Setup
    ChipCtrl.page0_wr.rbcr0 = 0x00;                 // Remote DMA Byte Count = 00
    ChipCtrl.page0_wr.rbcr1 = 0x00;                 // Remote DMA Byte Count = 00
    ChipCtrl.page0_wr.tbcr0 = 0x00;                 // Transmit Byte Count = 00
    ChipCtrl.page0_wr.tbcr1 = 0x00;                 // Transmit Byte Count = 00

    //Delay for some time!!!!!!
    delay(0xFF00);          //Wait around after Reset

    ChipCtrl.page0_wr.cr = USE_PAGE0;               // move to page 0
    ChipCtrl.page0_wr.isr = 0xFF;                   // Clear any pending ISR Flags that we may have produced
    ChipCtrl.page0_wr.imr = INTERRUPT_MASK;         // Enable these Interrupts to fire
    ChipCtrl.page0_wr.tcr = NORMAL_TRANSMIT;        // Transmit control ready!

    ChipCtrl.page1.cr = PAGE0_START;                // move to page 0 and start Chip!!!

    REMOVE_WAIT_STATE();    //Restore Saved CKCON 

#if (USE_HOLDOFF == ON)     // ON = Use Force Collision Circuit
    INIT_HOLDOFF;
    STOP_HOLDOFF;
#endif  //(USE_HOLDOFF == ON)
    EX0 = 1;        // Enable External0 Interrupt

}

//bit EthSelfTest (void)
//{
//    /* Check the chips functionality... */
//    
//    return TRUE;
//}

/*
void RingOverflow(void);

void RingOverflow(void)
{
    int nInc = 0;

    bEthOverflow = 1;

#if (WAIT_STATE_BOUNCE == ON)
    CKCON &= 0xFB;          //No Wait States for Chip Writes
#endif

//Double check the jumpered values for I/O, IRQ, etc
    ChipCtrl.page0_wr.cr = STOP_CHIP;           // Put Chip in STOP mode

//reset DMA info
    ChipCtrl.page0_wr.rbcr0 = 0x00;                 // Remote DMA Byte Count = 00
    ChipCtrl.page0_wr.rbcr1 = 0x00;                 // Remote DMA Byte Count = 00

    //Do nothing, just wait!!
    #define BREAK_AMOUNT_FOR_THE_REALLY_CRAPPY_TIMEOUT_WE_IMPLEMENTED 0x0A0
    //the 60 was determined to be around 2.6ms (must be an int for the 16 bit math)
    while (BREAK_AMOUNT_FOR_THE_REALLY_CRAPPY_TIMEOUT_WE_IMPLEMENTED != nInc++)
    {
    }

    ChipCtrl.page0_wr.tcr = INTERNAL_LOOPBACK;  // Transmit control in Internal Loopback mode
    ChipCtrl.page0_wr.cr = STOP_CHIP;           // Put Chip in STOP mode

    ChipCtrl.page0_wr.isr = OVW;                // Clear the Overflow Flag (by writing a 1 to it)
    ChipCtrl.page0_wr.tcr = NORMAL_TRANSMIT;    // Transmit control in Internal Loopback mode

//Clear out the Transmit Status, We caused the Chip to Reset, no more transmits pending!!!!
// if we were nice we would try and recover the prepared packet
    NICTxInProgress = 0;                // Clear the bit that says were busy

#if (WAIT_STATE_BOUNCE == ON)
    CKCON |= 0x02;   //Add 2 wait states to Movx Commands for Chip Reads
#endif

}
*/

//****************************************************************
//**
//**    Subroutine:     RTL_ISR
//**
//**    Description:    The function called when the RTL0819AS chip
//**                    creates an interrupt
//**
//**            On Entry:
//**            ============================
//**
//**            On Exit:
//**            ============================
//**                ISR Flag(s) = Cleared manually
//**
//****************************************************************
/*
void RTL_ISR(void)
{
    unsigned char ISR_Value;

//New version
INSERT_WAIT_STATE();
ISR_Value = ChipCtrl.page0_rd.isr;
REMOVE_WAIT_STATE();
if (ISR_Value & (PTX|TXE))
{
    NICTxInProgress = 0;
    START_HOLDOFF;
}
if(ISR_Value & OVW)                    // if receive overflow
{
    START_HOLDOFF;
    RingOverflow();
}
ChipCtrl.page0_wr.isr = ISR_Value;
return;


    INSERT_WAIT_STATE();//Save current CKCON value then force it to 2 wait states
    ISR_Value = ChipCtrl.page0_rd.isr;
#if (WAIT_STATE_BOUNCE == ON)
    CKCON &= 0xFB;          //No Wait States for Chip Writes
#endif
    while (((~RST & ~CNT)  & ISR_Value) != 0)
    {
        if (ISR_Value & PTX)                // if Transmit Packet interrupt
        {
            ChipCtrl.page0_wr.isr = PTX;    // Write TxBit to clear Interrupt
            NICTxInProgress = 0;
            START_HOLDOFF;
        }
        if (ISR_Value & TXE)                // if Transmit Error interrupt
        {
            ChipCtrl.page0_wr.isr = TXE;    // Write TxErrorBit to clear Interrupt
            NICTxInProgress = 0;
            START_HOLDOFF;
        }
        if(ISR_Value & PRX)                    // if receive complete interrupt
        {
            ChipCtrl.page0_wr.isr = PRX;    // Write RxPacket Bit to clear Interrupt
        }
        if (ISR_Value & RXE)                // if ReceivePacket with Errors
        {
            ChipCtrl.page0_wr.isr = RXE;    // Write ReceivePacket w/Errors Bit to clear Interrupt
        }
        if (ISR_Value & RDC)                // if RemoteDMA complete
        {
            ChipCtrl.page0_wr.isr = RDC;    // Write RemoteDMAComplete Bit to clear Interrupt
        }
        if(ISR_Value & OVW)                    // if receive overflow
        {
            //Do the Overflow Special Code path!!!!
            START_HOLDOFF;
            RingOverflow();
        }
        
#if (WAIT_STATE_BOUNCE == ON)
        CKCON |= 0x02;
#endif
        ISR_Value = ChipCtrl.page0_rd.isr;
#if (WAIT_STATE_BOUNCE == ON)
        CKCON &= 0xFB;          //No Wait States for Chip Writes
#endif
    }
    REMOVE_WAIT_STATE();//Restore Saved CKCON 
}
*/

WORD EthSend (EDT_RX_LIST* assm)
{
    BYTE i=0;
    WORD len;

    //DEBUG
    if (!assm)
    {
        EdtLog (ROUTER_ASSM_BAD); /* NOTE:: We shouldn't do this at "SEND" time!!! */
        return 0xFFFF;
    }
    //END DEBUG
//    if (!EthSendSetup(0)) /* Check if we can TX yet... */
//        return 0; /* Try again later... */

    for (len=0; i < (assm->eth.frag[MAX_ETH_FRAGS-1]->frag.plx.seq.num); i++)
        len += assm->eth.frag[i]->frag.plx.len - (sizeof (PLX_HEADER)-1);
    len += assm->eth.frag[MAX_ETH_FRAGS-1]->frag.plx.len - (sizeof (PLX_HEADER)-1);

    if (len > 0x600)
    {
        EdtLog (ROUTER_ASSM_LARGE);
        EdtReset(PLXRESET_CHIP); //Full reset!
    }
    
    if (!EthSendSetup( max (len,MIN_ETH_SIZE) ))
        return 0; /* We don't have a TX buffer avaiable right now.. Try again from the Poll loop. */


#if ((PRINTF_DEBUG == ON) && (LOG_ETH_RX == ON))
    for (i = 18; i < 22; i++)
    {
        printf("%02BX,",(assm->eth.frag[0])->frag.payload[i]);
    }
//        printf("\n");
#endif  //((PRINTF_DEBUG == ON) & (LOG_ETH_RX == ON))



    for (i=0;  i < (assm->eth.frag[MAX_ETH_FRAGS-1]->frag.plx.seq.num); i++)
    {
        EthSendCopy ((assm->eth.frag[i])->frag.plx.len - (sizeof (PLX_HEADER)-1),
                            ((BYTE*)&assm->eth.frag[i]->frag)+sizeof(PLX_HEADER) );
        _PUT_FRAG (assm->eth.frag[i], &pFragBuff);
    }
    EthSendCopy ((assm->eth.frag[MAX_ETH_FRAGS-1])->frag.plx.len - (sizeof (PLX_HEADER)-1),
                    ((BYTE*)&assm->eth.frag[MAX_ETH_FRAGS-1]->frag)+sizeof(PLX_HEADER) );
    _PUT_FRAG (assm->eth.frag[MAX_ETH_FRAGS-1], &pFragBuff);
    _PUT_FRAG ((PLX_FRAG_LIST*)assm, &pFragBuff);

    EthSendFinish( max (len,MIN_ETH_SIZE) );    //Transmit the packet!!

    return 0xFFFF;
}

⌨️ 快捷键说明

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