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

📄 rtl8139.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
//  File:  rtl8139.c
//
#include <windows.h>
#include <ceddk.h>
#include <ethdbg.h>
#include <oal_log.h>
#include <oal_memory.h>
#include <oal_io.h>
#include <oal_timer.h>
#include <nkexport.h>

//------------------------------------------------------------------------------

#define MAC_TX_BUFFER_SIZE          1536
#define MAC_TX_BUFFERS              4

//------------------------------------------------------------------------------

#define RTL_IDR0                    0x00
#define RTL_IDR4                    0x04

#define RTL_MAR0                    0x08
#define RTL_MAR4                    0x0c

#define RTL_TSD0                    0x10
#define RTL_TSAD0                   0x20

#define RTL_RBSTART                 0x30
#define RTL_CR                      0x37
#define RTL_CAPR                    0x38
#define RTL_CBR                     0x3a
#define RTL_IMR                     0x3c
#define RTL_ISR                     0x3e

#define RTL_TCR                     0x40
#define RTL_RCR                     0x44

#define RTL_MSR                     0x58

//------------------------------------------------------------------------------

#define CR_RST                      (1 << 4)
#define CR_RE                       (1 << 3)
#define CR_TE                       (1 << 2)
#define CR_BUFE                     (1 << 0)

//------------------------------------------------------------------------------

#define IR_TER                      (1 << 3)
#define IR_TOK                      (1 << 2)
#define IR_RER                      (1 << 1)
#define IR_ROK                      (1 << 0)

//------------------------------------------------------------------------------

#define RCR_RXFTH16                 (0 << 13)
#define RCR_RBLEN64                 (3 << 11)
#define RCR_RBLEN32                 (2 << 11)
#define RCR_RBLEN16                 (1 << 11)
#define RCR_RBLEN8                  (0 << 11)
#define RCR_MXDMA16                 (0 << 8)
#define RCR_MXDMA1024               (6 << 8)
#define RCR_MXDMA2048               (7 << 8)
#define RCR_AR                      (1 << 4)
#define RCR_AB                      (1 << 3)
#define RCR_AM                      (1 << 2)
#define RCR_APM                     (1 << 1)
#define RCR_AAP                     (1 << 0)

//------------------------------------------------------------------------------

#define RSR_ROK                     (1 << 0)

//------------------------------------------------------------------------------

#define TCR_IFG_STD                 (3 << 24)
#define TCR_MXDMA1024               (6 << 8)
#define TCR_MXDMA2048               (7 << 8)

//------------------------------------------------------------------------------

#define TSR_OWN                     (1 << 13)

//------------------------------------------------------------------------------

#define MSR_LINKB                   (1 << 2)

//------------------------------------------------------------------------------

typedef struct {
    UINT32 address;
    UINT32 txBuffer;
    UINT32 txSize;
    UINT32 txPos;
    UINT32 rxBuffer;
    UINT32 rxSize;
    UINT32 filter;    
    UINT32 hash[2];
} RTL8139;

static RTL8139 g_rtl8139;

//------------------------------------------------------------------------------

static UINT32 ComputeCRC(UINT8 *pBuffer, UINT32 length)
{
    UINT32 crc, carry, i, j;
    UINT8 byte;

    crc = 0xffffffff;

    for (i = 0; i < length; i++) {
        byte = pBuffer[i];
        for (j = 0; j < 8; j++) {
            carry = ((crc & 0x80000000) ? 1 : 0) ^ (byte & 0x01);
            crc <<= 1;
            byte >>= 1;
            if (carry) crc = (crc ^ 0x04c11db6) | carry;
        }
    }
    return crc;

}

