Our ‘nic.c’ module We create a ‘character-mode’ device-driver for the 82573L NIC to use in futrure experiments Character devices • The concept of a ‘character mode’ device is that it provides a ‘stream’ of data bytes which application-programs can access with these standard Linux system-calls: – ‘open()’ and ‘close()’ – ‘read()’ and ‘write()’ – ‘lseek()’ Requirement • The character-mode devices are known to a Linux system by their ‘names’ and by an associated pair of ID-numbers (major and minor) normally set up by a ‘superuser’ root# mknod /dev/nic c 97 0 root# chmod a+rw /dev/nic Driver module nic.c this module’s collection of ‘payload’ functions get_info() isr() read() write() ioctl() fops required pair of module administration functions module_init module_exit character-mode device-driver’s required ‘file-operations’ data-structure Overview user space standard runtime libraries kernel space Linux operating system Kernel file subsystem application program networking subsystem char driver module hardware Transmit operation user space kernel space Linux OS kernel runtime library write() file subsystem nic device-driver my_write() user data-buffer copy_from_user() packet buffer DMA application program hardware Receive operation user space kernel space Linux OS kernel runtime library read() file subsystem nic device-driver my_read() user data-buffer copy_to_user() packet buffer application program DMA hardware Our packet-format • Our ‘nic.c’ driver elects to have the NIC append ‘padding’ to any short packets • But this prevents a receiver from knowing how many bytes represent actual data • To solve this problem, we added our own ‘count’ field to each packet’s payload 0 6 destination MAC-address source MAC-address actual bytes of user-data 12 Type/Len 14 count Using ‘echo’ and ‘cat’ • Our device-driver module ‘nic.c’ is intended to allow two programs that are running on a pair of anchor-cluster PCs to communicate via that cluster’s Local Area Network Transmitting… $ echo Hello > /dev/nic $_ Receiving… $ cat /dev/nic Hello _ “Jumbo” packets • One of the innovations provided by gigabit ethernet technology is support in the NIC for larger-than-normal size data-packets • The most common upper bound for data capacity in “jumbo” frames is 9000 bytes (plus the usual ethernet frame “header”) • Our 82573L network controller implements “long packet” support as an option Receive Control (0x0100) 31 R =0 30 29 0 28 27 F 0LXBUF 15 B A M 14 R =0 13 MO 26 25 SE CRC BSEX 12 24 R 23 22 PMCF DPF =0 11 DTYP 10 9 8 RDMTS 21 20 R CFI =0 7 6 I S L LBML O S U 19 CFI EN 5 18 17 BSIZE VFE 4 16 3 2 LPE MPE UPE SBP 0 1 0 E R 0N =0 EN = Receive Enable DTYP = Descriptor Type DPF = Discard Pause Frames SBP = Store Bad Packets MO = Multicast Offset PMCF = Pass MAC Control Frames UPE = Unicast Promiscuous Enable BAM = Broadcast Accept Mode BSEX = Buffer Size Extension MPE = Multicast Promiscuous Enable BSIZE = Receive Buffer Size SECRC = Strip Ethernet CRC LPE = Long Packet reception Enable VFE = VLAN Filter Enable FLXBUF = Flexible Buffer size LBM = Loopback Mode CFIEN = Canonical Form Indicator Enable RDMTS = Rx-Descriptor Minimum Threshold Size CFI = Cannonical Form Indicator bit-value Our ‘nic.c’ driver initially will program this register with the value 0x0400801C. Later, when everything is ready, it will turn on bit #1 to ‘start the receive engine’ 82573L Project 1 • Revise our ‘nic.c’ device-driver module so it will allow application programs to ‘write’ (i.e., transmit) and to ‘read’ (i.e., receive) “jumbo” packets which contain up to 9000 data-bytes, plus ethernet header and CRC • Construct a pair of application-programs that you can use (in place of ‘echo’ and ‘cat’) to test your enhanced device-driver In-class demonstration • We can use our (unmodified) ‘nic.c’ driver to study the way in which our 82573L NIC uses a portion of its internal i/o-memory • We can view the NIC’s internal memory using our ‘82573.c’ character driver and our ‘fileview’ navigation-tool • We’ve also created an additional module (named ‘nicmap.c’) to assist in this study Rx-Descriptor Control (0x2828) 31 0 30 29 0 28 0 15 0 27 0 25 24 0 0 0 G R A N 13 12 11 10 0 14 26 0 FRC HTHRESH FRC 0 DPLX SPD (Host Threshold) 23 22 0 0 9 8 21 20 19 18 17 16 WTHRESH (Writeback Threshold) 7 I L 0 O0 S 6 00 5 A S D E 4 3 2 1 L PTHRESH R 0 00 00 (Prefetch S Threshold) T “This register controls the fetching and write back of receive descriptors. The three threshhold values are used to determine when descriptors are read from, and written to, host memory. Their values can be in units of cache lines or of descriptors (each descriptor is 16 bytes), based on the value of the GRAN bit (0=cache lines, 1=descriptors). When GRAN = 1, all descriptors are written back (even if not requested).” --Intel manual Recommended for 82573: 0x01010000 (GRAN=1, WTHRESH=1) 0 Exploring RX Descriptor FIFO Timeout for an in-class demonstration In-class exercise • Modify the code in our ‘nicmap.c’ module so that you can use it to explore the NIC’s TX Descriptor FIFO (begins at 0x07000)