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

📄 dec21140.c

📁 三星2410的BSP开发包
💻 C
📖 第 1 页 / 共 4 页
字号:
            //  localDEBUGMSG ("DEC21140GetFrame::: Error Frame !!!   1 Buffer Tossed...\r\n");
            localRDES0.dwReg = 0x00 | DESC_OWNED_BY_DEC21140;
            pCurrentRxDesc->RDES0.dwReg = localRDES0.dwReg;         
            
            //  Proceed to next descriptor...
            pCurrentRxDesc = (PRX_DESCRIPTOR_FORMAT) TO_VIRT (pCurrentRxDesc->RDES3);
            continue;
        }


        //  Okay, by now we must have a valid buffer.                   
        //  Copy data pointed to by this buffer to user buffer...           
        
        //  localDEBUGMSG ("DEC21140GetFrame()::: Copying %d bytes\r\n", (UINT16)localRDES0.FrameLength);   

        //  For Ethernet Debug and Bootloader, only ARP packet is accepted...
        //  Hence filter out non-ARP broadcast or Multicast packets...

        /////////////////////////////////////////////////////////////////////////
        //  Note: MULTICAST is ENABLED NOW. WE'LL PASS ALL FRAMES BACK

        pHeader = (PBYTE) TO_VIRT(pCurrentRxDesc->RDES2);
#if 0
        if (localRDES0.MulticastFrame || IsBroadcast(pHeader))
        {
            //  This is multicast or broadcast packet.
            //  Toss away if it is non-ARP (i.e Header[16] != 8  || Header[17] != 6)


            if (!bBootLoaderCall)
            {           
                if (pHeader[12] != 0x08 && pHeader[13] != 0x06)
                {
                    //  The buffer is tossed !!!        
                        //localDEBUGMSG ("DEC21140GetFrame()::: 1 non ARP broadcast/multicast buffer tossed.\r\n");
                        //localDEBUGMSG ("DEC21140GetFrame()::: RDES0 = 0x%x\r\n", localRDES0);                 
                    goto SkipCopy;
                }
            }
        }
#endif

        *pwLength = *pwLength + (UINT16)localRDES0.FrameLength;
        memcpy (pbData, (PBYTE) TO_VIRT(pCurrentRxDesc->RDES2), (UINT16)localRDES0.FrameLength);
        pbData += (UINT16)localRDES0.FrameLength;       


//SkipCopy:
        //  Return descriptor back to 21140...      
        pCurrentRxDesc->RDES0.dwReg = 0x00 | DESC_OWNED_BY_DEC21140;
            
        //  Proceed to next descriptor...
        pCurrentRxDesc = (PRX_DESCRIPTOR_FORMAT) TO_VIRT (pCurrentRxDesc->RDES3);       
    
        //  Check the First and Last descriptor indications and take action accordingly...
        switch ((localRDES0.dwReg & 0x300) >> 8)
        {       
            /////////////////////////////////////////////////////////////////////
            case 0x00:  // Not first and not last...                
                //localDEBUGMSG ("DEC21140GetFrame()::: Middle buffer...\r\n");
                break;

            
            /////////////////////////////////////////////////////////////////////
            case 0x01:  // Last Descriptor...
                if (bMultiBufferDetected)
                {
                    //localDEBUGMSG ("DEC21140GetFrame()::: Last Descriptor found...length = %d\r\n", *pwLength);                                   

                                        // Remove checksum from the length
                                        // returned...
                                        //
                                        if (*pwLength)
                                            *pwLength -= sizeof(ULONG); 
  
                    return(*pwLength);                                                          
                }
                else
                {
                    //  Must be an error, toss the whole buffer..
                    return(0);
                }       
            
            /////////////////////////////////////////////////////////////////////
            case 0x02:  //  First Descriptor... 
                if (!bMultiBufferDetected)
                {
                    //localDEBUGMSG ("DEC21140GetFrame()::: First Descriptor detected...\r\n");
                    bMultiBufferDetected = TRUE;                        
                }
                else
                {
                    //  Another First Descriptor ???
                    //  Must be something wrong !!!
                    //  localDEBUGMSG ("DEC21140GetFrame()::: Multiple First Descriptor...Tossing all...\r\n");
                    return(0);
                }           
                break;
        

            /////////////////////////////////////////////////////////////////////
            case 0x03:  //  One buffer frame...                 
                // localDEBUGMSG ("DEC21140GetFrame()::: One buffer frame (%d bytes)...\r\n", *pwLength);                           

                //  Let's see the destination MAC...
                //  Destination MAC starts from 8th byte.
                
                {
                    static  DWORD   dwTotalFrame = 0;
                    
                    //localDEBUGMSG (" ... Total = %d\r\n", dwTotalFrame++);
                }
                
                               // Remove checksum from the length
                               // returned...
                               //
                               if (*pwLength)
                                   *pwLength -= sizeof(ULONG); 
#if 0
                    if ((*pwLength > 0) && pbOrig[0] && (pbOrig[0] != 0xff))
                    {
                    localDEBUGMSG ("Dest MAC = ");
                    PrintMAC (pbOrig[0]);
                    PrintMAC (pbOrig[1]);
                    PrintMAC (pbOrig[2]);
                    PrintMAC (pbOrig[3]);
                    PrintMAC (pbOrig[4]);
                    PrintMAC (pbOrig[5]);                    
                    localDEBUGMSG ("\r\n");
                    }
#endif                    
                return(*pwLength);

            ///////////////////////////////////////////////////////
            default:
                //  Should NEVER get here..
                //  Just bail out...
                return(0);
        }
    }             

    // Remove checksum from the length
    // returned...
    //
    if (*pwLength)
        *pwLength -= sizeof(ULONG); 
