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

📄 rtl8139.c

📁 三星2410的BSP开发包
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  

Abstract:  
    Plain Vanilla Routines for Realtek RTL8139A.
    This mainly supports initialization and Sending/Receiving Ethernet 
    packets as well as interrupt handler.
    Minimum error handling is provided here...
    
Functions:
    
Notes: 
    Code is meant to be used for ethernet download and debugging only and 
    is expected to run in Kernel Mode...

    
--*/

#include <windows.h>
#include <halether.h>
#include <ceddk.h>
#include <wdm.h>

#define PRINTF(cond, printf_exp)        \
            ((void)((cond)?(EdbgOutputDebugString printf_exp) : 0))

#define NEXT(a, MAX)    \
            (++(a) >= MAX) ? (a = 0) : (0)

#define TO_REAL(Addr)   (Addr & ~0x80000000)
#define TO_VIRT(Addr)   (Addr |  0x80000000)


//
//	Forward decl..
//

void
RTL8139HWSetMCRegs(PUCHAR	pucMulticastRegs, BOOL bAllMulticast);

BOOL
RTL8139MulticastList(PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses);


//
//	Multicast support ..
//

#define		MAX_MULTICAST_LIST		8
UCHAR		g_pucMulticastList[MAX_MULTICAST_LIST][6];
DWORD		g_dwMulticastListInUse;
DWORD		g_dwRCR;           
DWORD		g_dwNdisFilter;


enum RTL8139Register
{
    RTL_IDR0_OFFSET                 = 0x00,
    RTL_IDR1_OFFSET                 = 0x01,
    RTL_IDR2_OFFSET                 = 0x02,
    RTL_IDR3_OFFSET                 = 0x03,
    RTL_IDR4_OFFSET                 = 0x04,
    RTL_IDR5_OFFSET                 = 0x05,
    
    RTL_MAR0_OFFSET                 = 0x08,
    RTL_MAR1_OFFSET                 = 0x09,
    RTL_MAR2_OFFSET                 = 0x0a,
    RTL_MAR3_OFFSET                 = 0x0b,
    RTL_MAR4_OFFSET                 = 0x0c,
    RTL_MAR5_OFFSET                 = 0x0d,
    RTL_MAR6_OFFSET                 = 0x0e,
    RTL_MAR7_OFFSET                 = 0x0f,

    RTL_TSD_BASE_OFFSET             = 0x10,
    RTL_TSAD_BASE_OFFSET            = 0x20,

    RTL_RBSTART_OFFSET              = 0x30,
    RTL_ERBCR_OFFSET                = 0x34,
    RTL_ERSR_OFFSET                 = 0x36,
    RTL_CR_OFFSET                   = 0x37,
    RTL_CAPR_OFFSET                 = 0x38,
    RTL_CBR_OFFSET                  = 0x3a,
    RTL_IMR_OFFSET                  = 0x3c,
    RTL_ISR_OFFSET                  = 0x3e,
    RTL_TCR_OFFSET                  = 0x40,
    RTL_RCR_OFFSET                  = 0x44,
    RTL_TCTR_OFFSET                 = 0x48,
    RTL_MPC_OFFSET                  = 0x4c,
    RTL_9346CR_OFFSET               = 0x50,
    RTL_CONFIG0_OFFSET              = 0x51,
    RTL_CONFIG1_OFFSET              = 0x52,

    RTL_TIMERINT_OFFSET             = 0x54,
    RTL_MSR_OFFSET                  = 0x58,
    RTL_CONFIG3_OFFSET              = 0x59,

    RTL_MULINT_OFFSET               = 0x5c,
    RTL_RERID_OFFSET                = 0x5e,
    RTL_TSAD_OFFSET                 = 0x60,
    RTL_BMCR_OFFSET                 = 0x62,
    RTL_BMSR_OFFSET                 = 0x64,
    RTL_ANAR_OFFSET                 = 0x66,
    RTL_ANLPAR_OFFSET               = 0x68,
    RTL_ANER_OFFSET                 = 0x6a,
    RTL_DIS_OFFSET                  = 0x6c,
    RTL_FCSC_OFFSET                 = 0x6e,
    RTL_NWAYTR_OFFSET               = 0x70,
    RTL_REC_OFFSET                  = 0x72, 
    RTL_CSCR_OFFSET                 = 0x74,

