lesson06.ppt

advertisement
What’s needed to transmit?
A look at the minimum steps
required for programming our
anchor nic’s to send packets
Access to PRO/1000 registers
• Device registers are hardware mapped to
a range of addresses in physical memory
• You obtain the location (and the length) of
this memory-range from a BAR register in
the nic device’s PCI Configuration Space
• Then you request the Linux kernel to setup
an I/O ‘remapping’ of this memory-range to
‘virtual’ addresses within kernel-space
i/o-memory remapping
Local-APIC
IO-APIC
nic
registers
APIC registers
nic registers
vram
1-GB
kernel code/data
vram
user
space
dynamic
ram
physical address-space
‘virtual’ address-space
3-GB
Enhanced ‘82573.c’ module
• Originally we created this module to view
the PCI Configuration Space for our nic
• Today we’ve added two character-mode
device-driver ‘methods’ allowing us to see
values in all of the nic’s internal registers
• You can use our ‘fileview’ utility to ‘read’
and ‘seek’ in the ‘/dev/82573’ device-file
(or you could write your own application)
An observation
• We notice that the 82573L device retains
the values in many of its internal registers
• This fact reduces the programming steps
that will be required to operate our nic on
the anchor cluster machines, since Intel’s
own Linux device driver (‘e1000.ko’) has
already initialized many nic registers
• But we WILL need to bring ‘eth1’ down!
Use ‘/sbin/ifconfig’
• You can use the ‘/sbin/ifconfig’ command
to find out whether the ‘eth1’ interface has
been turned off:
$ /sbin/ifconfig eth1
• If it is still operating, you can turn it off with
the (privileged) command:
$ sudo /sbin/ifconfig eth1 down
Our ‘nicping.c’ demo
• We created this module to help us identify
all of the programming steps that would be
needed for our nic to ‘transmit’ a packet
• The action of displaying this module’s
pseudo-file (e.g., with the ‘cat’ command)
will trigger transmission of a ‘broadcast’
message to all the other stations on our
anchor cluster’s LAN (if they are ‘listening’)
Tx-Desc Ring-Buffer
0x00
TDBA
base-address
0x10
0x20
TDH (head)
0x30
TDLEN
(in bytes)
0x40
0x50
0x60
TDT (tail)
0x70
0x80
= owned by hardware (nic)
= owned by software (cpu)
Circular buffer (128-bytes minimum)
How ‘transmit’ normally works
List of Buffer-Descriptors
descriptor0
descriptor1
descriptor2
descriptor3
0
0
0
0
Buffer0
Buffer1
Buffer2
We setup each data-packets that we want
to be transmitted in a ‘Buffer’ area in ram
We also create a list of buffer-descriptors
and inform the NIC of its location and size
Then, when ready, we tell the NIC to ‘Go!’
(i.e., start transmitting), but let us know
when these transmissions are ‘Done’
Buffer3
Random Access Memory
How ‘transmit’ works here
List of Buffer-Descriptors
TDH
TDT
descriptor0
descriptor1
descriptor2
descriptor3
descriptor4
descriptor5
descriptor6
descriptor7
Packet
Buffer
We setup just one packet-buffer, and we
let all of our descriptors pointing to it
We retain ‘ownership’ of all our descriptors,
so nothing gets transmitted, until we have
prepared all our data in the packet-buffer
Then, when ready, we tell the NIC to ‘Go!’
(i.e., start transmitting), by giving the nic
‘ownership’ of only the next descriptor
Random Access Memory
Essential ‘transmit’ registers
enum
{
E1000_CTRL
E1000_STATUS
E1000_IMC
E1000_TCRL
E1000_TDBAL
E1000_TDBAH
E1000_TDLEN
E1000_TDH
E1000_TDT
E1000_RA
};
0x0000, // Device Control
0x0008, // Device Status
0x00D8, // Interrupt Mask Clear
0x0400, // Transmit Control
0x3800, // Tx Descriptor Base Address Low
0x3804, // Tx Descriptor Base Address High
0x3808, // Tx Descriptor Length
0x3810, // Tx Descriptor Head
0X3818, // Tx Descriptor Tail
0x5400, // Receive address-filter Array
Programming challenge
• Can you see how use the code shown in
this example-module to implement a TX
capability in our earlier ‘netframe.c’ driver?
Download