Title: Receiver
1Receiver packet-splitting
- A look at how a driver can cause the 82573L NIC
to separate a packets headers from its data
2NIC can do packet-parsing
- Intels newest gigabit Ethernet controllers offer
an enhancement to the extended Receive
Descriptor, called packet-split format, which
empowers the hardware to recognize the packet
headers used with the most common network
protocols and to automatically separate those
headers from their accompanying packet data
3Extended RX-Descriptors
CPU writes this, NIC reads it
NIC writes this, CPU reads it
Base-address (64-bits)
MRQ (multiple receive queues)
Packet- checksum
IP identification
reserved (0)
Extended status
Packet- length
VLAN tag
Extended errors
The device-driver initializes the
base-address field with the physical address
of a packet-buffer, and it initializes the
reserved field with a zero-value the
network hardware will later modify both fields
The network controller will
write-back the values for these fields
when it has transferred a received packets
data into the packet-buffer
4Packet-Split RX-Descriptors
CPU writes this, NIC reads it
NIC writes this, CPU reads it
Base-address 0 (64-bits)
MRQ (multiple receive queues)
Packet- checksum
IP identification
Extended status
Packet- Length 0
VLAN tag
Extended errors
Base-address 1 (64-bits)
Base-address 2 (64-bits)
Packet Length 3
Packet Length 2
Packet Length 1
Header Length
S P
Base-address 3 (64-bits)
reserved
1
The network controller will write-back
values to these fields when it has transferred
a received packets data into those
packet-buffers
The device-driver initializes four
base-address fields (even-numbered addresses)
5Same Extended Status/Errors
19 18 17 16 15 14 13 12
11 10 9 8 7 6 5 4
3 2 1 0
0
0
0
0
A C K
0
0
0
0
U D P V
I P I V
0
P I F
I P C S
T C P C S
U D P C S
V P
I X S M
E O P
D D
11 10 9 8 7
6 5 4 3 2
1 0
RXE
IPE
TCPE
0
0
SEQ
SE
CE
0
0
0
0
6Syntax modifications for fetch
typedef struct unsigned long
long base_addr0 unsigned long
long base_addr1 unsigned long
long base_addr2 unsigned long
long base_addr3 RX_DESC_FETCH
7Syntax modifications for store
typedef struct unsigned int mrq unsigned
short ip_identification unsigned
short packet_chksum unsigned
int desc_status20 unsigned
int desc_errors12 unsigned
short packet_length0 unsigned
short vlan_tag unsigned short header_length
unsigned short packet_length1 unsigned
short packet_length2 unsigned
short packet_length3 unsigned long
long reserved RX_DESC_STORE
8Same syntax for the union
typedef union RX_DESC_FETCH rxf RX_DESC
_STORE rxs RX_DESCRIPTOR
9NIC Registers involved
31
10
0
D T Y P
RCTL
Device Control register
31
15
0
Reserved (0)
E X T E N
RFCTL
Receive Filter Control register
31 24 23
16 15 8
7 0
LEN3 (1KB)
LEN0 (128B)
LEN1 (1KB)
LEN2 (1KB)
PSRCTL
Packet-Split Receive Control register
10Each descriptor has four buffers
Packet-Split Rx-descriptor
base_addr0
base_addr1
base_addr2
base_addr3
buffer0
buffer1
buffer2
buffer3
Four buffers are allocated for receiving one
packet
11Refresh for reuse
- As with the extended receive-descriptors, it is
necessary for a device-driver to setup each
packet-split receive-descriptor any time it is
going to be reused, since prior
buffer-addresses get overwritten during a
packet-reception by the network controller - So driver needs a formula for recalculating
buffer-addresses, or use a shadow array
12Kernel-memory layout
Sixteen Rx-descriptors (32-bytes each)
Sixty-four receive-buffers (1024-bytes each)
512 bytes
65536 bytes
KMEM_SIZE ( 66048 bytes)
kmem
13Caveats
- Short packets are not always split
- Unrecognized packet-headers may not be separated
from accompanying packet-data - Demonstrating the packet-split capability will
require us to devise a way to transmit packets
which have the TCP/UDP and IP packet-headers that
the NIC recognizes
14Our pktsplit.c demo
- We created a minimal kernel-module for
demonstrating the NICs packet-splitting
capabilities
TIMEOUT for an in-class demonstration
15In-class exercise
- Can you enhance our pktsplit.c module so that
its Receive-Descriptor Queue will function
automatically as a ring-buffer (as happens in our
extended.c example)? - Your best option for this is to install an ISR
which will reinitialize some Rx-Descriptors (and
advance the RDT index) each time an RXDMT0
interrupt gets triggered