    RTL_PHY1_PARAM_OFFSET           = 0x78,
    RTL_TW_PARAM_OFFSET             = 0x7c,
    RTL_PHY2_PARAM_OFFSET           = 0x80  
};

enum RTL8139CommandRegister
{
    RTL8139_COMMAND_RESET           = 0x10,
    RTL8139_COMMAND_RX_ENABLE       = 0x08,
    RTL8139_COMMAND_TX_ENABLE       = 0x04,
    RTL8139_COMMAND_BUFFER_EMPTY    = 0x01
};

enum RTL8139BMCRRegister
{
    RTL_8139_PHY_REGISTERS_RESET    = 0x8000,
    RTL_100MBPS                     = 0x2000,
    RTL_AUTO_NEGOTIATE_ENABLE       = 0x1000,
    RTl_RESTART_AUTO                = 0x0200,
    RTL_FULL_DUPLEX                 = 0x0100
};



#define TX_DMA_BURST_SIZE       (0x007 << 8 )   //  2048 bytes. in TCR.
#define TX_CLEAR_ABORT          (0x01)          //  Clear abort in TCR.

#define NUM_TX_DESC             4
#define ONE_BUFFER_SIZE         1536


#define RX_DMA_BURST_SIZE       (0 << 8)
#define RX_ACCEPT_RUNT          (1 << 4)
#define RX_BROADCAST            (1 << 3)
#define RX_MULTICAST            (1 << 2)
#define RX_UNICAST              (1 << 1)
#define RX_PROMISCUOUS          (1 << 0)


////////////////////////////////////////////////////////////////////////////////
//  The packet header in RX buffer.
//
typedef struct 
{
    union
    {
        struct 
        {
            USHORT  ROK : 1;    //  Receive OK.
            USHORT  FAE : 1;    //  Frame Alignment Error.
            USHORT  CRC : 1;    //  CRC Error.  
            USHORT  LONG: 1;    //  Long packet.
            USHORT  RUNT: 1;    //  Runt packet.
            USHORT  ISE : 1;    //  Invalid Symbol Err.
            USHORT  resv: 7;        
            USHORT  BAR : 1;    //  Broadcast packet.
            USHORT  PAM : 1;    //  Mathcing unicast address.
            USHORT  MAR : 1;    //  Multicast address.
        };

        USHORT  usPacketHeader; 
    };
    
    USHORT  usPacketLength;

}   PACKET_HEADER, *PPACKET_HEADER;


typedef struct RTL8139
{
    DWORD       dwBaseIO;
    DWORD       dwMemOffset;
    USHORT      usMacAddr[3];
    
    UCHAR       *pucTxBuffer;               //  Start of the TX buffers.
    DWORD       dwCurrentTxDescriptor;      //  TX desc for next send.
    DWORD       dwCurrentHwTxDescriptor;    //  TX desc to get back from hw.
    DWORD       dwFreeTxDescriptors;        //  Curr no of free TX desc.
    
    UCHAR       *pucRxBuffer;               //  Start of the RX buffer.
    UCHAR       *puLastRxAddress;           //  The last byte of RX buffer. 
    DWORD       dwCurrentRxOffset;          //  Next RX packet read from here.

    

}   SRTL8139, *PSRTL8139;


