Network Interface Card �& its Linux programming
Dr A Sahu
Dept of Comp Sc & Engg.
IIT Guwahati
Outline
Major Player of NIC Cards
Detecting PCI Devices : Early PCs
The PC’s evolution
PCI Configuration Space
PCI Configuration Space Body
(48 doublewords – variable format)
64
doublewords
PCI Configuration Space Header
(16 doublewords – fixed format)
A non-volatile parameter-storage area
for each PCI device-function
PCI Configuration Header
Status
Register
Command
Register
Device
ID
Vendor
ID
BIST
Cache
Line
Size
Class Code
Class/SubClass/ProgIF
Revision
ID
Base Address 0
Subsystem
Device ID
Subsystem
Vendor ID
CardBus CIS Pointer
reserved
capabilities
pointer
Expansion ROM Base Address
Minimum
Grant
Interrupt
Pin
reserved
Latency
Timer
Header
Type
Base Address 1
Base Address 2
Base Address 3
Base Address 4
Base Address 5
Interrupt
Line
Maximum
Latency
31 0
31 0
16 doublewords
Dwords
1 - 0
3 - 2
5 - 4
7 - 6
9 - 8
11 - 10
13 - 12
15 - 14
Three IA-32 address-spaces
memory
space
(4GB)
i/o space
(64KB)
PCI
configuration
space
(16MB)
accessed using a large variety of processor
instructions (mov, add, or, shr, push, etc.)
and virtual-to-physical address-translation
accessed only by using the processor’s
special ‘in’ and ‘out’ instructions
(without any translation of port-addresses)
i/o-ports 0x0CF8-0x0CFF dedicated to accessing PCI Configuration Space
Interface to PCI Configuration Space
reserved
CONFADD
( 0x0CF8)
CONFDAT
( 0x0CFC)
31 23 16 15 11 10 8 7 2 0
E
N
bus
(8-bits)
device
(5-bits)
doubleword
(6-bits)
function
(3-bits)
00
PCI Configuration Space Address Port (32-bits)
PCI Configuration Space Data Port (32-bits)
31 0
Enable Configuration Space Mapping (1=yes, 0=no)
Reading PCI Configuration Data
Example: network interface
</usr/src/linux/include/linux/pci_ids.h>
Vendor’s identity example
nic
Typical NIC
TX FIFO
RX FIFO
transceiver
LAN
cable
B
U
S
main
memory
packet
buffer
CPU
Packet filtering capability
network packet’s layout
Destination-address (6-bytes)
Source-address (6-bytes)
Each data-packet begins with the 6-byte device-address
of the network interface which is intended to receive it
Your NIC’s unique address
$ /sbin/ifconfig
eth0 Link encap: Ethernet HWaddr 00:11:43:C9:50:3A
Demo “nic_pci_info.c”
How we got the MAC-address
</usr/src/linux/drivers/net/>
How we get PCI_NIC registers
Status
Register
Command
Register
DeviceID
0x1677
VendorID
0x14E4
BIST
Cache
Line
Size
Class Code
Class/SubClass/ProgIF
Revision
ID
Base Address 0
Subsystem
Device ID
Subsystem
Vendor ID
CardBus CIS Pointer
reserved
capabilities
pointer
Expansion ROM Base Address
Minimum
Grant
Interrupt
Pin
reserved
Latency
Timer
Header
Type
Base Address 1
Base Address 2
Base Address 3
Base Address 4
Base Address 5
Interrupt
Line
Maximum
Latency
31 0
31 0
16 doublewords
Dwords
1 - 0
3 - 2
5 - 4
7 - 6
9 - 8
11 - 10
13 - 12
15 - 14
Linux helper-functions
#include <linux/pci.h>
struct pci_dev *devp;
unsigned int iomem_base, iomem_size;
void *io;
devp = pci_get_device( 0x14E4, 0x1677, NULL );
if ( !devp ) return –ENODEV;
iomem_base = pci_resource_start( devp, 0 );
iomem_size = pci_resource_len( devp, 0 );
io = ioremap( iomem_base, iomem_size );
if ( !io ) return -EBUSY;
Big-Endian to Little-Endian
mac
1
mac
0
mac
5
mac
4
mac
3
mac
2
0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 0x0416 0x0417
Broadcom network interface storage-addresses
Intel IA-32 character-array storage
mac
0
mac
1
mac
2
mac
3
mac
4
mac
5
Little-Endian to Little-Endian
mac
0
mac
1
mac
2
mac
3
mac
4
mac
5
0x5400 0x5401 0x5402 0x5403 0x5404 0x5405 0x5406 0x5407
Intel network interface storage-addresses
Intel IA-32 character-array storage
mac
0
mac
1
mac
2
mac
3
mac
4
mac
5
For Intel NICs
#define VENDOR_ID 0x8086 // Intel Corp
#define DEVICE_ID 0x109A // 82573L NIC
Ethernet LAN
host-1
host-2
host-3
host-4
HUB
“Collision Domain”
CSMA/CD = “Carrier Sense Multiple Access/Collision Detection”
Acronyms
Intel 82573L NIC: Hardware Features
External Architecture
PCI/PCI-e Bus
10/100/1000 PHY
MAC/Controller
MDI interface
SM Bus
interface
EEPROM
Flash
interface
LED
indicators
S/W Defined
pins
GMII/MII
interface
MDIO
interface
Access to PRO/1000 registers
i/o-memory remapping
dynamic
ram
nic
registers
vram
IO-APIC
Local-APIC
user
space
APIC registers
kernel code/data
nic registers
vram
‘virtual’ address-space
physical address-space
1-GB
3-GB
portability syntax
#include <asm/io.h>
unsigned int datum;
iowrite32( datum, address );
datum = ioread32( address );
module_init()
#include <linux/pci.h>
#include <asm/io.h>
#define E1000_STATUS 0x0008
unsigned int iomem_base, iomem_size;
void *io;
// remap the device’s i/o-memory into kernel space
devp = pci_get_device( VENDOR_ID, DEVICE_ID, NULL );
if ( !devp ) return –ENODEV;
iomem_base = pci_resource_start( devp, 0 );
iomem_size = pci_resource_len( devp, 0 );
io = ioremap_nocache( iomem_base, iomem_size );
if ( !io ) return –ENOSPC;
// read and display the nic’s STATUS register
device_status = ioread32( io + E1000_STATUS );
printk( “ Device Status Register = 0x%08X \n”, status );
0
Device Status (0x0008)
?
0
0
0
0
0
0
0
0
0
0
0
GIO
Master
EN
0
0
0
0
0
0
0
PHY
reset
ASDV
I
L
O
S
S
L
U
0
TX
OFF
0 0
F
D
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Function
ID
L
U
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
SPEED
FD = Full-Duplex
LU = Link Up
TXOFF = Transmission Paused
SPEED (00=10Mbps,01=100Mbps, 10=1000Mbps, 11=reserved)
ASDV = Auto-negotiation Speed Detection Value
82573L
some undocumented functionality?
Thanks