题记:以开启CONFIG_RAETH_NAPI宏为例分析,只对网卡驱动的工作流程进行分析,不分析具体的处理过程。主要文件linux-
2.6.36.x/drivers/net/raeth/raether.c和linux-2.6.36.x/net/core/dev.c。
设备启动时,设备注册流程分析:
1、开机启动,操作系统起来时,网卡驱动的初始化函数ra2882eth_init会被执行,ra2882eth_init完成了设备的所有初始化操作。
2、
ra2882eth_init中,调用rather_probe,该函数主要是对网口初始化。首先从flash中读取mac地址,如果读取出错,则自动生
成mac地址,对接口进行设置;然后netif_napi_add被调用,设置napi的结构napi_struct,主要设置
napi->poll = poll;napi->weight = weight;
poll函数是轮询地从缓冲区中读取数据包进行处理,weight则表示待处理的数据包个数(前提是缓冲区中已经缓冲了足够多的数据包),初始值设置为128。
3、
紧接着ra2880_setup_dev_fptable被调用,该函数对设备dev进行设置,包括open、close、ioctl等。open函数先
申请NUM_RX_DESC个skb缓冲区,然后调用request_irq注册网卡的中断处理程序esw_interrupt;然后调用
napi_enable对napi结构状态进行设置
4、最后调用register_netdev注册设备dev。
数据包到达后的处理流程分析:
1、网卡向CPU报告中断,CPU响应,执行ei_interrupt中断处理函数。
2、中断处理函数中调用__napi_schedule,将napi结构添加到&__get_cpu_var(softnet_data)上,__raise_softirq_irqoff(NET_RX_SOFTIRQ);打开NET_RX_SOFTIRQ对应的软中断。
3、
中断返回,执行已注册并开启的软中断处理函数,net_rx_action会被执行。net_rx_action软中断处理函数在
net_dev_init函数中通过open_softirq(NET_RX_SOFTIRQ, net_rx_action);进行注册的。
4、net_rx_action函数中或得到sd=&__get_cpu_var(softnet_data),遍历sd->poll_list,执行已注册的napi结构中的poll函数(也就是之前通过netif_napi_add注册的raeth_clean函数)。
5、raeth_clean函数的工作就是掉从rt2880_eth_recv函数从缓冲区中读取数据包,netif_receive_skb函数进行处理,紧接着就是进入协议栈处理过程了。
NAPI跟旧的API不同之处就是,网卡中断比较频繁时,NAPI能够减少中断次数。如果缓冲区足够大,一次中断中就可处理多个数据包,由weight进行控制。
阅读(5398) | 评论(0) | 转发(0) |