#if 0
    if (*pwLength && (pbOrig[0] != 0xff) && (pbOrig[0])) {
        localDEBUGMSG ("Dest MAC2 = ");
        PrintMAC (pbOrig[0]);
        PrintMAC (pbOrig[1]);
        PrintMAC (pbOrig[2]);
        PrintMAC (pbOrig[3]);
        PrintMAC (pbOrig[4]);
        PrintMAC (pbOrig[5]);                    
        localDEBUGMSG ("\r\n");
        }
#endif
    return(*pwLength);

}   // DEC21140GetFrame()



/////////////////////////////////////////////////////////////////////////////////
//  DEC21140ModeSetByAutoNegotiation() 
//  Set the DEC to the common denominator between what PHY (ICS1890) has negotiated
//  with "link partner" and capability of DEC.
//
void    DEC21140ModeSetByAutoNegotiation()
{
    WORD    wReg4;
    WORD    wReg5;
    WORD    wModes;
    DWORD   WaitCount;
    CSR6_21140  CSR6;
    CSR0_21140  CSR0;

    WaitCount = 100000;
    while ((!(MIIRead(0x01) & 0x20)) && ( 0 != WaitCount-- ))
    {
        //  Wait till Autonegotiation completed...
        //  printf ("Autonegotiation not completed...\r\n");                    
    }

    //  Make sure TX and Rx are stopped.
    CSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
    CSR6.StartTransmit = 0x0;
    CSR6.StartReceive  = 0x0;
    WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);

    //  Default to 10Base-TxHD.
    CSR6.TransmitThresholdMode = 0x01;      //  FIFO threshold to 10Mbps
    CSR6.FullDuplexMode    = 0x00;      //  Set half duplex mode.
    CSR6.StoreAndForward       = 0x01;      //  Store/Forward...        
    WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);
    wModes = 0;

    //  If autonegotiation was successful, get the communications
    //  that are supported by the local host and the remote host.
    if ( 0 != WaitCount )
    {
        wReg4 = MIIRead(0x04);
        wReg5 = MIIRead(0x05);

        //  Determine the common modes of operation.
        wModes = wReg4 & wReg5;
    }

    //  I know that ICS1890 does not support 100Base-T4
    //  Hence we start check for
    //  100Base-TxFD
    //  100Base-TxHD 
    //  10Base-TxFD
    //  10Base-TxHD

    //  Enable 100Base-Tx if supported by both sides.
    if (( wModes & 100 ) || ( wModes & 0x80 ))
    {
        CSR0.dwReg = READ_PORT_ULONG(CSR0_REG);
        CSR0.ProgrammableBurstLength    = 32;
        WRITE_PORT_ULONG(CSR0_REG, CSR0.dwReg);

        CSR6.dwReg = READ_PORT_ULONG(CSR6_REG); 
        CSR6.TransmitThresholdMode      = 0x00;     //  FIFO threshold to 100Mbps
        WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);

        //  Set bit 0 if full duplex is enabled.
        wModes >>= 2;
    }
    wModes >>= 6;

    //  Enable full duplex if supported by both sides.
    if ( wModes & 1 )
    {
        CSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
        CSR6.FullDuplexMode             = 0x01;     //  Set Full duplex mode.
        WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);
    }
}


