Escolar Documentos
Profissional Documentos
Cultura Documentos
Device Drivers
COMS W6998
Spring 2010
Erich Nahum
E.g., dev->netdev_ops->ndo_start_xmit
Device Interfaces
Higher Protocol Instances
dev.c
napi_schedule
dev_open
dev_queue_xmit
net_device_ops
dev_close
Network devices
(adapter-independent)
Network devices
interface
netdev_ops->ndo_open
netdev_ops->ndo_start_xmit
netdev_ops->ndo_stop
Abstraction from
Adapter specifics
pcnet32.c
pcnet32_interrupt
pcnet32_open
pcnet32_start_xmit
pcnet32_stop
Network driver
(adapter-specific)
Process
context
Softirq
interrupt
context
Softnet
Driver
Memory
mapped
register
reads/
writes
Interrupts
Descriptors
contain
pointers,
status bits
Driver
allocates
packet
buffers
TX
Descriptor
Ring
Packet
Buffer
Packet
Buffer
Packet
Buffer
SendErr
Sent
Send
Send
Send
Packet
Buffer
Packet
Buffer
Packet
Buffer
Free
RX
Descriptor
Ring
TXQ
Tail
RXQ
Head
TXQ
Head
Free
Free
Free
Free
RecvOK
RecvOK
RcvErr
RecvCRC
RecvOK
RXQ
Tail
Free
Packet
Buffer
Packet
Buffer
Packet
Buffer
Packet
Buffer
Packet
Buffer
Packet
Buffer
Packet
Buffer
Packet
Buffer
NIC IRQ
dev.c
napi_schedule
hard
IRQ
pcnet32.c
pcnet32_interrupt
irq/handle.c
__do_IRQ
interrupt
HW interrupt invokes
__do_IRQ
__do_IRQ invokes each
handler for that IRQ:
action->handler(irq,
action->dev_id);
pcnet_32_interrupt
ip_rcv
..
ipx_rcv
dev.c
ptype_base[ntohs(type)]
soft
IRQ
netif_receive_skb
pcnet32.c
pcnet32_poll
dev.c
softirq.c
net_rx_action
do_softirq
Scheduler
arp_rcv
ip_rcv
..
ipx_rcv
dev.c
ptype_base[ntohs(type)]
soft
IRQ
netif_receive_skb
pcnet32.c
dev.c
softirq.c
netif_receive_skb:
pcnet32_poll
net_rx_action
do_softirq
Scheduler
A protocol that
receives only packets
with the correct packet
identifier
16
ptype_all
packet_type
type: ETH_P_ARP
dev: NULL
func
...
list
packet_type
type: ETH_P_IP
dev: NULL
func
...
list
...
packet_type
packet_type
type: ETH_P_ALL
dev
func
...
list
arp_rcv()
packet_type
ip_rcv()
A protocol that
receives all packets
arriving at the
interface
packet_type
type: ETH_P_ALL
dev
func
...
list
Transmission Overview
Transmission
is surprisingly complex
Each net_device has 1 or more tx queues
Each queue has a policy associated with it
struct Qdisc
Polices can be simple
In
Queuing Ops
enqueue()
Enqueues a packet
dequeue()
Returns a pointer to a packet (skb) eligible for
sending; NULL means nothing is ready
pfifo 3 band priority fifo
dev_queue_xmit
sched_generic.c
dev_queue_xmit
dev->qdisc->pfifo_fast_enqueue
__qdisc_run
Syscall
or
soft
IRQ
qdisc_restart
dev->qdisc->pfifo_fast_dequeue
dev.c
dev->q->enqueue(pfifo)
dev_hard_start_xmit
pcnet32.c
pcnet32_start_xmit
dev_queue_xmit
sched_generic.c
dev->qdisc->pfifo_fast_enqueue
__qdisc_run
Syscall
or
soft
IRQ
__qdisc_run
Qdisc_restart
qdisc_restart
dev->qdisc->pfifo_fast_dequeue
dev.c
pcnet32.c
pcnet32_start_xmit
Dequeues a packet
Finds tx queue
Calls
dev_hard_start_xmit
dev_hard_start_xmit
dev_hard_start_xmit
Invokes dev->xmit
Frees the skb
pcnet32_start_xmit
do_softirq
sched_generic.c
soft
IRQ
qdisc_restart
dev->qdisc->pfifo_fast_dequeue
dev.c
dev_hard_start_xmit
pcnet32.c
pcnet32_start_xmit
net_tx_action is the
action for
NET_TX_SOFTIRQ
net_tx_action
Frees packets posted to
completion queue
Invokes __qdisc_run on
all output qdiscs if possible
Sets bit in qdisc to run
again if necessary
net_tx_action
__qdisc_run
do_softirq invoked