Linux Device Drivers

Linux Device Drivers


Linux
Modules
Character drivers
IO & Memory
Linux Kernel
Process Management
Process Address space

Linux Scheduler
Memory Management
Interrupts
Signals
System Calls
Kernel Synchronization
Linux Inter Process Communications




Serial Ports
Parallel Ports
Introduction to Hardware
Linux Timers
DMA in Linux
Linux Threads
Linux Thread Synchronization

Linux Multi Threading
Debugging in Linux
GDB GNU Debugger
KDB Kernel Debugger
KGDB Kernel GNU Debugger
Example Ethernet Driver




Realtek RTL8139C(L)

Realtek RTL8139C(L)

 

The Realtek RTL8139C(L) is a highly integrated and cost-effective single-chip Fast Ethernet controller that provides 32-bit performance, PCI bus master capability, and full compliance with IEEE 802.3u 100Base-T specifications and IEEE 802.3x Full Duplex Flow Control.

It also supports Advanced Configuration Power management Interface (ACPI), PCI power management for modern operating systems that are capable of Operating System Directed Power Management (OSPM) to achieve the most efficient power management possible.

The RTL8139CL is suitable for applications such as CardBus or mobile devices with a built-in network controller.

 

 

Application Diagram

 

 

Transmit Packet

 

Architecture:

 

There are 4 Tx descriptors (TSD0-3), each descriptor has a fixed IO address offset. These 4 descriptors are used in round-robin. Transmit FIFO is a 2k bytes buffer in the chip that hold the data prepared to move to line(cable). Data in Transmit FIFO start move to line when early transmit threshold is meet (TSD0-3, Bit 21-16).

 

Transmit Packet

 

The Process of Tx:

 

1.     Copy the packet to a continuous buffer of Phy memory

2.     Write the start address of buffer to TSAD0-3

3.     Write the TSD0-3 (Early Tx Threshold, OWN, and Descriptor Size)

4.     Chip will start transmit when the byte count of the data in the Tx FIFO reaches the level Early_Tx_Threshold

5.     Own bit set to 0 when whole packet was moved to Tx FIFO

6.     TOK (TSD0-3 bit 15) set to 1 when whole packet was moved to line

7.     TOK interrupt (Offset 3Eh bit 2) arise

8.     Interrupt service routine be called, clear TOK(ISR), OWN/TOK(TSD0-3)

 

Involved Register

 

-TSD0-3 (Offset 0010h-001Fh)

-TSAD0-3 (Offset 0020h-002Fh)

-ISR/IMR (TOK/TER bits)

-TCR(Offset 0040h) Max DMA Burst Size (Bit 10-8)

Suggest value: 110 = 1024 bytes

 

Receive Packet

 

Architecture:

 

The receive path is designed as a ring buffer. This ring buffer is in a physical continuous memory. The register CBA keeps the current address of data moved to buffer. CAPR is the read pointer which keeps the address of data that driver had read. The status of receiving a packet is stored in front of the packet (Rx packet header).

 

Receive Packet

 

Rx Buffer Ring

 

 

 

The Process of Rx:

 

1.     Driver set RBSTART and CAPR during chip initialize

2.     Data received from line is stored in the receive FIFO

3.     Chip start moving data from Rx FIFO to Rx Buffer when the byte count of the data reaches the level of Rx_FIFO_Threshold (RCR bit 15-13) or Rx FIFO contained a complete packet

4.     Chip will write Rx Packet Header and update CBR(3Ah)

5.     ROK interrupt (Offset 3Eh bit 0) arise and BUFE (Offset 37h bit 0) Buffer_Empty set to 0 if no more packet stored in Rx Buffer

6.     Interrupt service routine be called, clear ROK and update CAPR

 

Receive Packet

 

Involved Register:

 

-RBSTART (Offset 30h)

-CR (Offset 37h) Buffer Empty (Bit 0)

-CAPR (Offset 38h)

-CBR (Offset 3Ah)

-ISR/IMR (ROK/RER/RXOVW/FOVW)

-RCR (Offset 44h)

-Rx Packet Header

 

Receive Packet

 

Driver program issue:

 

1.     Rx Buffer Overflow occur

a.      Chip will stop DMA (FIFO to Buffer)

b.     Driver has to write 1 to RXOVW (ISR bit 4)

 

2.     Rx FIFO Overflow occur

a.      All incoming packets will be discarded

b.     Driver has to write 1 to FOVW (ISR bit 6)

 

3.     Rx FIFO Threshold (RCR bit 15-12)

a.      Avoid set 111 = no rx threshold (suggest value: 110)

 

4.     Suggested handling

 

if (ROK/RXOVW/FOVW)

{

ClearISR(ROK/RXOVW/FOVW);

}

 

if (ROK)

{

while (Buffer Empty)

{

Receive one packet and update CAPR;

}

}