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

📄 dec21140.c

📁 三星2410的BSP开发包
💻 C
📖 第 1 页 / 共 4 页
字号:
    

    WRITE_PORT_ULONG(CSR13_REG, 0);        //pull it out of sleep  sudhakar
    WRITE_PORT_ULONG(CSR14_REG, 0xffff);
    WRITE_PORT_ULONG(CSR15_REG, 0x1000);
    WRITE_PORT_ULONG(CSR13_REG, 0xef01);

     Delay (1200);
     
     // CSR0

    
    localCSR0.dwReg = READ_PORT_ULONG(CSR0_REG);
    localCSR0.ProgrammableBurstLength = 0;      //  16 DWORD transfer in one DMA transaction.
    WRITE_PORT_ULONG(CSR0_REG, localCSR0.dwReg);
    localCSR0.CacheAlignment          = 1;      //  8 DWORD boundary alignment. 
    WRITE_PORT_ULONG(CSR0_REG, localCSR0.dwReg);

    //  CSR 3 & CSR4
    WRITE_PORT_ULONG(CSR3_REG, TO_REAL ((DWORD)pRxDesc));
    WRITE_PORT_ULONG(CSR4_REG, TO_REAL ((DWORD)pTxDesc));
    
    
    //  CSR6
    localCSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
    localCSR6.ReceiveAll = 1;                   //  Start off seeing everything...
    localCSR6.PromiscuousMode  = 1;             
    localCSR6.PassAllMulticast = 0;             //  No multicast...
    localCSR6.FullDuplexMode   = 0;             //  Use half duplex.
    localCSR6.dwReg &= CSR6_MUST_AND;
    localCSR6.dwReg |= CSR6_MUST_OR;
    WRITE_PORT_ULONG(CSR6_REG, localCSR6.dwReg);    
    
    DEC21140ModeSetByAutoNegotiation();//change for 5474
    
    DEC21140SetupPerfectFilter (NULL, 0);
     
    //  Turn on Receiver...
    localCSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
    localCSR6.StartReceive = 1;     
    WRITE_PORT_ULONG(CSR6_REG, localCSR6.dwReg);
    return TRUE;
}   // HWInit()



/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
//  Interfaces exported to caller starts here:
//  DEC21140Init()
//  DEC21140InitDMABuffer()
//  DEC21140EnableInts()
//  DEC21140DisableInts()
//  DEC21140ISR()   
//  DEC21140GetPendingInts()
//  DEC21140GetFrame()
//  DEC21140SendFrame()
//
//

/////////////////////////////////////////////////////////////////////////////////
//  DEC21140Detect - Detect whether there is 21140 compatible chip.
//  Input:  
//  -   pbBaseAddress... Caller can pass in either physical or virtual address here.
//                       But have to make sure that it's non cached (if it is virtual).
//
BOOL
DEC21140Detect(BYTE *pbBaseAddress)
{   
    //  Need to do proper detection here...

    g_pIOBase = (PUCHAR)pbBaseAddress;
    
    localDEBUGMSG ("DEC21140Detect()::: returning TRUE\r\n");
    return  TRUE;
}   // DEC21140Detect()



