网络设备
网络驱动结构
从上到下划分4层:
网络协议接口层
使上层协议独立于具体设备
网络设备接口层
向协议接口层提供统一的用于描述具体网络设别属性和操作的结构体 net_device
设备驱动功能层(提供实际功能)
net_device 的具体成员
网络设备与媒介层
完成数据包发送和接收的物理实体
网络设备初始化
- 硬件准备工作,检查设备是否存在和硬件资源
- 对 net_device 数据和函数指针初始化
- 获得设备的私有信息指针并初始化各成员值
网络设备打开与释放
open
- 使能设备硬件资源,申请IO区域、中断和DMA通道
- 调用Linux内核提供的 netif_start_queue() 函数,激活设备发送队列
release
- 调用内核提供的 netif_stop_queue() 函数
- 释放资源
数据发送流程
- 获取sk_buff数据包的数据和长度
- 有效长度小于以太网冲突检测所要求数据帧最小长度ETH_ZLEN,则补0
- 设置硬件寄存器,驱动设备进行数据发送
数据接收流程
- 设备接收数据的主要方法是由中断引发中断处理函数
- NAPI兼容的驱动,需先disable interrupt再调用NAPI接收pkt
网络状态
- 网络硬件电路可以检测网络连接是否正常
- 驱动程序可采取一定手段检测报告链路状态,中断或定时
网络设备驱动流程
struct net_device_stats(struct net_device *dev)
{
...
return &dev->stats;
}
static int xxx_config(struct net_device *dev, struct ifmap *map)
{
if (netif_running(dev))
return -EBUSY;
/* 假设不允许改变IO地址 */
if (map->base_addr != dev->base_addr) {
printk("xxx: Can't change I/O address\n");
return -EOPNOTSUPP;
}
/* 假设允许改变 IRQ */
if (map->irq != dev->irq)
dev->irq = map->irq;
return 0;
}
static int set_mac_address(struct net_device *dev, void *addr)
{