477 lines
14 KiB
Plaintext
477 lines
14 KiB
Plaintext
/*
|
|
* Copyright (c) 2007, 2008, ETH Zurich. All rights reserved.
|
|
*
|
|
* This file is distributed under the terms in the attached LICENSE file.
|
|
* If you do not find this file, copies can be found by writing to:
|
|
* ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
|
|
*/
|
|
|
|
/*
|
|
* rtl8029as.dev
|
|
*
|
|
* DESCRIPTION: RTL8029AS Realtek PCI Full-Duplex Ethernet Controller
|
|
* with built-in SRAM
|
|
*
|
|
* This is derived from the IC specification white paper from RealTek
|
|
* (RTL8029AS Preliminary LS009.0 1997.01.16).
|
|
*/
|
|
|
|
device rtl8029as lsbfirst ( io base ) "RTL8029AS Ethernet Controller"
|
|
{
|
|
/*
|
|
* 5. REGISTER DESCRIPTIONS
|
|
*
|
|
* The registers in RTL8029AS controller can be roughly divided into
|
|
* two groups by their address and functions -- one for NE2000, the
|
|
* other for PCI Configuration Space.
|
|
*/
|
|
|
|
/*
|
|
* 5.1. Group 1: NE2000 Registers
|
|
*
|
|
* This group includes 4 pages of registers which are selected by
|
|
* bit PS0 & PS1 in the CR register. Each page contains 16
|
|
* registers. Besides those registers compatible with NE2000, the
|
|
* RTL8029AS controller defines some registers for software
|
|
* configuration and feature enhancement.
|
|
*/
|
|
|
|
constants rd "Remote read/write" {
|
|
notallowed = 0b000 "Not allowed";
|
|
rrd = 0b001 "Remote read";
|
|
rwr = 0b010 "Remote write";
|
|
sp = 0b011 "Send packet";
|
|
acrdma = 0b100 "Abort/Complete remote DMA";
|
|
};
|
|
|
|
constants ps "Page identification" {
|
|
ne2000p0 = 0b00 "NE2000 compatible page 0";
|
|
ne2000p1 = 0b01 "NE2000 compatible page 1";
|
|
ne2000p2 = 0b10 "NE2000 compatible page 2";
|
|
rtl8029as = 0b11 "RTL8029AS configuration page 3";
|
|
};
|
|
space page0(addr) bytewise "NE2000 compatible page 0";
|
|
space page1(addr) bytewise "NE2000 compatible page 1";
|
|
space page2(addr) bytewise "NE2000 compatible page 2";
|
|
space p2p0(addr) bytewise "Write page 0, read page 2";
|
|
space rtlp(addr) bytewise "RTL8029AS configuration page 3";
|
|
|
|
constants lpconf "Loopback configuration" {
|
|
normal = 0b00 "Normal operation";
|
|
internal = 0b01 "Internal loopback";
|
|
external = 0b10 "External loopback";
|
|
external1 = 0b11 "External loopback";
|
|
};
|
|
|
|
/* Supported interrupts */
|
|
regtype irq "Interrupts" {
|
|
prx 1 "Packet received correctly";
|
|
ptx 1 "Packet transmitted correctly";
|
|
rxe 1 "Packet receive error";
|
|
txe 1 "Packet sent aborted (excessive collisions)";
|
|
ovw 1 "Receive buffer exhausted";
|
|
cnt 1 "MSB of one or more network tally counters is set";
|
|
rdc 1 "Remote DMA operation completed";
|
|
rst 1 "Reset state / Receive buffer overflow";
|
|
};
|
|
|
|
/*
|
|
* This register is used to select register pages, enable or disable
|
|
* remote DMA operation and issue commands.
|
|
*/
|
|
register cr rw io ( base, 0x0 ) "Command" {
|
|
stp 1 "Stop command";
|
|
sta 1 "Start command";
|
|
txp 1 "Transmit packet";
|
|
rd 3 type(rd) "Remote read/write";
|
|
ps 2 type(ps) "Page identification";
|
|
};
|
|
|
|
/*
|
|
* This register reflects the NIC status. The host reads it to
|
|
* determine the cause of an interrupt. Individual bits are cleared
|
|
* by writing a "1" into the corresponding bit. It must be cleared
|
|
* after power up.
|
|
*
|
|
* Type=R/W in Page0.
|
|
*/
|
|
register isr rw page0( 0x7 ) "Interrupt Status" type(irq);
|
|
|
|
/*
|
|
* All bits correspond to the bits in the ISR register. POWER UP=all
|
|
* 0s. Setting individual bits will enable the corresponding
|
|
* interrupts.
|
|
*
|
|
* Type=W in Page0, Type=R in Page2.
|
|
*/
|
|
register imr rw p2p0( 0xf ) "Interrupt Mask" type(irq);
|
|
|
|
/* Type=W in Page0, Type=R in Page2. */
|
|
register dcr rw p2p0( 0xe ) "Data Configuration" {
|
|
wts 1 "Word transfer select";
|
|
bos 1 "Byte order select";
|
|
_ 1 mbz;
|
|
ls 1 "Loopback select";
|
|
arm 1 "Auto-Initialize remote";
|
|
ft 2 "FIFO threshold select";
|
|
_ 1 mb1;
|
|
};
|
|
|
|
/* Type=W in Page0, Type=R in Page2 */
|
|
register tcr rw p2p0 ( 0xd ) "Transmit Configuration" {
|
|
crc 1 "Inhibit CRC generation";
|
|
lb 2 type(lpconf) "Loopback configuration";
|
|
atd 1 "Auto transmit disable";
|
|
ofst 1 "Collision offset enable";
|
|
_ 3 mb1;
|
|
};
|
|
|
|
/*
|
|
* This register indicates the status of a packet transmission.
|
|
*
|
|
* Type=R in Page0.
|
|
*/
|
|
register tsr ro page0( 0x4 ) "Transmit Status" {
|
|
ptx 1 "Transmission completed";
|
|
_ 1 mb1;
|
|
col 1 "Collision";
|
|
abt 1 "Aborted (excessive collisions)";
|
|
crs 1 "Carrier lost";
|
|
_ 1 mbz;
|
|
cdh 1 "CD Heartbeat failed";
|
|
owc 1 "Out of Window collision";
|
|
};
|
|
|
|
/* Type=W in Page0, Type=R in Page2. */
|
|
register rcr rw p2p0( 0xc ) "Receive Configuration" {
|
|
sep 1 "Accept packets with receive errors";
|
|
ar 1 "Accept length < 64 bytes";
|
|
ab 1 "Accept broadcast destination address";
|
|
am 1 "Accept multicast destination address";
|
|
pro 1 "Promiscuous mode";
|
|
mon 1 "Monitor mode";
|
|
_ 2 mb1;
|
|
};
|
|
|
|
/* Type=R in Page0. */
|
|
register rsr ro page0( 0xc ) "Receive Status" {
|
|
prx 1 "Packet received correctly";
|
|
crc 1 "CRC mismatch";
|
|
fae 1 "Frame alignment error";
|
|
_ 1 mbz;
|
|
mpa 1 "Missed packet";
|
|
phy 1 "Physical destination error";
|
|
dis 1 "Receiver disabled";
|
|
dfr 1 "Deferring";
|
|
};
|
|
|
|
/*
|
|
* These two registers can be read to get the current local DMA
|
|
* address.
|
|
*
|
|
* Type=R in Page0.
|
|
*/
|
|
register clda ro page0 ( 0x1 ) "Current Local DMA" type(uint16);
|
|
|
|
/*
|
|
* The Page Start register sets the start page address of the
|
|
* receive buffer ring.
|
|
*
|
|
* Type=W in Page0, Type=R in Page 2.
|
|
*/
|
|
register pstart rw p2p0( 0x1 ) "Page Start" type(uint8);
|
|
|
|
/*
|
|
* PSTOP: Page Stop Register (02H; Type=W in Page0, Type=R in Page2)
|
|
*
|
|
* The Page Stop register sets the stop page address of the receive
|
|
* buffer ring.
|
|
*/
|
|
register pstop rw p2p0( 0x2 ) "Page Stop" type(uint8);
|
|
|
|
/*
|
|
* BNRY: Boundary Register (03H; Type=R/W in Page0)
|
|
*
|
|
* This register is used to prevent overwrite of the receive buffer
|
|
* ring. It is typically used as a pointer indicating the last receive
|
|
* buffer page the host has read.
|
|
*/
|
|
register bnry rw page0( 0x3 ) "Boundary" type(uint8);
|
|
|
|
/*
|
|
* TPSR: Transmit Page Start Register (04H; Type=W in Page0)
|
|
*
|
|
* This register sets the start page address of the packet to the
|
|
* transmitted.
|
|
*/
|
|
register tpsr wo also page0( 0x4 ) "Transmit Page Start" type(uint8);
|
|
|
|
/*
|
|
* TBCR0,1: Transmit Byte Count Registers (05H & 06H; Type=W in
|
|
* Page0)
|
|
*
|
|
* These two registers set the byte counts of the packet to be
|
|
* transmitted.
|
|
*/
|
|
register tbcr wo also page0( 0x5 ) "Transmit Byte Count" type(uint16);
|
|
|
|
/*
|
|
* NCR: Number of Collisions Register (05H; Type=R in Page0)
|
|
*
|
|
* The register records the number of collisions a node experiences
|
|
* during a packet transmission.
|
|
*/
|
|
register ncr ro page0( 0x5 ) "Number of Collisions" type(uint8);
|
|
|
|
/*
|
|
* FIFO: First In First Out Register (06H; Type=R in Page0)
|
|
*
|
|
* This register allows the host to examine the contents of the FIFO
|
|
* after loopback.
|
|
*/
|
|
register fifo ro page0( 0x6 ) "FIFO" type(uint8);
|
|
|
|
/*
|
|
* CRDA0,1: Current Remote DMA Address registers (08H & 09H;
|
|
* Type=R in Page0)
|
|
*
|
|
* These two registers contain the current address of remote
|
|
* DMA.
|
|
*/
|
|
register crda ro page0( 0x8 ) "Current Remote DMA Address" type(uint16);
|
|
|
|
/*
|
|
* RSAR0,1: Remote Start Address Registers (08H & 09H; Type=W in Page0)
|
|
*
|
|
* These two registers set the start address of remote DMA.
|
|
*/
|
|
register rsar wo also page0( 0x8 ) "Remote Start Address" type(uint16);
|
|
|
|
/*
|
|
* RBCR0,1: Remote Byte Count Registers (0AH & 0BH; Type=W in Page0)
|
|
*
|
|
* These two registers set the data byte counts of remote DMA.
|
|
*/
|
|
register rbcr wo also page0( 0xa ) "Remote Byte Count" type(uint16);
|
|
|
|
/*
|
|
* CNTR0: Frame Alignment Error Tally Counter Register (0DH;
|
|
* Type=R in Page0)
|
|
*/
|
|
register cntr0 ro page0( 0xd ) "Frame Alignment Error Tally Counter" type(uint8);
|
|
|
|
/*
|
|
* CNTR1: CRC Error Tally Counter Register (0EH; Type=R in Page0)
|
|
*/
|
|
register cntr1 ro page0( 0xe ) "CRC Error Tally Counter" type(uint8);
|
|
|
|
/*
|
|
* CNTR2: Missed Packet Tally Counter Register (0FH; Type=R in
|
|
* Page0)
|
|
*/
|
|
register cntr2 ro page0( 0xf ) "Missed Packet Tally Counter" type(uint8);
|
|
|
|
/*
|
|
* PAR0-5: Physical Address Registers (01H - 06H; Type=R/W in Page1)
|
|
*
|
|
* These registers contain my Ethernet node address and are used
|
|
* to compare the destination address of incoming packets for
|
|
* acceptation or rejection.
|
|
*/
|
|
regarray par rw page1( 0x1 )[6] "Physical Address" type(uint8);
|
|
|
|
/*
|
|
* CURR: Current Page Register (07H; Type=R/W in Page1)
|
|
*
|
|
* This register points to the page address of the first receive
|
|
* buffer page to be used for a packet reception.
|
|
*/
|
|
register curr rw page1 ( 0x7 ) "Current Page" type(uint8);
|
|
|
|
/*
|
|
* MAR0-7: Multicast Address Register (08H - 0FH; Type=R/W in
|
|
* Page1)
|
|
*
|
|
* These registers provide filtering bits of multicast addresses
|
|
* hashed by the CRC logic.
|
|
*/
|
|
regarray mar rw page1( 0x8 )[8] "Multicast Address" type(uint8);
|
|
|
|
/*
|
|
* 5.1.2.2. RTL8029AS Defined Registers
|
|
*/
|
|
|
|
/*
|
|
* Page 0 (PS1=0, PS0=0)
|
|
*
|
|
* Two registers are defined to contain the RTL8029AS chip ID and
|
|
* Read Sequence Command is NO LONGER supported in RTL8029AS.
|
|
*
|
|
* Address 0x0a reads ASCII "P", address 0x0b reads ASCII "C".
|
|
*/
|
|
regarray rtl8029id ro page0( 0xa )[2] "RTL8029AS Chip ID" type(uint8);
|
|
|
|
/*
|
|
* Page 3 (PS1=1, PS0=1).
|
|
*/
|
|
|
|
constants mode "RTL8029AS operating mode" {
|
|
opnormal = 0b00 "Normal (DP8390 compatible)";
|
|
autoload = 0b01 "Auto-load 9346";
|
|
programming = 0b10 "9346 programming";
|
|
configwrite = 0b11 "Config register write enable";
|
|
};
|
|
|
|
/* 9346CR: 9346 Command Register (01H; Type=R/W except Bit0=R) */
|
|
register cr9346 rw also rtlp( 0x1 ) "9346 Command" {
|
|
eedo 1;
|
|
eedi 1;
|
|
eesk 1;
|
|
eecs 1;
|
|
_ 2;
|
|
eem 2 type(mode) "RTL8029AS operating mode";
|
|
};
|
|
|
|
/* CONFIG0: RTL8029AS Configuration Register 0 (03H; Type=R) */
|
|
register config0 ro rtlp( 0x3 ) "RTL8029AS Configuration 0" {
|
|
_ 2 mbz;
|
|
bnc 1 "10Base2 thin cable connected";
|
|
_ 5;
|
|
};
|
|
|
|
constants bromsize "Boot ROM Size" {
|
|
nobrom = 0b00 "No Boot ROM";
|
|
size8k = 0b01 "8K Boot ROM";
|
|
size16k = 0b10 "16K Boot ROM";
|
|
size32k = 0b11 "32K Boot ROM";
|
|
};
|
|
|
|
constants medium "Network Medium" {
|
|
auto = 0b00 "TP/CX auto-detect";
|
|
tenbaset = 0b01 "10BaseT";
|
|
tenbase5 = 0b10 "10Base5";
|
|
tenbase2 = 0b11 "10Base2";
|
|
};
|
|
|
|
/*
|
|
* CONFIG2: RTL8029AS Configuration Register 2 (05H; Type=R except
|
|
* Bit[7:5]=R/W)
|
|
*/
|
|
register config2 rtlp( 0x5 ) "RTL8029AS Configuration 2" {
|
|
bs 2 ro type(bromsize) "Boot ROM size";
|
|
_ 2;
|
|
pf 1 ro "Pause flag";
|
|
fce 1 rw "Flow control enable";
|
|
pl 2 rw type(medium) "Network medium select";
|
|
};
|
|
|
|
constants leds "LED Control" {
|
|
rxcol = 0b00 "RX and COL";
|
|
rxlink = 0b01 "RX and LINK";
|
|
crscol = 0b10 "CRS and COL";
|
|
crslink = 0b11 "CRS and LINK";
|
|
};
|
|
|
|
/*
|
|
* CONFIG3: RTL8029AS Configuration Register 3 (06H; Type=R except
|
|
* Bit[6,2:1]=R/W)
|
|
*/
|
|
register config3 rw rtlp( 0x6 ) "RTL8029AS Configuration 3" {
|
|
_ 1;
|
|
pwrdn 1 "Power down mode";
|
|
sleep 1 "Sleep mode";
|
|
_ 1 mbz;
|
|
leds 2 type(leds) "LED control";
|
|
fudup 1 "Full-duplex mode";
|
|
_ 1;
|
|
};
|
|
|
|
constants clock "Halt Clock Mode" {
|
|
running = 0x52 "Running"; /* ASCII code of 'R' */
|
|
halted = 0x48 "Halted"; /* ASCII code of 'H' */
|
|
};
|
|
|
|
/*
|
|
* HLTCLK: Halt Clock Register (09H; Type=W)
|
|
*
|
|
* This is the only active one of Group1 registers when RTL8029AS
|
|
* is inactivated. Writing to this register is invalid if
|
|
* RTL8029AS is not in power down mode. (i.e., If PWRDN bit in
|
|
* CONFIG3 register is zero.) The data written to this register
|
|
* determines the RTL8029AS's power down mode.
|
|
*/
|
|
register hltclk wo rtlp( 0x9 ) "Halt Clock" type(uint8);
|
|
|
|
/* 8029ASID0,1: RTL8029AS ID = 8029H (0E,0FH; Type=R) */
|
|
register rtl8029asid ro rtlp( 0xe ) "8029AS ID" type(uint16);
|
|
|
|
/*
|
|
* 6.2.2 ID PROM Contents
|
|
*
|
|
* The RTL8029AS emulates the ID PROM of NE2000 internally. After
|
|
* 9346 is loaded, the contents of ID PROM are as follows.
|
|
*
|
|
* offset Byte contents
|
|
* ------ -------------
|
|
* 00H Ethernet ID0
|
|
* 01H Ethernet ID1
|
|
* 02H Ethernet ID2
|
|
* 03H Ethernet ID3
|
|
* 04H Ethernet ID4
|
|
* 05H Ethernet ID5
|
|
* 06H PID0
|
|
* 07H PID1
|
|
* 08H PID2
|
|
* 09H PID3
|
|
* 0AH PID4
|
|
* 0BH PID5
|
|
* 0CH PID6
|
|
* 0DH PID7
|
|
* 0EH 57 (ASCII Code of "W")
|
|
* 0FH 57 (ASCII Code of "W")
|
|
* 10H Ethernet ID0
|
|
* 11H Ethernet ID1
|
|
* 12H Ethernet ID2
|
|
* 13H Ethernet ID3
|
|
* 14H Ethernet ID4
|
|
* 15H Ethernet ID5
|
|
* 16H PID0
|
|
* 17H PID1
|
|
* 18H PID2
|
|
* 19H PID3
|
|
* 1AH PID4
|
|
* 1BH PID5
|
|
* 1CH PID6
|
|
* 1DH PID7
|
|
* 1EH 42 (ASCII Code of "B")
|
|
* 1FH 42 (ASCII Code of "B")
|
|
*/
|
|
|
|
/*
|
|
* Remote DMA Port (10H - 17H)
|
|
*
|
|
*
|
|
* The ID PROM and Ethernet packet RAM contents can be read using
|
|
* these registers. Set the start address in RSAR and amount of
|
|
* bytes to transfer in RBCR.
|
|
*
|
|
* RAM start is at offset 0x4000.
|
|
*/
|
|
/*
|
|
regarray rdma rw rtlp( 0x10 )[8] "Remote DMA 0" type(uint8);
|
|
*/
|
|
register rdma32 rw rtlp( 0x10 ) "Remote DMA 32-bit" type(uint32);
|
|
register rdma16 rw also rtlp( 0x10 ) "Remote DMA 16-bit" type(uint16);
|
|
register rdma8 rw also rtlp( 0x10 ) "Remote DMA 8-bit" type(uint8);
|
|
|
|
/*
|
|
* Reset Port
|
|
*
|
|
* Ports in the range 0x18 - 0x1f are reset ports. We only index the
|
|
* last one here as the others are not used on QEMU.
|
|
*
|
|
* Reading from the reset port causes the card to be reset.
|
|
*/
|
|
register reset rc rtlp( 0x1f ) "Reset" type(uint8);
|
|
};
|