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 #define VID0x10EC // RealTek Corp #define DID0x8139// 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: 000ResetTxEn0 RxBuf empty r / or / w RxEn 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 = ; 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): Hardware Version ID (Part A) Inter Frame Gap HWVER ID (Part B) GAP 2 LOOP BACK TEST CRCCRC MAX DMA BURST Transmission Retry Count CLR ABT
Receive Configuration 32-bit register (offsets 0x44-0x47) reserved Early Receive Threshold reserved Mult ER INT Rx ERR 8 Rx FIFO Threshold Rx Buf Length Max DMA Burse Size WRAPWRAP 0 LONGLONG RUNTRUNT BCASTBCAST MCASTMCAST MACMAC ALLALL
In-class exercise #1 Enhance the information displayed by the ‘nicregs.cpp’ demo-program by showing the workstation’s hostname: #include 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