首页 > 代码库 > 网卡驱动
网卡驱动
Platform架构的驱动程序便于移植和管理
易变得内容都放在了device
Driver如果需要使用这些易变得内容,统统从device获得。
-------
网卡设备驱动
1.内核中关于网卡设备相关的框架
网卡设备驱动工作于网络接口层
1.1核心数据结构:structnet_device{
base_addr I/O基地址
Irq /**/中断号
Net_device_ops /*网卡设备操作函数集合*/
{
Ndo_start_xmit 发送函数
}
Alloc_etherdev(....) //申请net_device空间
Register_netdev(...)注册
Unregister_net_device注销
1.2网卡的数据的收发函数
A) ndo_start_xmit 发送函数
Net_device *dev指定你哪块网卡发送数据 根据 IP
B)接收函数
将网卡芯片中收到数据拷贝到DDRAM,形成一个struct sk_buff结构
然后调用netif_rx(...),驱动程序中的接收工作就算完成了
1.3struct sk_buff()结构,驱动层发送数据,提交数据的基本数据单位
{ *data
}
释放 sk_buff dev_free_skb(....)
申请 dev_alloc_skb(...)
有一块网卡在内核中就需要实例化一个struct net_device
struct net_device {
/*
* This is the first field of the "visible" part of this structure
* (i.e. as seen by users in the "Space.c" file). It is the name
* of the interface.
*/
charname[IFNAMSIZ];
struct pm_qos_request_list pm_qos_req;
/* device name hash chain */
struct hlist_nodename_hlist;
/* snmp alias */
char *ifalias;
/*
*I/O specific fields
*FIXME: Merge these and struct ifmap into one
*/
unsigned longmem_end;/* shared mem end*/
unsigned longmem_start;/* shared mem start*/
unsigned longbase_addr;/* device I/O address*/
unsigned intirq;/* device IRQ number*/
/*
*Some hardware also needs these fields, but they are not
*part of the usual set specified in Space.c.
*/
unsigned longstate;
struct list_headdev_list;
struct list_headnapi_list;
struct list_headunreg_list;
。。。
中的
name
2.虚拟网卡的设备的设备驱动
2.虚拟网卡的设备驱动
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
申请net_device
Xxxx=alloc_etherdev(0);
设置 net_device xx->netdev_ops = &xxxxx_ops;
注册net_device register_netdev
Struct net_device_ops xxxxx_ops =
{
进一步初始化
.ndo_init =xxxx,
.ndo_open = xxxx_open,
.ndo_start_xmit =xxxxx_xmit,
};
Int xxxx_init(struct net_devicer *dev)
{
/*和以太网相关的进一步初始化
ether_setup();
strcpy(dev->name,“xxxxx”)
}
int xxxx_open(struct net_devicer *dev)
{}
int xxxxx_xmit(struct sk_buff *skb, struct net_device *dev)
{
printk();
/* 通过硬件发送数据*/
/* 释放传入的skb空间*/
dev_kfree_skb();
}
注销unregister_netdev
Free_netdev()
模块安装完后ifconfig -a 会有个 “”名字
ifconfig xxx(名字) IP地址
示例代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Songmao");
#define NETDEV_NAME "eth_first"
static struct net_device *virtua_card;
static int virtua_card_init(struct net_device *dev)
{
printk(KERN_INFO"Netdriv:Entry virtua_card_init");
ether_setup(dev);
strcpy(dev->name,NETDEV_NAME);
return 0;
}
static int virtua_card_open(struct net_device *dev)
{
printk(KERN_INFO"Netdriv:Entry virtua_card_open");
return 0;
}
static int virtua_card_stop(struct net_device *dev)
{
printk(KERN_INFO"Netdriv:Entry virtua_card_stop");
return 0;
}
struct net_device_ops virt_netdev_ops = {
.ndo_init = virtua_card_init,
.ndo_open = virtua_card_open,
.ndo_stop = virtua_card_stop,
};
static int __init init_netdriv(void)
{
int ret = 0;
printk(KERN_ERR"Netdriv:Entry netdriv ...");
virtua_card = alloc_etherdev(0);//0 表示 100字节+0字节
if(virtua_card==NULL)
{
printk(KERN_ERR"Netdriv:Fail for alloc_etherdev");
return -1;
}
printk(KERN_INFO"Netdriv:Success for alloc_etherdev");
virtua_card->netdev_ops = &virt_netdev_ops;
virtua_card->dev_addr[0] = 0x08;
ret = register_netdev(virtua_card);
if(ret<0)
{
printk(KERN_ERR"Netdriv:Fail for register_netdev ");
goto fail_register_netdev;
}
printk(KERN_INFO"Netdriv:Success for register_netdev ");
return 0;
fail_register_netdev:
free_netdev(virtua_card);
return 0;
}
static void __exit exit_netdriv(void)
{
printk(KERN_INFO"Netdriv:Entry exit_netdriv");
unregister_netdev(&virtua_card);
free_netdev(virtua_card);
}
module_init(init_netdriv);
module_exit(exit_netdriv);
3.分析硬件
3.1DM9000芯片datasheet
1)读芯片手册
10M/100
8bit 16bit?
16k SRAM TX SRAM 3K RX SRAM 13K
片选
CMD (高电平。。。。低电平。。。)
INT
EECK 高 INT低有效 反之。。。
EECS 高电平 8bit 低电平16bit
寄存器的每个bit位的意义?
怎么往DM9000内部寄存器TCR(0X02) 写入0x55
0x02??是啥?是index ,data是0x55 他们都是通过SD端口进去的,通过CMD来区分 保证片选被选中(CS#为低电平即选中bank地址),先CMD为低电平 地址总线的bit2此时为0 数据总线 0x02
即: volatile unsigned int *p=0xxxxxx
*p=0x02
送数据到DM9000
数据总线 0xxxxx
地址总线 0xxxxxx
片选CMD ADD高电平
第九章 数据收发
发送数据过程:把要发送写入TX SRAM(DMA)
设置要发送数据的长度 0xfc 0xfd
control reg bit 1
3.2硬件原理图
1)DM9000的sd0~sd15连接到了CPU的哪里
2) CMD 连接到CPU哪去了(addr bus bit)
3)CS# 连接到CPU哪去了 bank:一个bank就是128M空间
4) INT 连接CPU的中断为。。。
5) EECS (NC无连接 ) 低电平 16 bit 模式
6) EECK 低电平) INT为高电平有效
4)
3.3和CPU相关的接口
1)SM9000挂在bankn上了,在他地址范围内,当你cpu地址总线上的值是那个范围内都会导致XM0csn(n)为低电平,也就是选中其中的片选
4,内核中自带网卡驱动程序是如何完成的,移植网卡驱动需要注意哪些内容
找到内核中DM9000的驱动程序
的driver/net/ 变量CONFIG_DM9000 dm9000.c
DM9000网卡驱动程序是按照平台总线架构完成的
总线
设备
设备驱动 dm9000.c
1)框架
2)发送函数
3)
5.移植网卡驱动问题 resource(platform_device)
你使用的物理地址
使用的中断号
中断的有效状态
位宽
6.内存控制器的配置
1)外接设备的位宽
SROM
2)读写时序
SROM_BCx
本文出自 “毛散人” 博客,请务必保留此出处http://songmao.blog.51cto.com/11700139/1880187
网卡驱动