【驱动】DM9000网卡驱动分析

Preface

内核源码版本:linux-2.6.18

网卡驱动·linux内核网络分层结构:

DM9000芯片

DM9000是一款高度集成低功耗快速以太网处理器,该芯片集成了MAC和PHY。DM9000可以和CPU直接连接,支持8位、16位和32位数据总线宽度。该芯片支持10M和100M自适应以太网接口,内部有16K的FIFO以及4K双字节SRAM,支持全双工工作。

DM9000内部还集成了接收缓冲区,可以在接收到数据的时候把数据存放到缓冲区中,链路层可以直接把数据从缓冲区取走。

网卡驱动程序框架

在一个网络驱动程序中,一般都提供了一个platform_driver结构变量。

platform_driver结构包括了网卡驱动的相关操作函数,通过platform_driver_register()函数注册到内核设备驱动列表。

内核会根据驱动程序中设备描述设置网卡的中断和定时器,并且在网络数据包到来的时候调用网卡对应的处理函数。

通常,网卡需要向内核提供下面几个接口函数:

probe:加载网卡驱动的时候执行,主要用于初始化网卡硬件接口,设置网络接口函数;

remove:卸载网卡驱动的时候执行该函数,用于从系统中注销网络接口函数;

suspend:在挂起网络设备的时候被调用;

resume:在恢复网络设备的时候被调用。

网络设备驱动主要是按照内核网络数据包处理流程中用到的数据结构,设置对应的处理函数供内核使用。

DM9000网卡驱动主要数据结构

DM9000网卡驱动位于driver/net/dm9000.c文件,有两个主要的数据结构dm9000_driver和board_info。其中,dm9000_driver是platform_driver结构。

static struct platform_driver dm9000_driver = {.driver = {.name = “dm9000”, //网卡名称.owner = THIS_MODULE,},.probe = dm9000_probe, //加载驱动函数.remove = dm9000_drv_remove, //删除驱动函数.suspend = dm9000_drv_suspend, //挂起驱动函数.resume = dm9000_drv_resume, //恢复驱动函数};

dm9000_probe()函数在加载驱动的时候被内核调用,用于检测mqh上设备并且分配资源,设置网络接口控制器;

dm9000_drv_remove()函数在卸载驱动的时候被调用,用于释放网卡驱动占用的资源;

dm9000_drv_suspend()函数在挂起网卡的时候被调用,该函数会暂时删除网络口;

dm9000_drv_resume()函数在恢复网卡接口时被调用,该函数重新加载网络接口。

DM9000网卡驱动还设置了供DM9000网络控制芯片使用的 board_info结构

/* Structure/enum declaration ——————————- */typedef struct board_info {void __iomem *io_addr;/* Register I/O base address *///控制寄存器地址void __iomem *io_data;/* Data I/O address *///数据寄存器地址u16 irq;/* IRQ *///中断号,在嵌入式系统常常无效u16 tx_pkt_cnt;//已发送数据包个数u16 queue_pkt_len;//数据包发送队列中的数据包个数u16 queue_start_addr;//数据包发送队列的起始地址u16 dbug_cnt;u8 io_mode;/* 0:word, 2:byte */u8 phy_addr;//网卡物理地址void (*inblk)(void __iomem *port, void *data, int length);void (*outblk)(void __iomem *port, void *data, int length);void (*dumpblk)(void __iomem *port, int length);struct resource*addr_res; /* resources found */struct resource *data_res;struct resource*addr_req; /* resources requested */struct resource *data_req;struct resource *irq_res;struct timer_list timer;struct net_device_stats stats;unsigned char srom[128];//网络控制器内部EEPROM内容spinlock_t lock;struct mii_if_info mii;u32 msg_enable;} board_info_t;

board_info结构存放在 net_device结构的私有数据部分,DM9000驱动的接口处理函数会使用该结构访问网络控制芯片。

在 board_info结构中,

io_addr和 io_data成员变量存放了控制寄存器和数据寄存器地址;

tx_pkt_cnt记录了发送数据包个数;

queue_pkt_len记录了发送队列中数据包个数;

queue_start_addr记录了数据包发送队列的起始地址;

phy_addr是网卡的物理地址;

srom是一个组,记录了DM9000网络控制芯片内部EEPROM的内容。

加载驱动程序

在dm9000.c文件中使用模块加载宏和卸载宏设置了模块的初始化函数dm9000_init()和卸载函数dm9000_cleanup()。

static int __initdm9000_init(void){printk(KERN_INFO “%s Ethernet Driver\n”, CARDNAME); //打印模块启动信息return platform_driver_register(&dm9000_driver); /* search board and register */ //调用驱动注册函数}static void __exitdm9000_cleanup(void){platform_driver_unregister(&dm9000_driver); //调用驱动卸载函数}module_init(dm9000_init); //设置模块启动函数module_exit(dm9000_cleanup); //设置模块卸载函数

设置好驱动函数的初始化后,在启动的时候会注册 dm9000_driver结构到内核,内核会调用 dm9000 driver结构中的 probe函数成员,也就是调用 dm9000_probe()函数设置网卡驱动。

函数执行过程如下。

步骤一

函数首先是分配 board_info结构占用的私有资源,在程序中使用 alloc_etherdev()函数分配网卡驱动使用的私有资源。

关于爱情的句子:情不知所起,一往而情深。

【驱动】DM9000网卡驱动分析

相关文章:

你感兴趣的文章:

标签云: