tag 标签: 网卡驱动

相关博文
  • 热度 18
    2012-8-31 14:50
    1527 次阅读|
    2 个评论
    3. 6   参数设置和统计数据 当用户调用ioctl()函数,并制定SIOCSIFHWADDR命令时,意味着要设置这个设备的MAC地址。设置网络设备的MAC地址可以用如下模板。? S tatic int set_mac_address (struct  net_device  *dev,void *addr) { I f(netif_running(dev)) R eturn  – Ebusy; X xx_set_mac(dev,addr); R eturn 0; } 上述程序首先用netif_running()宏判断设备是否正在运行,如果是,则意味着设备忙,此时不允许设置MAC地址;否则,条用xxx_set_mac()函数在网络适配器硬件内写入新的MAC地址。这个要求设备在硬件上支持MAC地址的修改,而实际上,许多设备并不提供修改MAC地址的接口。 驱动程序还应提供get_stats()函数用以向用户反馈设备状态和统计信息,该函数返回的是一个net_device_stats结构体(include/linux/netdevice.h)。 S truct net_device_stats { U nsigned long rx_packets; U nsigned long tx_packets; U nsigned long rx_bytes; U nsigned long tx_bytes; U nsigned long rx_errors; U nsigned long tx_errors; } 3. 7   网络设备注册与注销 int register_netdev(struct  net_ device  *dev); void unregister_netdev(struct  net_ device  *dev); 3. 8   总结 L inux网络设备驱动体系结构的层次化设计实现了对上层协议接口的统一和硬件驱动的对下层多样化硬件设备的可适应。程序员需要完成的工作集中在设备驱动功能层,网络设备接口层net_device结构体的存在将千变万化的网络设备得以抽象,使得设备功能层中除数据包接收以外的主体都由填充 net_device 的属性和函数指针完成。 在linux网络子系统和设备驱动中,套接字缓冲区 sk_buff 发挥者巨大的作用,时所有数据流动的载体。网络设备驱动和上层协议之间也依赖此结构进行数据包交互,因此,我们要特别牢记它的操作方法。
  • 热度 20
    2012-8-31 14:47
    1365 次阅读|
    0 个评论
    3. 4   数据接收流程 网络驱动程序实现了两种模式接收数据包:中断和轮询。? 大多数驱动程序实现了中断驱动技术,中断处理函数判断中断的类型,如果为接收中断,则读取接收到的数据,分配一个保存数据包的 sk_buff 套接字缓冲区,将接收到的数据复制到缓冲区,并调用netif_rx()函数将数据包交给上层协议。 netif_rx()里数据放入处理队列然后返回,真正的处理是在中断返回以后,这样可以减少中断时间。调用netif_rx()以后,驱动程序就不能再存取数据缓冲区skb。   S tatic void xxx_interrupt(int irq,void *dev_id,struct pt_regs *regs) { … switch(status IRQ_EVENT_MASK) { C ase IRQ_EVENT_MASK: X xx_rx(dev);break; … } } S tatic void xxx_rx(struct xxx_device *dev) { …   L ength = get_rev_len( … ); S kb = dev_alloc_skb(length + 2); S kb_reserve(skb,2); S kb - dev = dev; I nsw(ioaddr + rx_frame_port,skb_put(skb,length),length1); I f(length 1) S kb-data  = inw(ioaddr+rx_frame_port); S kb-protocal = eth_type_trans(skb_dev); N etif_rx(skb); D ev-last_rx = jiffies; … } 3. 5   网络连接状态 网络设备驱动程序中往往设置一个定时器来对链路状态进行周期性的检查。当定时器到期之后,在定时器处理函数中读取物理设备的相关寄存器获得载波状态,从而更新设备的连接状态。 有的驱动程序也通过中断寄存器来检查链路状态的变化,网络适配器硬件电路可以检测出链路上是否有载波,载波反映了网络的连接是否正常。网络设备驱动可以通过netif_carrier_on()和netif_carrier_off()函数改变设备的连接状态,如果驱动检测到连接状态发生变化,也应该以netif_carrier_on()和netif_carrier_off()函数显示的通知内核,而函数netif_carrier_ok()可以用于向条用着返回链路上的载波信号是否存在。 V oid netif_carrier_on(struct  net_device  *dev); V oid netif_carrier_off(struct  net_device  *dev); V oid netif_carrier_ok(struct  net_device  *dev);  
  • 热度 17
    2012-8-31 14:44
    1492 次阅读|
    0 个评论
    2. 4   设备驱动功能层 Net_device 结构体的成员(属性和函数指针)需要被设备驱动功能层的具体数值和函数赋予,应编写相应的设备驱动功能层的函数,这些函数形如 xxx_open(),xxx_stop(), Xxx_stop(),xxx_tx(),xxx_get_stats(),xxx_tx_timeout 等。 由于网络数据包的接收可由中断引发,设备驱动的功能层中另一个主题部分将是中断处理函数,它负责读取硬件上接收的数据包并传给上层协议,可能包含 xxx_interrupt() 和 xxx_rx() 函数,前者主要完成中断类型判断等基本的工作,后者则需完成数据包的生成和递交上层等复杂工作。 2. 5   网络设备与媒介层 网络设备与媒介层直接对应于实际硬件设备。 直接操作硬件寄存器。   三 . 网络驱动程序的基本方法 网络设备做为一个对象,提供一些方法供系统访问。正是这些有统一接口的方法,  掩蔽了硬件的具体细节,让系统对各种网络设备的访问都采用统一的形式,做到硬件  无关性,下面解释最基本的方法。   3 .1 初始化 驱动程序必须有一个初始化方法。在把驱动程序载入系统的时候会调用这个初始化程序。它做以下几方面的工作。 检测设备 ,在初始化程序里你可以根据硬件的特征检查硬件是否存在,然后决定是否启动这个驱动程序; 配置和初始化硬件 ,在初始化程序里你可以完成对硬件资源的配置。配置或协商好硬件占用的资源以后,就可以向系统申请这些资源。接下来你要 初始化device 结构中的变量。最后,你可以让硬件正式开始工作。 dev-irq  = KSZ8842_IRQ; dev-base_addr  = KSZ8842_BASE; dev-open = net_open; dev-stop = net_stop; dev-tx_timeout = net_tx_timeout; dev-watchdog_timeo = 3*HZ; dev-hard_start_xmit  = net_hard_start_xmit; dev-set_mac_address  = net_set_mac_address; dev-ethtool_ops = net_ethtool_ops; 3.2  打开 与释放 在传送数据包到达接口之前,内核必须打开接口并赋予地址。例如内核在响应ifconfig命令时打开或关闭一个接口。 内核响应ifconfig时,首先通过ioctl(SIOCSIFADDR)赋予地址,然后通过ioctl (SIOCSIFFLAGS)打开接口,这些都由内核来执行,与设备无关,只是后一个命令会条用设备的open方法 网络设备的打开函数需要完成如下工作: 1、使能设备使用的硬件资源,申请I/O区域、中断和DMA等。 2、激活设备发送队列:void netif_start_queue(struct net_device *dev); I nt xxx_open(struct net_device *dev) { R et = request_irq(dev-irq, xxx_interrrupt,0,dev-name,dev); … N etif_start_queue(dev); … }  
  • 热度 13
    2012-8-31 14:36
    1330 次阅读|
    0 个评论
    2. 2  网络 协议接口层 网络协议接口层主要给上层协议提供透明的数据发送和接收的接口。 数据包发送: Dev_queuex_xmit (struct sk_buff  *skb); 数据包接收: I nt netif_rx (struct sk_buff  *skb); Sk_buff  套接字缓冲区  用于在 linux 网络子系统中的各层之间传递数据。当发送数据包时, linux 内核网络处理模块必须建立一个包含要传输的数据包的 sk _ buff ,然后将 sk _ buff 递交给下层,各层在 sk_buff 中添加不同的协议头直至交给网络设备发送。同样,当网络设备从网络媒介上接收到数据包后,它必须将接收到的数据转换为 sk_buff 数据结构并传递给上层,各层剥去相应的协议头直至交给用户。 套接字缓冲区的分配 : Struct sk_buff  *alloc_skb(unsigned int len,int priority); Struct sk_buff  * dev_alloc_skb (unsigned int len,int priority); 套接字缓冲区的释放 : Void kfree_skb(struct sk_buff  *skb); 内核内部使用 Void  dev_kfree_skb (struct sk_buff  *skb); 非中断上下文 Void dev_kfree_skb_irq(struct sk_buff  *skb); 中断上下文 Void dev_kfree_skb_any(struct sk_buff *skb); 前两项均可 套接字缓冲区的指针移动 : 1、put操作--tail指针下移,增加len值,在尾部添加数据 Unsigned char * skb_put (struct sk_buff *skb,unsigned int len); Unsigned char *__skb_put(struct sk_buff *skb,unsigned int len); 2、push操作—data指针上移,增加len值,发送时在头部添加数据 Unsigned char *skb_push(struct sk_buff *skb,unsigned int len); Unsigned char *__skb_push(struct sk_buff *skb,unsigned int len); 3、pull操作—data指针下移,减小len值 Unsigned char *skb_pull(struct sk_buff *skb,unsigned int len); 4、reserve操作—data和tail指针下移 Void skb_reserve(struct sk_buff *skb,unsigned int len); 2. 3  网络 设备接口层 net_device 结构体在内核中指代一个网络设备,网络设备驱动程序只需通过 填充net_device的具体成员并注册 ,即可实现硬件操作函数与内核的挂接。 net_device包含网络设备的属性描述和操作接口。在编写网络设备驱动程序时,只需要了解其中的一部分。 全局信息: char name ; Int (*init)(struct net_device *dev); 硬件信息: U nsigned long base_addr; U nsigned long irq; 设备操作函数:int (* open )/(* stop )(struct net_device *dev); I nt (* hard_start_xmit )(struct  sk_buff  *skb,struct net_device *dev); V oid (* tx_timeout )(struct net_device *dev) S truct net_device_stats* (* get_stats )(struct net_device *dev);
  • 热度 11
    2012-8-31 14:33
    2431 次阅读|
    0 个评论
    Linux 网卡驱动程序 一.  Linux系统设备驱动程序概述   1.1  Linux 设备驱动程序分类  与字符设备不同,网络设备并不对应于 /dev 目录下的文件,应用程序最终使用套接字成与网络设备的接口。因而在网络设备身上并不能体现出“一切都是文件”的思想。      Linux系统的设备分为 字符设备 (char device) ,块设备 (block device) 和网络设备 (network device) 三种 。字符设备是指存取时没有缓存的设备 (必须串行顺序访问,鼠标、键盘、触摸品、 LED 等) 。块设备的读写都有缓存来支持,并且块设备必须能够随机存取(random access),字符设备则没有这个要求。块设备主要包括硬盘软盘设备,CD-ROM等。一个文件系统要安装进入操作系统必须在块设备上。  Linux的网络系统主要是基于BSD unix的 socket 机制 。在系统和驱动程序之间定义有专门的数据结构 ( sk_buff ) 进行数据的传递 。 1.2  以太网接口 以太网接口由MAC和PHY组成。 以太网MAC由IEEE-802.3以太网标准定义,实现了数据链路层。常用的MAC支持10Mbit/s或100Mbit/s两种速率。 以太网PHY则实现物理层功能IEEE-802.3标准定义了以太网PHY,它符合IEEE-802.3K中用于10BaseT和100BaseTX的规范。 MAC和PHY之间通常采用MII连接,它是IEEE-802.3定义的以太网行业标准,包括1个数据接口和1个MAC和PHY之间的管理接口。数据接口包括分别用于发送和接收的两条独立信道,每条信道都有自己的数据、时钟和控制信号,MII数据接口总共需要16个信号,MII管理接口包含两个信号,分别是时钟和数据,通过管理接口,上层能监视和控制PHY。   以太网接口原理图如下图所示,以太网隔离变压器时以太网收发芯片与连接器之间的磁性组件,在其两者之间起着信号传输、阻抗匹配、波形修复、信号杂波抑制和高电压隔离作用。 二.Linux系统网络设备驱动程序  2.1 网络驱动程序的结构   网络协议接口层:向网络层协议提供统一的数据接口,使得上层协议独立于具体设备。 网络设备接口层: struct net_device 描述具体网络设备属性和操作。 设备驱动功能层:驱动硬件完成相应的收发数据过程,具体和硬件相关。 网络设备与媒介层:具体的硬件实体,包括网络适配器和具体的传输媒介。 在设计具体的网络设备驱动程序时,我们要完成的主要工作是编写设备驱动功能层的相关函数以填充 net_device 数据结构的内容并将 net_device 注册入内核。
相关资源