📄 rtl8139.c
字号:
//
// 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 + -