////////////////////////////////////////////////////////////////////////////////
//
// DEC21140SetupPerfectFilter (BYTE *pbPermittedAddress)
// This function creates a setup frame to be used to filter all incoming 
// frames.  A perfect filter filters out everything except its own IP address 
// and broadcast address.
//
BOOL DEC21140SetupPerfectFilter (PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
    // Here are the steps taken...  
    // 1.  Prepare a zero-length buffer descriptor from current tx descriptor.
    // 2.  Setup the perfect filter frame with exactly 192 bytes data length.
    // 3.  First Segment = Last Segment = 0.
    // 4.  Finally, set TDES0[31] = 1 ... Adapter owned descriptor.
    //
    //     Zero length descriptor needs:
    //     TDES1[30] = 0 ... Last Segment Bit 0
    //     TDES1[29] = 0 ... First Segment Bit 0
    //     TDES1[21..11] = ... Transmit buffer 2 = 0
    //     TDES1[10..0]  = ... Transmit buffer 1 = 0
    //
    // 5.  Trigger transmitter, wait for packet 'eaten' by DEC.
    // 6.  Reset descriptor to become normal descriptor.


    PTX_DESCRIPTOR_FORMAT       pSetupDescriptor = NULL;
    PTX_DESCRIPTOR_FORMAT       pZeroLengthDescriptor = NULL;
    TX_TDES1                    ZeroLengthDescriptorOriginTDES1;
    TX_TDES1                    SetupDescriptorOriginTDES1;
    PBYTE                       pbBuffer = NULL;
    CSR6_21140                  CSR6;
    CSR0_21140                  CSR0;
    DWORD                       i;

    //
    // for multicast: first two entries reserved for Local MAC address and broadcast address
    //
    if (DEC21140_SETUP_PERFECT_ENTRIES-2 < dwNoOfAddresses) {
        return FALSE;
    }

    if (!pucMulticastAddresses) {
        //
        // Initial Setting -- make sure receiver is off and transmitter is on.
        //
        CSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
        CSR6.StartReceive  = 0;     
        CSR6.StartTransmit = 1;
        WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);

        CSR0.dwReg = READ_PORT_ULONG(CSR0_REG);
        CSR0.OnNow = 0;
        WRITE_PORT_ULONG(CSR0_REG, CSR0.dwReg);
    }

    // Setup zero length buffer descriptor.
    //
    pZeroLengthDescriptor  = pCurrentTxDesc;            
    pCurrentTxDesc     = (PTX_DESCRIPTOR_FORMAT) TO_VIRT(pCurrentTxDesc->TDES3);
    pSetupDescriptor       = pCurrentTxDesc;
    pCurrentTxDesc     = (PTX_DESCRIPTOR_FORMAT) TO_VIRT(pCurrentTxDesc->TDES3);

    ZeroLengthDescriptorOriginTDES1.dwReg = pZeroLengthDescriptor->TDES1.dwReg; 
    pZeroLengthDescriptor->TDES1.dwReg    = 0x09000000; 
    pZeroLengthDescriptor->TDES0.OwnBit   = 1;  

    
    CSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
    CSR6.StartTransmit = 1;
    WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);
    WRITE_PORT_ULONG(CSR1_REG, 0xffffffff); // Trigger transmitter...

    localDEBUGMSG ("Waiting for Zero Length Descriptor...\r\n");    
    while ((pZeroLengthDescriptor->TDES0.OwnBit) == 1)      
    {
        WRITE_PORT_ULONG(CSR1_REG, 0xffffffff);         
    }
      
    // Restore the original TDES1 descriptor.
    //
    pZeroLengthDescriptor->TDES1 = ZeroLengthDescriptorOriginTDES1; 


    // Now, setup the perfect filter packet...
    //
    
    // Store original TDES1 value to restore later.     
    //
    SetupDescriptorOriginTDES1.dwReg = pSetupDescriptor->TDES1.dwReg;

    //Store this into descriptor and it is ready to go...
    //
    pSetupDescriptor->TDES1.dwReg = (0x69000000 | 192);

    pbBuffer = (PVOID)TO_VIRT(pSetupDescriptor->TDES2);
    memset (pbBuffer, 0xff, 500);       
    pbBuffer[0] = pbEthernetAddr[0];
    pbBuffer[1] = pbEthernetAddr[1];
    pbBuffer[4] = pbEthernetAddr[2];        
    pbBuffer[5] = pbEthernetAddr[3];
    pbBuffer[8] = pbEthernetAddr[4];
    pbBuffer[9] = pbEthernetAddr[5];        

    //
    // setup the rest of the addresses
    //
    for (i = 0; i < dwNoOfAddresses; i ++) {
        pbBuffer[(i+2)*12]   = pucMulticastAddresses[i*6];
        pbBuffer[(i+2)*12+1] = pucMulticastAddresses[i*6+1];
        pbBuffer[(i+2)*12+4] = pucMulticastAddresses[i*6+2];
        pbBuffer[(i+2)*12+5] = pucMulticastAddresses[i*6+3];
        pbBuffer[(i+2)*12+8] = pucMulticastAddresses[i*6+4];
        pbBuffer[(i+2)*12+9] = pucMulticastAddresses[i*6+5];
    }
    
    // We are ready to go...
    //
    pSetupDescriptor->TDES0.OwnBit = 1; 
    WRITE_PORT_ULONG(CSR1_REG, 0xffffffff); 

    // Now we just wait till it gobbles up the packets...
    //
    localDEBUGMSG ("Waiting for DEC21140 to perform perfect filtering...\r\n");

    while ((pSetupDescriptor->TDES0.OwnBit) == 1)       
        WRITE_PORT_ULONG(CSR1_REG, 0xffffffff);         
    
    
    // Finally, restore the original TDES1 for the setupdescriptor so that 
    // next packet won't be treated as setup packet.
    //
    pSetupDescriptor->TDES1.dwReg = SetupDescriptorOriginTDES1.dwReg;

    if (!pucMulticastAddresses) {
        //
        // Initial setup: turn off promiscuous mode
        //
        CSR6.dwReg = READ_PORT_ULONG(CSR6_REG);
        CSR6.PromiscuousMode  = 0;              
        CSR6.ReceiveAll = 0;
        WRITE_PORT_ULONG(CSR6_REG, CSR6.dwReg);
    }
    return(TRUE);
}