//------------------------------------------------------------------------------
//
//  Function:  RTL8139InitDMABuffer
//
//  This function is used to inform this library on where the buffer for
//  Tx/Rx DMA is. Driver needs  at least:
//    4 TX buffers (4 * ONE_BUFFER_SIZE) ~ 6k
//    8K + 16 bytes of RX buffers (64K max)
//    ** Note ** that ONE_BUFFER_SIZE is 1536 bytes which is in UINT32 boundary
//
//
BOOL RTL8139InitDMABuffer(UINT32 address, UINT32 size)
{
    BOOL rc = FALSE;
    UINT32 ph;

    OALMSGS(OAL_ETHER&&OAL_FUNC, (
        L"+RTL8139InitDMABuffer(0x%08x, 0x%08x)\r\n", address, size
    ));

    ph = OALVAtoPA((VOID*)address);
    if ((ph & 0x03) != 0) {
        size -= 4 - (ph & 0x03);
        ph = (ph + 3) & ~0x03;
    }

    g_rtl8139.txBuffer = (UINT32)OALPAtoUA(ph);
    g_rtl8139.txSize = MAC_TX_BUFFERS * MAC_TX_BUFFER_SIZE;
    if (g_rtl8139.txSize > size) {
        OALMSGS(OAL_ERROR, (
            L"ERROR: RTL8139InitDMABuffer: Buffer too small\r\n"
        ));
        goto cleanUp;
    }
    size -= g_rtl8139.txSize;
    ph += g_rtl8139.txSize;

    g_rtl8139.rxBuffer = (UINT32)OALPAtoUA(ph);
    if (size >= (64 * 1024 + 16)) {
        g_rtl8139.rxSize = 64 * 1024;
    } else if (size >= (32 * 1024 + 16)) {
        g_rtl8139.rxSize = 32 * 1024;
    } else if (size >= (16 * 1024 + 16)) {
        g_rtl8139.rxSize = 16 * 1024;
    } else if (size >= (8 * 1024 + 16)) {
        g_rtl8139.rxSize = 8 * 1024;
    } else {
        OALMSGS(OAL_ERROR, (
            L"ERROR: RTL8139InitDMABuffer: Buffer too small\r\n"
        ));
        goto cleanUp;
    }

    rc = TRUE;

cleanUp:
    OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-RTL8139InitDMABuffer(rc = %d)\r\n", rc));
    return rc;
}

//------------------------------------------------------------------------------
//
//  Function:  RTL8139InitDMABuffer
//
BOOL RTL8139Init(UINT8 *pAddress, UINT32 offset, UINT16 mac[3])
{
    BOOL rc = FALSE;
    UINT32 u32, address, i, start;
    

    OALMSGS(OAL_ETHER&&OAL_FUNC, (
        L"+RTL8139Init(0x%08x, 0x%08x, 0x%08x)\r\n", pAddress, offset, mac
    ));

    // Get virtual uncached address
    g_rtl8139.address = (UINT32)pAddress;

    // Reset card
    OUTPORT8((UINT8*)(g_rtl8139.address + RTL_CR), CR_RST);
    while ((INPORT8((UINT8*)(g_rtl8139.address + RTL_CR)) & CR_RST) != 0);

    // Wait for link
    OALMSGS(OAL_WARN, (L"RTL8139: Wait for link..."));
    start = OALGetTickCount();
    while ((INPORT8((UINT8*)(g_rtl8139.address + RTL_MSR)) & MSR_LINKB) != 0) {
        if ((OALGetTickCount() - start) > 5000) {
            OALMSGS(OAL_WARN, (L" Wait timouted, exiting\r\n"));
            goto clean;
        }            
    }        
    OALMSGS(OAL_WARN, (L" Link detected\r\n"));

    // Enable TX/RX
    OUTPORT8((UINT8*)(g_rtl8139.address + RTL_CR), CR_TE | CR_RE);

    // Read MAC address
    u32 = INPORT32((UINT32*)(g_rtl8139.address + RTL_IDR0));
    mac[0] = (UINT16)(u32);
    mac[1] = (UINT16)(u32 >> 16);
    u32 = INPORT32((UINT32*)(g_rtl8139.address + RTL_IDR4));
    mac[2] = (UINT16)(u32);

    // Set TX descriptors
    address = OALVAtoPA((VOID*)g_rtl8139.txBuffer);
    offset = RTL_TSAD0;
    for (i = 0; i < MAC_TX_BUFFERS; i++) {
        OUTPORT32((UINT32*)(g_rtl8139.address + offset), address);
        address += MAC_TX_BUFFER_SIZE;
        offset += 4;
    }
    g_rtl8139.txPos = 0;

    // Set TX DMA burst size per TX DMA burst & standard interframe gap
    OUTPORT32((UINT32*)(g_rtl8139.address + RTL_TCR), TCR_IFG_STD|TCR_MXDMA1024);

    // Clear multicast hash registers
    g_rtl8139.hash[0] = g_rtl8139.hash[1] = 0;

⌨️ 快捷键说明

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