/////////////////////////////////////////////////////////////////////////////////
//  DEC21140Init -  This is called to initialze the ethernet low level driver.  
//                  The base address of the ethernet hardware is passed into 
//                  the routine.  The routine will return TRUE for a successful 
//                  initialization.
//  Initialization:
//  1.  Perform 21140 hardware initialization.
//  2.  Create transmit and receive descriptor lists.
//  3.  Start transmit and receive process on 21140.
//  
BOOL
DEC21140Init( BYTE *pbBaseAddress, ULONG dwMemOffset, USHORT MacAddr[3])
{
    int         n = 0;
    PBYTE       pDst = NULL;
    PBYTE       pSrc = NULL;

   
    localDEBUGMSG ("DEC21140::: Init using i/o address : 0x%x - mem offset = 0x%x\r\n", pbBaseAddress, dwMemOffset);

    dwMEM_OFFSET = dwMemOffset;

    // ** NOTE - the method for determining the MAC address is platform
    // ** dependent in the case of built-in controllers.  For plug-in NICs, we
    // ** generally assume the MAC address can be found in a common location.
    // ** Either way, the following code needs to obtain the MAC address to
    // ** be used with the controller.
 
    if ((PUSHORT)MacAddr != NULL)
    {
        if (!EEPROMReadMAC(&MacAddr[0]))
        {
            localDEBUGMSG("ERROR: Unable to get MAC address for DEC21140.\r\n");
            return(FALSE);
        } 

        // Make a copy of the MAC address...
        pSrc = (PBYTE)MacAddr;
        pDst = pbEthernetAddr;  
        for (n = 6; n ; n--) 
        {
            *pDst++ = *pSrc++;      
        }
        
        localDEBUGMSG ("MAC = %x-%x-%x", pbEthernetAddr[0], pbEthernetAddr[1], pbEthernetAddr[2]);
        localDEBUGMSG ("-%x-%x-%x\r\n",  pbEthernetAddr[3], pbEthernetAddr[4], pbEthernetAddr[5]);
    }
    else
    {
        //localDEBUGMSG("INFO: MAC address to be provided via call to DEC21140SetMACAddress().\r\n");
    }

    
    // HWInit will return false if hardware is not detected.
    g_pIOBase = (PUCHAR)pbBaseAddress;

    if (!HWInit())
    {
        localDEBUGMSG ("DEC21140:::HWInit() failed...\r\n");
        return FALSE;
    }
    
    localDEBUGMSG ("DEC21140Init()::: Done.\r\n");  
    return TRUE;   

}   // DEC21140Init()



////////////////////////////////////////////////////////////////////////////////
//
//  InitTxDescriptor -  
//
//  Caller tells us where the descriptors and buffers should live.  Furthermore,
//  the size of buffer is fixed at MAX_BUFFER_SIZE.  It is caller's 
//  responsibility to allocate enough memory.  Note: Caller can use 
//  DEC21140QueryBufferSize() to find out the size of buffer used for each 
//  buffer and hence calculate the Total Buffer that can be allocated...    
//  DEC21140QueryDescriptorSize() will return size of descriptor...
//
//  Input:  
//  - dwStartAddress = Location where descriptors start.
//  - dwSize         = Size of buffer allocated by caller.
//
//  WARNING: IT IS CALLER RESPONSIBILITY TO GIVE PROPER DATA.
//       NO SANITY CHECK HERE !!!
//       THIS IS ONLY FOR INTERNAL USAGE...
//

void InitTxDescriptor(DWORD dwStartAddress, DWORD dwSize)
{
    
    // Easy... Simply use the provided addresses and size to fit the maximum 
    // number of buffer and descriptors we can...
    // We must have been called from Bootloader or Ethdbg.

    BOOL   bDone = FALSE;
    int    i = 1;   
    DWORD  dwCostOfOneBuffer = sizeof(TX_DESCRIPTOR_FORMAT) + MAX_BUFFER_SIZE;

    // Calculate the max number of descriptor + buffer that I can have for the 
    // given size.
    while (!bDone)
    {
        if ((i * dwCostOfOneBuffer) > dwSize)
        {
            bDone = TRUE;
            i--;
        }
        else
            i++;
    }       

    dwTRANSMIT_DESCRIPTORS_HEAD = dwStartAddress;       
    dwTRANSMIT_BUFFER_START = dwStartAddress + i * sizeof(TX_DESCRIPTOR_FORMAT);
    dwTRANSMIT_RING_SIZE = i;

    localDEBUGMSG ("InitTxDescriptor::: dwTRANSMIT_DESCRIPTORS_HEAD = 0x%x...\r\n", dwTRANSMIT_DESCRIPTORS_HEAD);
    localDEBUGMSG ("InitTxDescriptor::: dwTRANSMIT_BUFFER_START     = 0x%x...\r\n", dwTRANSMIT_BUFFER_START);
    localDEBUGMSG ("InitTxDescriptor::: dwTRANSMIT_RING_SIZE        = 0x%x...\r\n", dwTRANSMIT_RING_SIZE);


} // InitTxDescriptor()



////////////////////////////////////////////////////////////////////////////////
//
//  InitRxDescriptor - See InitTxDescriptor()
//
//

