网络设备被抽象为统一的接口供系统访问,应用层对各种网络设备的访问都采用统一的形式,也就是套接字形式,它具有硬件无关性。
网络设备驱动程序最重要的结构是net_device。该结构保存一个网络接口的重要信息,是网络驱动程序的核心。net_device结构非常庞大,下面介绍该结构中几个最重要的成员:
网络设备注册和注销函数原型如下:
int register_netdev(struct net_device*dev);
void unregister_netdev(struct net_device*dev);
网络设备操作结构net_device_ops是网络子系统提供给网络设备驱动的接口。
网络设备驱动程序与网络子系统直接交互。两者交互的基本单位是sk_buff结构。图13-1为网络数据的流向图。
图13-1 网络数据的流向
网络子系统向设备驱动下发数据要通过dev_queue_xmit函数,而dev_queue_xmit函数会调用网络设备的netdev_ops->ndo_start_xmit接口。
int dev_queue_xmit(struct sk_buff*skb);
网络设备收到数据后都会产生一个中断。在中断处理程序中驱动程序会申请一块sk_buff,把从硬件读出的数据放置到申请好的缓冲区里,接下来填充sk_buff中的一些成员,最后驱动程序调用netif_rx函数把数据传送给协议层。netif_rx函数将数据放入处理队列然后返回,真正的处理是在中断返回以后,这样可以减少中断时间。
int netif_rx(struct sk_buff*skb);
网络设备驱动程序主要功能是实现netdev_ops结构中的函数接口。
(1)ndo_open接口
int(*ndo_open)(struct net_device*dev);
ndo_open接口在网络设备被激活的时候被调用。它主要完成资源和中断的申请以及DMA的注册等工作。使用ifconfig命令可以激活网络设备。
(2)ndo_start_xmit接口
netdev_tx_t(*ndo_start_xmit)(struct sk_buff*skb,struct net_device*dev);
ndo_start_xmit接口用来将网络子系统发来的数据通过网卡发送到物理网络。net_device结构中没有读数据接口,读数据一般在网卡中断中处理。(www.xing528.com)
(3)ndo_get_stats接口
struct net_device_stats*(*ndo_get_stats)(struct net_device*dev);
ndo_get_stats函数返回一个net_device_stats结构,该结构保存了驱动所管理的网络设备接口的详细的流量与错误统计信息:
(4)ndo_do_ioctl接口
int(*ndo_do_ioctl)(struct net_device*dev,struct ifreq*ifr,int cmd);
Linux下有一些特定的socket ioctl,定义在sockios.h头文件中。网络子系统一般已经实现了这些IOCTL命令(见/driver/net/core/dev_ioctl.c),也有的命令需要在自定义的驱动程序中实现。常用的IOCTL命令有:
例13.1 使用SIOCGIFHWADDR获取MAC地址
本例介绍如何使用SIOCGIFHWADDR获取网卡MAC地址。参考代码如下:
ndo_do_ioctl函数一般用来实现驱动程序私有的IOCTL命令,命令的类型在
SIOCDEVPRIVATE和SIOCDEVPRIVATE+15之间。
(5)ndo_set_mac_address接口
int(*ndo_set_mac_address)(struct net_device*dev,void*addr);
该接口用来设置网络设备的MAC地址,MAC地址就存放在addr参数中。
(6)ndo_stop接口
int(*ndo_stop)(struct net_device*dev);
ndo_stop接口在网卡状态由up转为down时被调用,一般用来释放资源。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。