/* * 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); };