void InitRxDescriptor(DWORD dwStartAddress, DWORD dwSize)
{
    // Easy... Simply use the provided addresses and size to fit the maximum 
    // number of buffer and descriptors we can...
    // We must have been called from Bootloader or Ethdbg.

    BOOL   bDone = FALSE;
    int    i = 1;   
    DWORD  dwCostOfOneBuffer = sizeof(RX_DESCRIPTOR_FORMAT) + MAX_BUFFER_SIZE;

    // Calculate the max number of descriptor + buffer that I can have for the
    // given size.
    while (!bDone)
    {
        if ((i * dwCostOfOneBuffer) > dwSize)
        {
            bDone = TRUE;
            i--;
        }
        else
            i++;
    }

    dwRECEIVE_DESCRIPTORS_HEAD = dwStartAddress;                
    dwRECEIVE_BUFFER_START = dwStartAddress + i * sizeof(RX_DESCRIPTOR_FORMAT);
    dwRECEIVE_RING_SIZE = i;        


    localDEBUGMSG ("InitRxDescriptor::: dwRECEIVE_DESCRIPTORS_HEAD   = 0x%x...\r\n", dwRECEIVE_DESCRIPTORS_HEAD);
    localDEBUGMSG ("InitRxDescriptor::: dwRECEIVE_BUFFER_START       = 0x%x...\r\n", dwRECEIVE_BUFFER_START);
    localDEBUGMSG ("InitRxDescriptor::: dwRECEIVE_RING_SIZE          = 0x%x...\r\n", dwRECEIVE_RING_SIZE);

}  // InitRxDescriptor()
    

BOOL DEC21140InitDMABuffer(DWORD dwStartAddress, DWORD dwSize)
{
    DWORD dwAlignedTxStart = 0;
    DWORD dwAlignedRxStart = 0;
    DWORD dwTxBufferSize   = 0;
    DWORD dwRxBufferSize   = 0;


    // Check for minimum buffer size.
    if (dwSize < MIN_DMA_SIZE)
    {
        localDEBUGMSG("ERROR: DMA buffer is too small.\r\n");
        return(FALSE);
    } 

    // Determine aligned start address for DMA buffer.
    dwAlignedTxStart = (dwStartAddress + 0x03) & 0xFFFFFFFC;
    dwSize          -= (dwAlignedTxStart - dwStartAddress);

    // Roughly split buffer in two and init Tx and Rx regions. 
    dwTxBufferSize   = dwSize / 2;
    dwSize          -= dwTxBufferSize;
    dwStartAddress  += dwTxBufferSize;

    dwAlignedRxStart = (dwStartAddress + 0x03) & 0xFFFFFFFC;
    dwSize          -= (dwAlignedRxStart - dwStartAddress);
    dwRxBufferSize   = dwSize;
    

    InitTxDescriptor(dwAlignedTxStart, dwTxBufferSize);
    InitRxDescriptor(dwAlignedRxStart, dwRxBufferSize);

    return(TRUE);
}


/////////////////////////////////////////////////////////////////////////////////
//  DEC21140EnableInts -    Interrupts left disabled at init, call this function 
//                          to turn them on
//  For Ethernet debug, we only need Receive Interrupt.
//  Hence simply turn on CSR7[6] and CSR7[16]
//      
void
DEC21140EnableInts()
{
    CSR7_21140  localCSR7;
    
    localDEBUGMSG ("DEC21140EnableInts::: Interrupt Enabled...\r\n");
    localCSR7.dwReg = READ_PORT_ULONG(CSR7_REG);    
    localCSR7.ReceiveInterruptEnable    = 1;
    localCSR7.NormalIntrSummaryEnable   = 1;
    WRITE_PORT_ULONG(CSR7_REG, localCSR7.dwReg);    
}   // DEC21140EnableInts()



/////////////////////////////////////////////////////////////////////////////////
//  DEC21140DisableInts -   Disable interrupt.
//  For etherent debug, we only worry about normal interrupt...
//
void
DEC21140DisableInts()
{
    CSR7_21140  CSR7;

    localDEBUGMSG ("+/- DEC21140DisableInts::: Interrupt Enabled...\r\n");
    CSR7.dwReg = READ_PORT_ULONG(CSR7_REG);
    CSR7.NormalIntrSummaryEnable    = 0;
    WRITE_PORT_ULONG(CSR7_REG, CSR7.dwReg);
}   //  DEC21140DisableInts()