////////////////////////////////////////////////////////////////////////////////
//  Useful constants..
//
#define RTL_IDR0            (PULONG) (sRTL8139.dwBaseIO + RTL_IDR0_OFFSET)
#define RTL_IDR1            (PULONG) (sRTL8139.dwBaseIO + RTL_IDR1_OFFSET)
#define RTL_IDR2            (PULONG) (sRTL8139.dwBaseIO + RTL_IDR2_OFFSET)
#define RTL_IDR3            (PULONG) (sRTL8139.dwBaseIO + RTL_IDR3_OFFSET)
#define RTL_IDR4            (PULONG) (sRTL8139.dwBaseIO + RTL_IDR4_OFFSET)
#define RTL_IDR5            (PULONG) (sRTL8139.dwBaseIO + RTL_IDR5_OFFSET)
#define RTL_MAR0            (PULONG) (sRTL8139.dwBaseIO + RTL_MAR0_OFFSET)
#define RTL_MAR1            (PULONG) (sRTL8139.dwBaseIO + RTL_MAR1_OFFSET)
#define RTL_MAR2            (PULONG) (sRTL8139.dwBaseIO + RTL_MAR2_OFFSET)
#define RTL_MAR3            (PULONG) (sRTL8139.dwBaseIO + RTL_MAR3_OFFSET)
#define RTL_MAR4            (PULONG) (sRTL8139.dwBaseIO + RTL_MAR4_OFFSET)
#define RTL_MAR5            (PULONG) (sRTL8139.dwBaseIO + RTL_MAR5_OFFSET)
#define RTL_MAR6            (PULONG) (sRTL8139.dwBaseIO + RTL_MAR6_OFFSET)
#define RTL_MAR7            (PULONG) (sRTL8139.dwBaseIO + RTL_MAR7_OFFSET)
#define RTL_RBSTART         (PULONG) (sRTL8139.dwBaseIO + RTL_RBSTART_OFFSET)
#define RTL_ERBCR           (PUSHORT)(sRTL8139.dwBaseIO + RTL_ERBCR_OFFSET)
#define RTL_ERSR            (PUCHAR) (sRTL8139.dwBaseIO + RTL_ERSR_OFFSET)
#define RTL_CR              (PUCHAR) (sRTL8139.dwBaseIO + RTL_CR_OFFSET)
#define RTL_CAPR            (PUSHORT)(sRTL8139.dwBaseIO + RTL_CAPR_OFFSET)
#define RTL_CBR             (PUSHORT)(sRTL8139.dwBaseIO + RTL_CBR_OFFSET)
#define RTL_IMR             (PUSHORT)(sRTL8139.dwBaseIO + RTL_IMR_OFFSET)
#define RTL_ISR             (PUSHORT)(sRTL8139.dwBaseIO + RTL_ISR_OFFSET)
#define RTL_TCR             (PULONG) (sRTL8139.dwBaseIO + RTL_TCR_OFFSET)
#define RTL_RCR             (PULONG) (sRTL8139.dwBaseIO + RTL_RCR_OFFSET)
#define RTL_TCTR            (PULONG) (sRTL8139.dwBaseIO + RTL_TCTR_OFFSET)
#define RTL_MPC             (PULONG) (sRTL8139.dwBaseIO + RTL_MPC_OFFSET)
#define RTL_9346CR          (PUCHAR) (sRTL8139.dwBaseIO + RTL_9346CR_OFFSET)
#define RTL_CONFIG0         (PUCHAR) (sRTL8139.dwBaseIO + RTL_CONFIG0_OFFSET)
#define RTL_CONFIG1         (PUCHAR) (sRTL8139.dwBaseIO + RTL_CONFIG1_OFFSET)
#define RTL_TIMERINT        (PULONG) (sRTL8139.dwBaseIO + RTL_TIMERINT_OFFSET)
#define RTL_MSR             (PUCHAR) (sRTL8139.dwBaseIO + RTL_MSR_OFFSET)
#define RTL_CONFIG3         (PUCHAR) (sRTL8139.dwBaseIO + RTL_CONFIG3_OFFSET)
#define RTL_MULINT          (PUSHORT)(sRTL8139.dwBaseIO + RTL_MULINT_OFFSET)
#define RTL_RERID           (PUSHORT)(sRTL8139.dwBaseIO + RTL_RERID_OFFSET)
#define RTL_TSAD            (PUSHORT)(sRTL8139.dwBaseIO + RTL_TSAD_OFFSET)
#define RTL_BMCR            (PUSHORT)(sRTL8139.dwBaseIO + RTL_BMCR_OFFSET)
#define RTL_BMSR            (PUSHORT)(sRTL8139.dwBaseIO + RTL_BMSR_OFFSET)
#define RTL_ANAR            (PUSHORT)(sRTL8139.dwBaseIO + RTL_ANAR_OFFSET)
#define RTL_ANLPAR          (PUSHORT)(sRTL8139.dwBaseIO + RTL_ANLPAR_OFFSET)
#define RTL_ANER            (PUSHORT)(sRTL8139.dwBaseIO + RTL_ANER_OFFSET)
#define RTL_DIS             (PUSHORT)(sRTL8139.dwBaseIO + RTL_DIS_OFFSET)
#define RTL_FCSC            (PUSHORT)(sRTL8139.dwBaseIO + RTL_FCSC_OFFSET)
#define RTL_NWAYTR          (PUSHORT)(sRTL8139.dwBaseIO + RTL_NWAYTR_OFFSET)
#define RTL_REC             (PUSHORT)(sRTL8139.dwBaseIO + RTL_REC_OFFSET)
#define RTL_CSCR            (PUSHORT)(sRTL8139.dwBaseIO + RTL_CSCR_OFFSET)
#define RTL_PHY1_PARM       (PULONG) (sRTL8139.dwBaseIO + RTL_PHY1_PARAM_OFFSET)
#define RTL_TW_PARM         (PULONG) (sRTL8139.dwBaseIO + RTL_TW_PARAM_OFFSET)
#define RTL_PHY2_PARM       (PUCHAR) (sRTL8139.dwBaseIO + RTL_PHY2_PARAM_OFFSET)

