1 / 21

CS 498 Lecture 8 Network Drivers

CS 498 Lecture 8 Network Drivers. Jennifer Hou Department of Computer Science University of Illinois at Urbana-Champaign Reading: Chapters 5.3, The Linux Networking Architecture: Design and Implementation of Network Protocols in the Linux Kernel. Network Device Interfaces.

finley
Download Presentation

CS 498 Lecture 8 Network Drivers

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CS 498 Lecture 8Network Drivers Jennifer Hou Department of Computer Science University of Illinois at Urbana-Champaign Reading: Chapters 5.3, The Linux Networking Architecture: Design and Implementation of Network Protocols in the Linux Kernel

  2. Network Device Interfaces Higher Protocol Instances Network devices (adapter-independent) dev.c dev_open dev_close netif_rx dev_queue_xmit Network devices interface net_device dev->hard_start_xmit dev->open dev->stop Abstraction from Adapter specifics driver.c net_start_xmit net_rx net_tx Network driver (adapter-specific) net_open net_stop skb skb net_interrupt skb

  3. Procedures to Look at in Network Drivers • Initializing network adapters • Opening and closing a network adapter • Sending data packets to a network adapter • Receiving data packets from a network adapter

  4. init() • An example is netcard_probe(dev) in net/core/isa-skeleton.c (lines 135-157). • Major functions • Search for a matched adapter and discover the I/O port for devbase_addr. • Initialize the net_device structure with driver information.

  5. When is init() Invoked? Recall in register_netdevice() • If devinit() exists, the network adapter is first searched and initialized with the function init(). • If a net_device with the same name is already in the list dev_base, return an error message; otherwise, add the dev_device, dev, to the list. • Sets devstate to LINK_STATE_PRESENT • dev_init_scheduler() (i) sets the scheduling discipline to FIFO; (ii) initializes the timer devwatchdog_timer with dev_watchdog_init(). • The network device is assigned a new index (devifindex). • notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev) calls all the registered methods in netdev_chain

  6. Searching for a Network Adapter • Case 1: If the base address is already specified when the module is loaded or when the system is booted, it can be used to locate the network adapter. • In the case of modularized drivers, the I/O base address (e.g., io=0x280) is transferred to the net_device structure in init_module() of the driver module. • In the case of integrated drivers, the base address is maintained in the list dev_boot_setup of the method netdev_boot_setup_check() at system boot time. The base address is then set in the net_device structure in init_netdev().

  7. Searching for a Network Adapter • Case 2: The base address is not specified: • A network adapter generally supports a set of defined port addresses. • The addresses in the pre-defined set can be probed one after another to locate a network adapter. • In either case, the I/O port, starting at the base address, are reserved by request_region (ioaddr,NETCARD_IO_EXTENT, cardname).

  8. Initializing physical/MAC fields in net_device • If the network adapter does not support dynamic interrupt allocation, then the irq number is determined (through autoirq_setup() followed by autoirq_report()). The irq request is made via request_irq() • A list of reserved interrupts can be viewed in /proc/interrupts • The DMA channel is determined and reserved by request_dma(). • The memory for the private data structure devpriv is reserved and initialized. • The references to driver-specific methods are set in the net_device structure. Methods specific to the MAC protocol is set via ether_setup().

  9. Helper Functions • request_region(port,range,name) reserves a region of I/O ports, starting with port, and marks them as allocated. • release_region(start,n) releases allocated port ranges. • check_region(port,range) checks if the range has already been taken.

  10. Helper Functions • request_irq(irq, handler, flags, device, dev_id) reserves and initializes the interrupt line with number irq. • free_irq(irq,dev_id) releases a reserved interrupt.

  11. Opening a Network Adapter • ifconfig  ioctl()  dev_open() in dev.c  [ devopen() ]  net_open() in driver.c • lines 335-367 in isa-skeleton.c • For modern adapters that support dynamic interrupt allocation, IRQ and DMA are reserved in net_open(). • The reference count is increased using MOD_INC_USE_COUNT. • The adapter is initialized by writing a specific value to a hardware register (I/O port) of the adapter. • netif_start_queue(dev) sets devstate to LINK_STATE_START.

  12. Closing a Network Adapter • Lines 557-582 in isa-skeleton.c • netif_stop_queue() sets devstate to LINK_STATE_OFF. • Disable DMA and free the DMA channel (set in devdma). • Free the IRQ (set in devirq). • Release the physical interrupt line. • Decrement the reference count using MOD_INC_USE_COUNT.

  13. Transmitting Data Packets • dev_queue_xmt  [ devhard_start_xmit ]  net_start_xmt. • net_send_packet(skb,dev) in lines 374--434 • devhard_start_xmit(skb,dev) • The ring buffer of modern network adapters usually consists of 16-64 pointers to socket buffers. • Before the call, netif_queue_stopped(dev) has been used to make sure that there is at least one free pointer in the ring buffer. • To send a packet, skb, the pointer to the skb is inserted into the ring buffer.

  14. Transmitting Data Packets • devtrans_start = jiffies • After the insertion, one needs to check for whether or not there are more free buffers. If not, invoke netif_stop_queue(dev). • The socket buffer remains in the ring buffer until the network adapter notifies that the packet has been transmitted via an interrupt. • In the interrupt-handling routine, the socket buffer will be removed from the ring buffer and freed via dev_kfree_skb().

  15. Receiving Packets/Control Information • A network adapter uses interrupts and its driver-specific interrupt-handling routine to communicate with the kernel. • There are three cases in which a network adapter will use an interrupt: • Receiving a data packet • Acknowledging a packet transmission • Notifying an error.

  16. Cases Under Which Interrupts Are Used dev.c netif_rx driver.c net_error net_tx net_rx Receiving a packet Completing a transmission process Error condition net_interrupt

  17. Receiving Packets/Control Information • Example: net_interrupt() in lines 476--503 • The status is read from the state register to determine the case. • If a packet is received, net_rx() is called. • If the packet transmission is completed, • the interrupt handling routine net_tx() is called • the statistics are updated • netif_wake_queue(dev) is called to resume passing packets from the upper layer (i.e., LINK_STATE_OFF is deleted from devstate) and to trigger the NET_TX software interrupt. • If an error has been reported, update the error statistics.

  18. Receiving Packets/Control Information • net_tx() (lines 436-470)is part of the interrupt handling routine, andis invoked when a network adapter acknowledges transmission. • A spin lock is set to prevent parallel access to the net_local structure. • The network adapter is repeatedly asked which packets have been sent. For packets that are sent, dev_kfree_skb_irq(skb) is used to free the socket buffer. • If dev state == LINK_STATE_OFF (checked via netif_queue_stopped(dev)) and the ring buffer is not full, then netif_wake_queue(dev). • The spin lock is released.

  19. Receiving Data Packets • net_rx() (lines 506-555) • The status of a received packet is verified from specific hardware registers. • If errors occur, the statistics is collected in the net_device_stats structure (as part of the data structure pointed to by dev priv) • Otherwise, the socket buffer is created via dev_alloc_skb(pkt_len), and the packet is transferred to the packet data area of the skb. • netif_rx(skb) places the socket buffers in the input queue and completes the interrupt handling. • The various statistics are updated.

  20. Receiving Data Packets .. p8022_rcv arp_rcv ip_rcv ETH_P_802_2 dev.c net_rx_action do_softirq Scheduler softnet_data[cpun].input_pkt_queue CPU1 CPU2 dev.c netif_rx eth_type_trans() driver.c dev_alloc_skb() net_interrupt

  21. Problems in Transmitting Packets • During the registration of a network device (register_netdevice()) • The watchdog timer dev watchdog_timer is initialized (with the handling routine set to dev_watchdog()) in the function dev_watchdog_init(). • Upon timeout, dev_watchdog() checks if the network device is active, and if (netif_queue_stopped(dev) && (jiffies – dev trans_start > devwatchdog_timeo). • If the above condition holds, devtx_timeout() (lines 301-325) is called to reset and reinitialize the network adapter.

More Related