RTL8169 — Änderungen 11246 → 11247

Zeile 10: Zeile 10:
 
=== IO/MMIO ===
 
=== IO/MMIO ===
 
RTL8168 und RTL8169 unterstützen MMIO. Die Basisadresse kann über die [[PCI]]-BARs ausgelesen werden. Sollten mehrere MMIO-BARs angegeben sein, ist die erste zu nutzen. Im Folgenden wird die Karte über IO-Ports angesteuert, für eine Ansteuerung über MMIO kann analog vorgegangen werden.
 
RTL8168 und RTL8169 unterstützen MMIO. Die Basisadresse kann über die [[PCI]]-BARs ausgelesen werden. Sollten mehrere MMIO-BARs angegeben sein, ist die erste zu nutzen. Im Folgenden wird die Karte über IO-Ports angesteuert, für eine Ansteuerung über MMIO kann analog vorgegangen werden.
 +
 +
Die Offsets der im Folgenden verwendeten Register sind wie folgt definiert:
 +
<c>
 +
#define RTL8168_IDR0                0x00        // Mac address
 +
#define RTL8168_TXDESC              0x20        // Tx descriptors (32bit)
 +
#define RTL8168_RXDESC              0xE4        // Tx descriptors (32bit)
 +
#define RTL8168_CHIPCMD            0x37        // Command register
 +
#define RTL8168_TPPOLL              0x38        // Transmit Priority Polling
 +
#define RTL8168_INTRMASK            0x3C        // Interrupt mask
 +
#define RTL8168_INTRSTATUS          0x3E        // Interrupt status
 +
#define RTL8168_TXCONFIG            0x40        // Tx config
 +
#define RTL8168_RXCONFIG            0x44        // Rx config
 +
#define RTL8168_CFG9346            0x50        // 93C46 command register
 +
#define RTL8168_RPS                0xDA        // Max Receive Packet Size
 +
</c>
  
 
=== MAC-Adresse herausfinden ===
 
=== MAC-Adresse herausfinden ===
Zeile 17: Zeile 32:
 
for(int i = 0; i < 6; ++i)
 
for(int i = 0; i < 6; ++i)
 
{
 
{
−
     mac_addr[i] = inb(pci_port + i); // Funktion zum Einlesen eines Bytes vom angegebenen Port
+
     mac_addr[i] = inb(port_base + RTL8168_IDR0 + i); // Funktion zum Einlesen eines Bytes vom angegebenen Port
 
}
 
}
 
</c>
 
</c>
Zeile 36: Zeile 51:
 
</c>
 
</c>
  
−
Die Deskriptoren sind an 256-Bytes-Grenzen auszurichten und bilden einen Ring, dessen Ende durch das Setzen von Bit 30 des command-Felds indiziert wird. In dieses Feld werden außerdem die Länge des Puffers (Bits 0-15) so wie das OWN-Bit (Bit 31) geschrieben. Die Sende- bzw. Empfangspuffer können maximal 64 KiB groß sein, ihre physische Adresse wird in low_buf und high_buf gespeichert. Die Puffer sind an 8-Bytes-Grenzen auszurichten.
+
Die Deskriptoren sind an 256-Bytes-Grenzen auszurichten und bilden einen Ring, dessen Ende durch das Setzen von Bit 30 des command-Felds indiziert wird. In dieses Feld werden außerdem die Länge des Puffers (Bits 0-15) so wie das OWN-Bit (Bit 31) geschrieben. Die Sende- bzw. Empfangspuffer können maximal 64 KiB groß sein (allerdings kann die Karte höchstens 16 KiB große Pakete empfangen), ihre physische Adresse wird in low_buf und high_buf gespeichert. Die Puffer sind an 8-Bytes-Grenzen auszurichten.
  
 
Die Karte verfügt über drei Ringe von je maximal 1024 Deskriptoren, einen Empfangsring, einen Sendering mit normaler und einen Sendering mit hoher Priorität.
 
Die Karte verfügt über drei Ringe von je maximal 1024 Deskriptoren, einen Empfangsring, einen Sendering mit normaler und einen Sendering mit hoher Priorität.
  
 +
=== Konfiguration ===
 +
Dieser Beispielcode konfiguriert die Karte für das Senden und Empfangen von Paketen. Hierbei wird die Karte in den sog. "promiscuous mode" gesetzt, in dem alle Pakete akzeptiert werden, auch solche, die nicht an das Gerät gerichtet sind. Weiterhin werden Interrupts aktiviert.
 +
<c>
 +
outb(port_base + RTL8168_CFG9346, 0xC0); // Entsperren der Konfigurationsregister durch Schreiben von 0xC0 in das 93C46-Kommandoregister
 +
outl(port_base + RTL8168_RXCONFIG, 0x0000E70F); // RxConfig = RXFTH: unlimited, MXDMA: unlimited, AAP: set (promisc. mode set)
 +
outb(port_base + RTL8168_CHIPCMD, 0x04); // Aktiviere Tx, bevor TxConfig gesetzt wird
 +
outl(port_base + RTL8168_TXCONFIG, 0x03000700); // TxConfig = IFG: normal, MXDMA: unlimited
 +
outw(port_base + RTL8168_RPS, 0x1FFF); // Maximale Größe empfangener Pakete (hier: 8 KiB)
 +
 +
outl(port_base + RTL8168_TXDESC, paging_getPhysAddr(rAdapter->Tx_Descriptors)); // Adresse des ersten Tx-Descriptors (normale Priorität)
 +
outl(port_base + RTL8168_RXDESC, paging_getPhysAddr(rAdapter->Rx_Descriptors)); // Adresse des ersten Rx-Descriptors
 +
 +
outw(port_base + RTL8168_INTRMASK, 0xC3FF); // Aktiviere alle Interrupts
 +
outb(port_base + RTL8168_CHIPCMD, 0x0C); // Aktivere Senden und Empfangen
 +
outb(port_base + RTL8168_CFG9346, 0x00); // Sperren der Konfigurationsregister
 +
</c>
  
 
==Weblinks==
 
==Weblinks==