The RealTek interface Introduction to the RTL-8139 network controller registers Device driver’s duties • Summary of device-driver responsibilities: – Detect – Register – Reset – Allocate – Initialize – Enable – Configure – Manage PCI device detection #include <linux/pci.h> #define VID 0x10EC // RealTek Corp #define DID 0x8139 // RTL8139 chip struct pci_dev *devp; // structure pointer devp = pci_find_device( VID, DID, NULL ); if ( devp == NULL ) return –ENODEV; Two access methods • The 8139 provides two ways for drivers to access its device-registers: – via io-port addresses (use ‘in’ and ‘out’) – via memory addresses (use ‘mov’, ‘and’, ‘or’) • io_base = pci_resource_start( devp, 0 ); • io_len = pci_resource_len( devp, 0 ); • membase = pci_resource_start( devp, 1 ); • memlen = pci_resource_len( devp, 1 ); Advantages/Disadvantages • Memory-space access is faster and more flexible (can directly use x86 instructions) • But memory-mapped access requires the setup of suitable entries in the system’s page-directory and page-table(s), and the driver-writer must consider caching issues and instruction-reordering by the compiler • I/O port-access is more straightforward How many registers? • By either access-method, the RTL-8139 provides 256-byte programming interface • Register-sizes vary: 8-bit, 16-bit, 32-bit • Register-implementations vary: most are read/write; some are read-only, some are write-only; some are ‘reserved’; some may have undisclosed functions; some have clearly documented ‘side-effects’ You need these Manuals! • RealTek has two official publications that are vital for writers of device-drivers: – RTL-8139D(L) Datasheet (60 pages) – RTL-8100 Programming Guide (10 pages) • These docs are not protected by copyright, so we are providing copies for you to use The Linux driver • You can also look at the source-code for the Linux driver that operates our NICs: – See: ‘/usr/src/linux/drivers/net/8139too.c’ • And there are other public-domain drivers for the 8139 controller as well • The authors of these drivers have added comments in their code, which may help whenever the manuals are ambiguous Examination at ‘runtime’ • It is very helpful to look at the contents of the RTL-8139 registers while the network is being used (as programmed by another driver-writer) • We have created a special device-driver that makes this possible: ‘mmap8139.c’ • Using this driver, a companion program (‘nicregs.cpp’) displays all 8139 registers Command Register byte-register at offset 0x37: 7 6 5 0 0 0 4 3 2 Reset RxEn TxEn r/w r/w r/w 1 0 0 RxBuf empty r/o Legend: RxBuf empty (Receive Buffer is Empty): 1 = yes. 0 = no TxEn (Transmission is Enabled): 1 = yes, 0 = no RxEn (Reception is Enabled): 1 = yes, 0 – no Reset (Resets the controller): writing 0 to this bit has no effect; writing 1 to this bit initiates a ‘reset’ operation, placing all the NIC registers and internal buffers into a known default state; this bit automatically clears upon completion of the reset operation. The six ID registers • Six byte-registers (at offsets 0x00-0x05) hold the unique identification number of your network controller – known as the MAC address (Media Access Control) • The transceiver uses the MAC-address to ‘filter out’ all packets on the local network that were not directed to your machine • These six registers get initialized during power-on reset (and seem to be read-only) Display of the MAC-address • Here’s a programming loop that will print your MAC-address using the customary hexadecimal format: xx:xx:xx:xx:xx:xx unsigned char *reg = <base-address>; for (int i = 0; i < 6; i++) { char ch = ( i < 5 ) ? ‘:’ : ‘ ‘; printf( “%02X%c”, reg[ i ], ch ); } Transmit Configuration 32-bit register (offsets 0x40-0x43): 31 30 26 25 Hardware Version ID (Part A) 15 24 Inter Frame Gap 11 10 8 MAX DMA BURST 23 22 21 20 HWVER ID (Part B) 7 GAP 2 4 Transmission Retry Count 19 18 17 16 LOOP BACK TEST C R C 0 CLR ABT Receive Configuration 32-bit register (offsets 0x44-0x47) 31 28 27 13 Rx FIFO Threshold 23 18 Early Receive Threshold reserved 15 24 12 11 Rx Buf Length 10 7 5 4 Max DMA Burse Size W R A P L O N G R U N T 0 16 Mult Rx ER ERR INT 8 reserved 8 17 3 B C A S T 2 1 0 M C A S T M A C A L L In-class exercise #1 • Enhance the information displayed by the ‘nicregs.cpp’ demo-program by showing the workstation’s hostname: #include <unistd.h> char hostname[ 64 ]; gethostname( hostname, 64 ); printf( “station is %s \n”, hostname ); In-class exercise #2 • Enhance the ‘nicregs.cpp’ application, by adding ‘printf()’ statements to display the information in registers in a way that can more easily understood by humans: – Show the chip’s unique MAC address – Show the Transmit Configuration fields – Show the Receive Configuration fields – Show the Command Register settings