/////////////////////////////////////////////////////////////////////////////////
//  DEC21140SendFrame - This routine should be called with a pointer to the 
//                      ethernet frame data.  It is the caller's responsibility 
//                      to fill in all information including the destination and 
//                      source addresses and the frame type.  
//                      The length parameter gives the number of bytes in 
//                      the ethernet frame.
//                      The routine will return immediately regardless of 
//                      whether transmission has successfully been performed by 
//                      21140.
//  Error return:   Non zero.
//  No error:       Returns zero.
//

UINT16 DEC21140SendFrame( BYTE *pbData, DWORD dwLength )
{   
    DWORD                   i = 0;
    DWORD                   dwTotalSent = 0;
    DWORD                   dwNumberOfDescriptorUsed = 0;
    DWORD                   dwToSend;
    CSR6_21140              CSR6;

    volatile PTX_DESCRIPTOR_FORMAT  pFirstTxDescriptor;
    volatile PTX_DESCRIPTOR_FORMAT  pRememberingTheVeryFirstDescriptor;


    pFirstTxDescriptor  = (PTX_DESCRIPTOR_FORMAT) NULL; 

    //printf ("DEC21140SendFrame()::: Sending %d bytes \r\n", dwLength);        

    //  localDEBUGMSG ("DEC21140SendFrame()::: Sending : %d bytes\r\n", dwLength);
    
    //  Need time out...   When all TX process of dec21140 STALL !!!
    while (dwTotalSent < dwLength)
    {   
        if (pCurrentTxDesc->TDES0.dwReg & ~DESC_OWNED_BY_HOST)
        {           
            //  Do something here to make sure the TX process get rid of all these packets...
            //  Then back to top of loop...     
            
            continue;
        }

        if (pCurrentTxDesc == pFirstTxDescriptor)
        {
            //  This should NEVER happen if we have plenty of descriptors...

⌨️ 快捷键说明

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