#define RTL_TSD_X(x)    (PULONG)(sRTL8139.dwBaseIO + RTL_TSD_BASE_OFFSET  + x * 4)
#define RTL_TSAD_X(x)   (PULONG)(sRTL8139.dwBaseIO + RTL_TSAD_BASE_OFFSET + x * 4)


    
////////////////////////////////////////////////////////////////////////////////
//  Global var..
//

//#define   BUFFER_START_ADDRESS    0x00200000  //  TX/RX DMA Buffer..
                                                //  *** WARNING *** 
                                                //  THIS IS HARDCODED UNTIL EDBG
                                                //  IS CHANGED TO CONTROL THIS..
//#define   RX_BUFFER_LENGTH        (64 * 1024)     
//#define   RX_BUFFER_LENGTH_BIT    (3 << 11)   //  64K + 16 bytes.

                                                //  SO WE NEED AROUND 70k OF 
                                                //  BUFFER.. (64k + 6K for TX)

SRTL8139    sRTL8139;       
DWORD       dwTxStartAddress  = 0x00;
DWORD       dwRxStartAddress  = 0x00;
DWORD       dwRxLength        = 0x00;
DWORD       dwRxLengthBit     = 0x00;   



////////////////////////////////////////////////////////////////////////////////
//  Misc utility functions.
//
void DisplayHex (BYTE data)
{    
    if (data < 0x10)
        PRINTF(1, ("0"));
    PRINTF (1, ("%x ", data));

}    // DisplayHex()


void DumpMemory (PBYTE pSource, DWORD dwLength)
{
    int        i = 0;

    PRINTF (1, ("+---- MEM DUMP (%d bytes)----+\r\n", dwLength));
    PRINTF (1, ("0x%x: ", pSource));
    while (dwLength--)
    {    
        DisplayHex (*pSource++);
        if (++i == 16)
        {
            i = 0;        
            PRINTF (1, ("\r\n0x%x: ", pSource));
        }        
    }
    
    PRINTF (1, ("\r\n\r\n"));

}    // DumpMemory()


void
DumpAll8139Regs()
{
    PRINTF (1, 
        ("+------------------------------------------------------------+\r\n"));

    PRINTF (1, ("IDR[0..5]  = 0x[%x - %x - %x - %x - %x - %x]\r\n",
        (UCHAR) READ_PORT_ULONG(RTL_IDR0),
        (UCHAR) READ_PORT_ULONG(RTL_IDR1),
        (UCHAR) READ_PORT_ULONG(RTL_IDR2),
        (UCHAR) READ_PORT_ULONG(RTL_IDR3),
        (UCHAR) READ_PORT_ULONG(RTL_IDR4),
        (UCHAR) READ_PORT_ULONG(RTL_IDR5)));

    PRINTF (1, ("MAR[0..7]  = 0x[%x - %x - %x - %x - %x - %x - %x - %x]\r\n",
        (UCHAR) READ_PORT_ULONG(RTL_MAR0),
        (UCHAR) READ_PORT_ULONG(RTL_MAR1),
        (UCHAR) READ_PORT_ULONG(RTL_MAR2),
        (UCHAR) READ_PORT_ULONG(RTL_MAR3),
        (UCHAR) READ_PORT_ULONG(RTL_MAR4),
        (UCHAR) READ_PORT_ULONG(RTL_MAR5),
        (UCHAR) READ_PORT_ULONG(RTL_MAR6),
        (UCHAR) READ_PORT_ULONG(RTL_MAR7)));

    PRINTF (1, ("TSD[0..3]  = 0x[%x - %x - %x - %x]\r\n",
        READ_PORT_ULONG(RTL_TSD_X(0)),
        READ_PORT_ULONG(RTL_TSD_X(1)),
        READ_PORT_ULONG(RTL_TSD_X(2)),
        READ_PORT_ULONG(RTL_TSD_X(3))));

    PRINTF (1, ("TSAD[0..3] = 0x[%x - %x - %x - %x]\r\n",
        READ_PORT_ULONG(RTL_TSAD_X(0)),
        READ_PORT_ULONG(RTL_TSAD_X(1)),
        READ_PORT_ULONG(RTL_TSAD_X(2)),
        READ_PORT_ULONG(RTL_TSAD_X(3))));

    PRINTF (1, ("RBSTART [0x%x] \t ERBCR   [0x%x] \t ERSR     [0x%x] \t CR       [0x%x]\r\n",
        READ_PORT_ULONG(RTL_RBSTART),
        READ_PORT_USHORT(RTL_ERBCR),
        READ_PORT_UCHAR(RTL_ERSR),
        READ_PORT_UCHAR(RTL_CR)));  

    PRINTF (1, ("CAPR    [0x%x] \t CBR     [0x%x] \t IMR      [0x%x] \t ISR      [0x%x]\r\n",
        READ_PORT_USHORT(RTL_CAPR),
        READ_PORT_USHORT(RTL_CBR),
        READ_PORT_USHORT(RTL_IMR),
        READ_PORT_USHORT(RTL_ISR)));

    PRINTF (1, ("TCR     [0x%x] \t RCR     [0x%x] \t TCTR     [0x%x] \t MPC      [0x%x]\r\n",
        READ_PORT_ULONG(RTL_TCR),
        READ_PORT_ULONG(RTL_RCR),
        READ_PORT_ULONG(RTL_TCTR),
        READ_PORT_ULONG(RTL_MPC)));

    PRINTF (1, ("9346CR  [0x%x] \t CONFIG0 [0x%x] \t CONFIG1  [0x%x] \t TimerInt [0x%x]\r\n",
        READ_PORT_UCHAR(RTL_9346CR),
        READ_PORT_UCHAR(RTL_CONFIG0),
        READ_PORT_UCHAR(RTL_CONFIG1),
        READ_PORT_ULONG(RTL_TIMERINT)));

    PRINTF (1, ("MSR     [0x%x] \t CONFIG3 [0x%x] \t MULINT   [0x%x] \t RERID    [0x%x]\r\n",
        READ_PORT_UCHAR(RTL_MSR),
        READ_PORT_UCHAR(RTL_CONFIG3),
        READ_PORT_USHORT(RTL_MULINT),
        READ_PORT_USHORT(RTL_RERID)));

    PRINTF (1, ("TSAD    [0x%x] \t BMCR    [0x%x] \t BMSR     [0x%x] \t ANAR     [0x%x]\r\n",
        READ_PORT_USHORT(RTL_TSAD),
        READ_PORT_USHORT(RTL_BMCR),
        READ_PORT_USHORT(RTL_BMSR),
        READ_PORT_USHORT(RTL_ANAR)));

    PRINTF (1, ("ANLPAR  [0x%x] \t ANER    [0x%x] \t DIS      [0x%x] \t FCSC     [0x%x]\r\n",
        READ_PORT_USHORT(RTL_ANLPAR),
        READ_PORT_USHORT(RTL_ANER),
        READ_PORT_USHORT(RTL_DIS),
        READ_PORT_USHORT(RTL_FCSC)));

    PRINTF (1, ("NWAYTR  [0x%x] \t REC     [0x%x] \t CSCR     [0x%x] \t PHY1_PARM[0x%x]\r\n",
        READ_PORT_USHORT(RTL_NWAYTR),
        READ_PORT_USHORT(RTL_REC),
        READ_PORT_USHORT(RTL_CSCR),
        READ_PORT_ULONG(RTL_PHY1_PARM)));

    PRINTF (1, ("TW_PARM [0x%x] \t PHY2PARM[0x%x] \r\n\r\n",
        READ_PORT_ULONG(RTL_TW_PARM),
        READ_PORT_UCHAR(RTL_PHY2_PARM)));

}   // DumpAll8139Regs()



