12. Realtek 8139 Ethernet Controller 12.1.1 Ethernetvarianten 12.1
Transcrição
12. Realtek 8139 Ethernet Controller 12.1.1 Ethernetvarianten 12.1
12. 12.1.1 Realtek 8139 Ethernet Controller Ethernetvarianten • 10 BASE T: 10MBit Manchester Codierung. • 100 BASE T/TX: 100MBit 4B/5B Codierung: - full-duplex mit passendem Switching-Hub, - halb-duplex. 12.1.2 Steckerformat • RJ-45 Stecker - 8 Stifte, davon nur 4 Stifte benutzt, - keine Überkreuzung im Kabel. 1Transmit + 2 Transmit 3 Receive + 6 Receive - 8 1 • Stiftbelegung an Dosen, Hubs und Switches. • Stiftbelegung an der Netzwerkkarte oder Uplink am Hub oder Switch. 1 1 Receive 2 Receive + 3 Transmit + 6 Transmit - 1 8 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.2 Chip-Architektur des 8139 • PCI-Schnittstelle: - Bus Master Übertragung, - DMA Deskriptoren. • Interruptsteuerung: - Senden, empfangen, - Fehlersituationen. PCI • FIFO Steuerung: - Schwellwert-Einstellungen ... • Zusätzliche Features: - Auto-Negotiation Power-Control, LAN Wakeup, Flow Control. FiFo FiFo Control Receive Transmit Interrupt control Boot ROM Interface EPROM Interface LED • Boot ROM zum Starten vom Netz. • LED zur Anzeige des Link-Zustandes. • EEPROM zur Ablage von Konfigurierungsparametern. 2 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.3 Arbeitsweise • Transfer nur über Bus Mastering möglich: RAM - Ältere Boards bieten nicht auf allen Sockeln Bus Mastering, - RTL 8139 arbeitet auf physikalischen Adressen, - CPU arbeitet auf logischen Adressen. • Pufferung geschieht im Hauptspeicher: - 64 KByte Ringpuffer für die empfangenen Pakete, - 4 Deskriptoren für abgehende Pakete im Chip, - Pakete selber im Hauptspeicher. • 4 Transmit-Deskriptoren: - Sendeadresse im Hauptspeicher, - Zustand der Übertragung, - Länge des Paketes. RLT 8139 • Zwei FiFo Puffer à je 2Kbyte auf dem Chip (Senden & Empfangen): - beim Erreichen eines Schwellwertes im Empfangspuffer beginnt DMA Übertragung, - beim Erreichen eines Schwellwertes im Sendepuffer beginnt Übertragung ins Netz. 3 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.4 12.4.1 Registersemantik Transmit-Deskriptoren • Transmit Status Register - TSD0 .. TSD3 (32 Bit, $10): [31] [30] [29] [28] [27..24] [21..16] [15] [14] [13] [12..0] Carrier Sense Lost Transmit Abort Out of Window Collision TSD0 @ $10 CD Heart Beat ; nur bei 10MBit ; Carrier Sense Lost Early Transmit Threshold: - 8, n*32 Bytes, TSAD0 @ $20 TOK, Transmit successful, TUN, Transmit FiFo underrun, OWN, - the CPU currently owns the packet - not the adapter. Größe des zu versendenden Paketes in Bytes 24 Bit Status 12 Bit Länge 32 Bit Startadresse 32 Bit Startadresse 32 Bit Startadresse 32 Bit Startadresse • Transmit Start Adress Register - TSAD0 .. TSAD (32 Bit, $20). 4 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.4.2 Weitere Geräteregister • ca. 60 Register vorhanden, Memory mapped. • CR - Command Register (8 Bit, $37 ): [4] Reset [3] Receiver Enable [2] Transmitter Enable [0] Buffer empty • BMCR - Basic Mode Control Register (16 Bit, $62): [15] Reset [13] Speed_Set 100Mbps [12] Auto Negotation enabled [9] Restart Auto Negotation [8] Enable full-duplex mode 5 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess • TCR - Transmit Configuration Register (32 Bit, $40) - 6 [30..28] Hardware Versionsnummer [27] RTL8139B(L) [25..24] Interframe Gap 9.6us .. 8.4us (100Mbit) oder 960ns .. 840 ns (10Mbit) [18..17] (normal, MAC, PHY, Twister)-Loopback, [16] CRC Prüfsumme am Paketende anfügen [10..8] Max Tx-DMA Burst 16-2048 Bytes [7..4] TxRetryCount: Retries=16 + ( Tx Retry*16 ) [0] Clear Abort Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess • RCR - Receive Configuration Register (32 Bit, $44): [27..24] [16] [15..13] [12..11] [10..8] [7] [6] [5] [4] [3] [2] [1] [0] 7 Early Receive Threshold zum Auslösen des Interrupts (% der Gesamtlänge): 0000 = no early threshold, 0001 = 1/16, 0010 = 2/16 .... 1111 = 15/16 Nur möglich für bekannte Protokolle mit Längenfeld. fehlerhafte Pakete mit Länge > 8 Bytes empfangen Schwellwert für Empfangs-DMA (16 Bytes ... 1024 Bytes, 111 = ganzes Paket) Länge des Empfangspuffers (00 = 8K ; 01 =16K ... 11 = 64K ) Maximale DMA Burst Size per Rx DMA (16 Bytes .. unbegrenzt) sofortiger Wraparound am Ende des Ringpuffers oder erst nach einem Paket Eprom Typ (nicht alle Chipversionen) Fehlerhafte Pakete annehmen Pakete < 64 Bytes annehmen Broadcast Pakete annehmen Multicast Pakete annehmen, Pakete mit übereinstimmender MAC- Adresse annehmen Pakete mit beliebiger MAC Adresse annehmen Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess • Interrupt Status & Interrupt Mask Register (16 Bit, $3e / $3c ): [15] [14] [13] [6] [5] [4] [3] [2] [1] [0] 8 System Error Time Out Cable Length changed Receive Fifo Overflow Link changed Rx Buffer overflow Transmit Error Interrupt Transmit OK Interrupt Receive Error Interrupt Receive OK Interrupt Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess • RBSTART- Receive Buffer Start Address (32 Bit, $30): - Offset an der das nächste zu lesende Paket steht, - maximal 64 Kbyte Puffer möglich. • CAPR - Current Address of Packet Read (16 Bit, $38): - Offset an der das nächste zu lesende Paket steht, - maximal 64 Kbyte Puffer möglich, - aktueller Lesezeiger der Karte. • CBA - Current Buffer Address (16 Bit, $3a): - aktueller Schreibzeiger der Karte, - Wrap-Around am Ende des Puffers. • IDR0..IDR5 - Mac ID Register (48 Bit, $00): - Ethernet-Adresse der Karte, - gegebenfalls selber setzen. • MAR0..MAR7 - Multicast Address (64 Bit, $08): - Bitmap für den Hashcode der Multicast-Adresse, - Detailtest durch die Software. 9 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.5 12.5.1 Registerklasse für RLT 8139 Die Plurix-Klasse PMapper: • gestattet eine Registerstruktur auf den Speicher abzubilden, • Basisklasse für memory-mapped Registerklassen, • kann nicht mit new() alloziert werden, • attr_sys & attr_nobc (No Backchain). PCI-Space • public class Regs8139 extends PMapper => mapAt(0xefffffff) Regs8139 10 RAM-Space Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.5.2 Geräteregister als Java-Klasse Regs8139 • Adressierung im Kontext der Registerklasse. • Kann keine eigentlichen Variablen besitzen. • Gemappt wird in der zugehörigen Device-Instanz. • Mnemonischer und effizienter als Methodenaufrufe. • Immer mit der Synthetisierung eines Zeigers verbunden. • In Sprachen wie C, Pascal, Modula-2 als Struct bzw. Record. • In Plurix als Compiler-Feature implementiert ( ....mapAt() ). package devices; /** Bildet die RLT8139 Register in den PCI-Speicher ab * @author P. Schulthess * @version 0.001 */ public class Regs8139 extends PMapper { int IDR0, IDR4, MAR0, MAR4; // 6 Byte MAC-Address, 2 B Filler, 8 B Multicast Mask 11 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess int TSD0, TSD1, TSD2, TSD3; // Transmit status of descriptors 0..3, $10 ... int TSAD0, TSAD1, TSAD2, TSAD3; // Transmit address of descriptors 0..3, $20 .. int RBSTART; // receive buffer start address, $30 . short ERBCR; // early receive byte count, $34 byte ERSR, CR; // early receive status, command register, $36 short CAPR, CBR; // curr. adr. of pk read, curr. buffer adr. short IMR, ISR; // Int mask, Int status int TCR, RCR; // Transmit/Receive configuration register, int TCTR, MPC; // timer count, missed packets, $40 byte CR9346, CONFIG0, CONFIG1, f1; // 9346 command, configuration1/2,, $50 int TimerInt; // Timer interval until timeout interupt in ISR byte MSR, CONFIG3, f2, f3; // Media status, configuration 3,,, $58 short MULINT, RERID, TSAD; // Multiple Int, PCI Revision, xMit status all short BMCR, BMSR; // Basic mode control/-status, short ANAR, ANLPAR, ANER; // autoneg. advertise/-partner/-expansion, $$66 short DIS, FSC; // disconnect counter, false carrier short NWAYTR, RX_ER, CSCR, f4; // N-wy test, receive errors, cs configuration, $70 long PHY1_P, TW_P, PHY2_P; // Physical parameters, twist p., 3 bytes filler, $78 byte CRC0, CRC4; // Power management and wakeup, $84 long W0, W1, W2, W3; // wakeup frames, $8c long W4, W5, W6, W7; // wakeup frames byte LSB0, LSB4; // Power management and wakeup, $cc final static int 12 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess ErrorPck=0x20, RuntPacket=0x10, BroadCastPck=0x08, MultiCastPck=0x4, PhysMatchPck=0x2, AllPck=0x1; final static int InterframeGapTime=3, RxFifoThreshold=7, MaxTxDmaBurst=6, MaxRxDmaBurst=6, RxBufferSize=3; // which packets// -to receive ? // 9.6us 10MBit, 960ns 100MBit // 0=16Bytes, 1=32Bytes, ..., 7=no rx threshold // 0=16Bytes, 1=32Bytes, .. 7=2048bytes // 0=16Bytes, 1=32Bytes, .. 7=unlimited // 0=8K, 1=16K, 2=32K, 3=64K public void initRegisters( byte[] rxBuffer) { CR=Reset; while (CR > 0); // reset pending CR9346=0xC0; // enable Config_Register_Write ANAR=0x3E1; // all modes advertised, CSMA#1 BMCR=ANE; // auto negotiation enable IMR=0; // disable all NIC interrupts RCR=(RxBufferSize<<11)|(RxFifoThreshold<<13)|(MaxRxDmaBurst<<8); TCR=(MaxTxDmaBurst<<8)|(InterframeGapTime<<24); // command registers CR9346=0x00; // disable Config_Register_Write RBSTART=Magic.Cast(int, rxBuffer); // Startaddress of receive buffer } } 13 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.6 12.6.1 Realtek 8139 Treiber als Java Instanz Header und Konstanten: package devices; import kernel.*; import kernel.memory.*; import devices.bus.pci.*; /** Driver instance for Realtek 8139 network adapter * @author O. Marquardt, M. Schöttner, P. Schulthess * @version 0.5 */ public attr_sys attr_nonbc class Realtek8139 extends NetworkAdapter{ final static int // Bitpositions - sorry for the mess Reset=0x10, rEnable=0x0008, tEnable=0x4, BufferEmpty=0x0001, // init ANE=0x1000, MBPS100=0x2000, MBPS10 =0x0, FullDuplex =0x0100, // network mode Tx_OWN=0x2000, Tx_TOK=0x8000, Tx_Threshold=0, clearAbort=0x1, // sending state SyERR=0x8000, TmOut=0x4000, LCh=0x2000, FOVW=0x40, PUN=0x0020, // int types RXOVW=0x0010, TER =0x0008, TOK=0x0004, RER =0x02, ROK=0x0001, xMulticast=0x8000, RxPhyscl=0x4000, RxBrodcst=0x2000, RxBadSymbl=0x0020, RxRuntPk=0x0010, RxTooLong=0x0008, RxCRCErr =0x0004, RxBdAlgn=0x0002, RxStatsOK=0x0001; 14 // receive results Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.6.2 Variablen, Standardmethoden und PCI-Initialisierung: • Jeder Plurix Treiber muss einige abstrakte Methoden implementieren: - DetectDevice() prüft, ob das gerät auch tatsächlich vorhanden ist. Initialize() zum Aufbauen der persistenten Datenstrukturen, Reinitialize() wird beim Warmstart oder Fallback gerufen, Start() aktiviert das Gerät zum Senden/empfangen, Stop() fährt das Gerät sicher herunter. • Dazu kommen gerätespezifische Methoden (real soon now ...): - Lesen, Schreiben, Parameter setzen, Signalisieren, Mechanik, - USB-Device, ATAPI-Device, SCSI ... Regs8139 int[] byte[] int r; tDescPool= new int[1000]; rxBuff = new byte[80000]; rxRead; // mapped registers // pool for TxDescriptors // must lock to be safe // read pointer public boolean detectDevice(){ deviceID=PCI.LookForDevice(PCI.NetworkCntl, 0x10EC , 0x8139); return deviceID != PCI.NoDevice ; } 15 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess public int initialize() { int baseAdr = PCI.ReadConfig(deviceID, 0x04)& 0xFFFF0000; baseAdr = baseAdr | PCI.Inst_MAR|PCI.Inst_BM| PCI.Inst_IOR; PCI.WriteConfig(deviceID, 0x04, baseAdr); r= Magic.cast(Regs8139, Regs8139.mapAt( baseAdr)); return reinitialize(); } public int reinitialize() { r.initRegisters(rxBuff); rxRead=0; Interrupts.InsertHandler( this, PCI.getInterrupt(deviceID)); return start(); } public int start(){ r.CR= rEnable | tEnable; r.IMR=FOVW|RXOVW|TER|TOK|RER|ROK; state=Device.STARTED; return 0; } public int stop() { r.CR=0; r.IMR=0; state=Device.STOPPED; // disable return 0; } public long getNicAdress() { return (long) r.IDR4<<32 | r.IDR0; } private void sendMore() {} // check for pending packets some day 16 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.7 Vererbungshierarchie für Devices in Plurix • Geplant, jedoch nicht implementiert. • Grundprinzip: Device ByteDevice Keyboard V24 Networkdevice RTL8139 NE2000 Videoadapter S3 Virge VGA • Auf oberster Ebene nur abstrakte Klasse Device. • Auf unterster Ebene konkrete Implementierungen. • Package-Organisation jedoch entsprechend den PCI Signaturen. 17 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.8 Paket senden • Neuen Deskriptor aufsetzen, sobald vorherige Aktion zu Ende. • Hier wird nur ein Deskriptor verwendet (im Prinzip sind 4 vorhanden). private void Tx(int physicalAddress, int len) { while ((r.TSD0 | Tx_OWN)=0) len = len; // "lazy" loop r.TSAD0 = physicalAddress; // only descriptor #0 r.TSD0 = len ; // set length and start descriptor } • Methode sendMore(): - prüft ob noch weitere Pakete in Sender-Queue liegen, - Hier jedoch keine Sender-Queue, nur Busy-Loop, - Für optimale Performance jedoch erforderlich. • Pufferungsstrategien: 18 pro Paket maximal 1792 Bytes, nur einen Deskriptor nutzen, alle 4 Deskriptoren nutzen, weitere Pakete vorhalten. Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.9 ISR - Interrupt Service Routine: • Ein Plurix Gerätetreiber wird vom First-Level Handler (FLIH) gerufen. public int ISR() { // called by first level handler int intStatus; while ( (intStatus=r.ISR) >0) { // no write combining possible in the lines below if((intStatus&ROK)>0) { r.ISR=ROK; rxPacket (); }; if((intStatus&TOK)>0) { r.ISR=TOK; sendMore(); }; if((intStatus&(RXOVW|FOVW)) >0) r.IsR=RXOVW|FOVW; // Might insert overwrite warning message if((intStatus&TER)>0) { // transmit error r.ISR=TER; // might "clearAbort" if((r.TSAD&0xF)>0 ) // this deskriptor, low bits r.TCR= r.TCR | clearAbort; } }; return 0; } • sendMore() im Prinzip zum autonomen Versenden mehrerer Pakete. 19 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.10 First-Level Interrupt Handler • "Shared Interrupt" Szenarium: - mehrere Geräte nutzen denselben Interrupt, - PCI Bus verfügt nur über 4 Interrupt Leitungen, - Mehrere IRQ Holder (FLIH) sind an IRQ# gebunden, - IRQ-Holder ruft nacheinander die Handler für IRQ# auf, - Holder kehrt zurück, wenn keine weiteren Interrupts, - bedient den Interrupt Kontroller Chip. • Meist 15 festverdrahtete First-Level-Handler: - FLIH Instanzen mit jeweils eigener IRQ Nummer, - rufen die vorgeschriebene Methode ISR(), - Tabelle mit den Treiberinstanzen. • Vereinfachung für Plurix: - nur eine FLIH-Instanz, ohne inneren Zustand, - ISR Register im Int-Kontroller ergibt die IRQ#. • Plurix FLIH als Klasse Interrupts im Kernel-Package. 20 IDT IRQ0 IRQ1 IRQ3 IRQ15 IRQ15 IRQ12 IRQ13 IRQ14 IRQ15 Device Device Device Device Device Device Device Device FLIH ISR() Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess • Direkter Interruptaufruf (nicht Plurix): - jedes Gerät besitzt einen eigenen Interrupt mit IRQ#, dieser Interrupt ist an den Handler gebunden. Interrupt wird durch das Gerät ausgelöst. Handler wird direkt angesprungen, Schnellere Verarbeitung. IDT IRQ0 IRQ1 IRQ3 IRQ15 IRQ15 IRQ12 IRQ13 IRQ14 IRQ15 • Nachteil: - Schwierig bei "Shared Interrupts". - Treiberkontext schwieriger bereitzustellen, - Jeder Treiber muss selber den Interrupt Kontroller bedienen, Device ISR( ) Device 21 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.11 12.11.1 Empfangen eines Paketes Format im Ringpuffer: • Der Ringpuffer enthält auch die 4 Bytes des Headers, • Länge des Pakets in Bytes (2 Byte), Höheres Protokoll • Status des Pakets (2 Byte). • Ablauf im Chip - CAPR um 4 inkrementieren, Speicherplatz für ReceiveOK, CRC-Error, Runt, .. Transfer des Paketes vom FiFo in den Hauptspeicher, Nachträgliches Schreiben von Paketlänge + Status. • Empfangen eines Paketes: getData received Header rxPacket() im Treiber - Meldung der Paketankunft nach oben, - Übergeordnetes Protokoll holt dann die Daten ab, - Weiterschalten des Lesezeigers im Puffer (Karte & Programm). 22 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.11.2 Methoden zum Empfangen eines Paketes: • Überprüfen des per DMA abgelegten Paketes. • Benachrichtigen des übergeordneten IP-Protokolles. • Pufferzeiger inkrementieren - unabhängig von der höheren Ebene. • Läuft im Interrupt mit unterbundener Unterbrechung. void rxPacket() { boolean paketOK; int len, status, iMask=RxStatusOK|RxBadAlign|RxCRCErr|RxTooLong|RxRunt; while ((r.CR & BufferEmpty)==0) { // loop for finish of PCI Transfer status =(rxBuffer[rxRead+1]<<8)+rxBuffer[rxRead]; // 8139 header len =(rxBuffer[rxRead+3]<<8)+rxBuffer[rxRead+2]; // watch for Byteorder paketOK=(status & iMask)==RxStatusOK; if(packetOK && (SYSTEM.ip!=null)) { // notify protocol above and if(SYSTEM.ip.received(this, rxRead+4, len-4)); // let it then call getData } rxRead=(rxRead+len+4+3) & 0xFFFC; // update pointer, wrap around r.CAPR=rxRead-16; // notify adapter, update pointer } } 23 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess • Abholen der eingegangenen Daten durch das höhere Protokoll: public void getData(int source, int offset, int bytes, int MemAdr) { int rap, bufferOffset; // higher level protocols will acess via getData bufferOffset=(source+offset) % BufferSize; if((bufferOffset+bytes-1)<BufferSize){ Memory.CopyMemory(bufferBase+bufferOffset, MemAdr, bytes); } else {rap=BufferSize-bufferOffset; // simulate RingBuffer Memory.CopyMemory(bufferBase+bufferOffset, MemAdr, rap); Memory.CopyMemory(bufferBase, MemAdr+rap, bytes-rap); } } • Sonderfall für Wrap-Around Situation. • Läuft normalerweise ebenfalls noch im Interrupt: - Hauptarbeit in der Methode Memory.CopyMemory(), - ca. 2.5 µsec pro Kilobyte (=> R. Göckelmann), - Überlaufschutz durch die Karte. 24 Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.11.3 Byte-Order Prüfung • Little Endian (PC): Niedrigwertige Bits an niedrigen Speicheradressen: - Pascal-Testprogramm mit Varianten-Record. • 8139 Header im Bytepuffer: - Statusbits in den unteren 16 Bit, - Längenfeld in oberen 16 Bit, - byteweise zusammensetzen: 4 Byte Header Läng e 25 Status Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess 12.12 Empfang von Multicast Paketen • Anwendungsfall: z.B. Seitenanfrage oder Commit-Request im Plurix-Cluster. • Problem: - Eine Multicast Nachrichten für eine andere Gruppe sollen keine CPU-Zeit kosten, - Eine Station kann an vielen Multicast-Gruppen teilnehmen, - Hardwareaufwand soll sich in Grenzen halten. • Lösungsansatz: - Neben der eigentlichen Mac-Adresse gibt es eine 64 Bit Multicast-Bitmap, - Eine ankommende Multicast-Adresse wird hash-codiert auf "eins aus 64", - Empfang, falls das entsprechende Bit in der Multicast-Bitmap gesetzt ist, - Interrupt-Status zeigt an, dass ein Multicast Paket empfangen wurde, - Anschliessend zusätzliche Prüfung der MC-Adresse in Software. MultiC-Addr. hash ? MAC-Addr. MultiC-Bitmap 26 8139 Register sr Systemprogrammierung I, Sommer 2002, @VS, Informatik Ulm, P. Schulthess