/////////////////////////////////////////////////////////////////////////////////
//  DEC21140GetPendingInts -
//                  
//
DWORD
DEC21140GetPendingInts()
{
    CSR5_21140  CSR5;

    //localDEBUGMSG ("+/- DEC21140GetPendingInts::: ...\r\n");
    
    //  The only time we get here is when RX interrupt happens.
    //  Let's check it and see if it is the case...
    CSR5.dwReg = READ_PORT_ULONG(CSR5_REG);
    if (CSR5.ReceiveInterrupt)
    {
        //  Clear the interrupt...
        CSR5.ReceiveInterrupt = 1;
                WRITE_PORT_ULONG(CSR5_REG, CSR5.dwReg);
        return INTR_TYPE_RX;
    }

    //  Probably need to fix other abnormal interrupts here...
    //localDEBUGMSG ("DEC21140GetPendingInts::: Suspicious... how do I get here ???\r\n");

    return(0);
}   // DEC21140GetPendngInts()



/////////////////////////////////////////////////////////////////////////////////
//  DEC21140GetFrame -  This routine is used to find out if a frame has been 
//                      received.  If there are no frames in the RX FIFO, the 
//                      routine will return 0.  
//                      If there was a frame that was received correctly,
//                      it will be stored in pwData, otherwise it will be discarded.  
//
//  Check if the address is broadcast address...
BOOL IsBroadcast(PBYTE pHeader)
{
    int i = 0;
    while (1)
    {
        if (pHeader[i++] != 0xff)
            break;
        if (i == 6)
            return TRUE;        
    }
    
    return FALSE;
}   // IsBroadcast()


void PrintMAC (BYTE bData)
{
    if (bData < 10)
        localDEBUGMSG ("0");
    
    //localDEBUGMSG ("%x", bData);
    localDEBUGMSG ("%x", bData);
}   // PrintMAC



/////////////////////////////////////////////////////////////////////////////////
//  Not until SP1 that the problem in talking to DHCP server that does not reply 
//  discovery packet with ARP broadcast is solved.
//  For altoona, the solution is to differentiate between a kernel call and
//  bootloader call. 
//  We pass all broadcast packets up if it is bootloader.
//  Bootloader has to call this function with bBootLoaderCall == TRUE

UINT16
DEC21140GetFrame(BYTE *pbData, UINT16 *pwLength)
{   
    RX_RDES0    localRDES0;
    BOOL        bMultiBufferDetected = FALSE;   
    PBYTE       pHeader, pbOrig = pbData;
    BOOL        bBootLoaderCall = FALSE;
    CSR5_21140  CSR5;

    //  localDEBUGMSG ("+/- DEC2114GetFrame:::...\r\n");    
    *pwLength = 0;
    
    //  Bail out immediately if the target descriptor is owned by DEC21140
    if (pCurrentRxDesc->RDES0.OwnBit == 1)
        return(0);  

    // KITL doesn't call GetPendingInts to clear the interrupt at the card
    // therefore we need to do it here.
    //
    CSR5.dwReg = READ_PORT_ULONG(CSR5_REG);
    if (CSR5.ReceiveInterrupt)
    {
        //      Clear the interrupt...
        CSR5.ReceiveInterrupt = 1;
        WRITE_PORT_ULONG(CSR5_REG, CSR5.dwReg);
    }

    //  A chance of getting valid packet... 
    //  Need to bail out if we wait too long for a frame completion...

    while (pCurrentRxDesc->RDES0.OwnBit == 0 || bMultiBufferDetected)
    {
        localRDES0 = pCurrentRxDesc->RDES0;     
        //  localDEBUGMSG ("DEC21140GetFrame::: Looking at descriptor: %d... RDES0 = 0x%x\r\n", 
        //      (pCurrentRxDesc - pRxDesc), localRDES0.dwReg);      
        
        //  Discard Error Frame for now...   Donno what to do to them.
        //  Error frame detected if RDES0[15] and RDES0[8] are set.
        //  In this case, we simply clean up the Descriptor and release it back to 21140.       
        if (localRDES0.ErrorSummary && localRDES0.LastDescriptor)
        {

⌨️ 快捷键说明

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