////////////////////////////////////////////////////////////////////////////////
//  RTL8139InitDMABuffer()
//  This function is used to inform this library on where the buffer for
//  Tx/Rx DMA is.
//
BOOL
RTL8139InitDMABuffer(DWORD dwStartAddress, DWORD dwSize)
{
    DWORD   dwRxSize;
    DWORD   dwAlignedStart;

    ////////////////////////////////////////////////////////////////////////////
    //  We need at least:
    //  4 TX buffers (4 * ONE_BUFFER_SIZE) ~ 6k
    //  8K + 16 bytes of RX buffers.
    //  (64K Max) of RX buffer size is welcome!
    //  ** Note ** that ONE_BUFFER_SIZE is 1536 bytes which is in DWORD
    //  boundary!
    //
    #define MIN_DMA_SIZE    ((NUM_TX_DESC * ONE_BUFFER_SIZE) + (8 * 1024 + 16))
    
    dwAlignedStart = (dwStartAddress + 0x03) & 0xfffffffc;  
    dwSize -= (dwAlignedStart - dwStartAddress);

    if (dwSize <= MIN_DMA_SIZE)
    {
        PRINTF (1, ("RTL8139InitDMABuffer():: DMA buffer is too small!!\r\n"));
        PRINTF (1, ("Given:[0x%x] :: Minimun required [0x%x]\r\n",
            dwSize,
            MIN_DMA_SIZE));

        return FALSE;
    }

    PRINTF (1, 
        ("RTL8139InitDMABuffer():: Start[0x%x]-[0x%x] - Size[0x%x]\r\n",
        dwStartAddress,
        dwAlignedStart,
        dwSize));
    
    ////////////////////////////////////////////////////////////////////////////
    //  Okay, so we are in business..
    //  TX is fixed, so see how much RX we have.
    //
    
    dwTxStartAddress = dwAlignedStart;
    dwRxStartAddress = dwAlignedStart + (NUM_TX_DESC * ONE_BUFFER_SIZE);
    dwRxSize = dwSize - NUM_TX_DESC * ONE_BUFFER_SIZE;

    if (dwRxSize > (64 * 1024 + 16))
    {
        dwRxLength      = 64 * 1024;
        dwRxLengthBit   = 3 << 11;

    }
    else
    if (dwRxSize > (32 * 1024 + 16))
    {
        dwRxLength      = 32 * 1024;
        dwRxLengthBit   = 2 << 11;

    }
    else
    if (dwRxSize > (16 * 1024 + 16))
    {
        dwRxLength      = 16 * 1024;
        dwRxLengthBit   = 1 << 11;

    }
    else
    {
        dwRxLength      = 8 * 1024;
        dwRxLengthBit   = 0x00; 
    }

    PRINTF (1, ("Tx[0x%x] - Rx[0x%x] - RxLength[0x%x] - RxLengthBit[0x%x]\r\n",
        dwTxStartAddress,
        dwRxStartAddress,
        dwRxLength,
        dwRxLengthBit));

    return TRUE;


}   //  RTL8139InitDMABuffer()


#define	AUTO_NEGOTIATE	1

////////////////////////////////////////////////////////////////////////////////
//  RTL8139Init()
//
BOOL
RTL8139Init(BYTE *pbBaseAddress, ULONG dwMemOffset, USHORT MacAddr[3])
{
    DWORD   dwScrap;

#ifndef AUTO_NEGOTIATE
    USHORT  usScrap;
#endif

    DWORD   i;

    if (dwTxStartAddress == 0x00)
    {
        ////////////////////////////////////////////////////////////////////////
        //  Caller ** MUST ** call RTL8139InitDMABuffer() first!!
        //
        PRINTF (1, 
            ("RTL8139():: Error!! RTL8139InitDMABuffer() was not called.\r\n"));
        return FALSE;
    }

    PRINTF (1, ("RTL8139Init():: BaseIO[0x%x] : MemOffset[0x%x]\r\n",
        pbBaseAddress,
        dwMemOffset));

    memset (&sRTL8139, 0x00, sizeof(SRTL8139));

    sRTL8139.dwBaseIO            = (DWORD)pbBaseAddress;
    sRTL8139.dwMemOffset         = dwMemOffset;
    sRTL8139.dwFreeTxDescriptors = NUM_TX_DESC;

    ////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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