
//注释者: zl
//评论格式: //评论内容
//博客: blog.sina.com.cn/foreveralbum
//日期: 08.5.3
//描述: 注释了代码的几个关键功能,包括初始化,发送和接收数据包等.
//功能运行顺序: 加载模块-> b44_init()-> b44_init_one()-> register_netdev()
//注册后,您可以调用驱动程序来操作设备.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//此驱动程序在/ driver / ssb
中使用ssb代码
#include
#include
#include
#include
#include“ b44.h”
#define DRV_MODULE_NAME“ b44”
#define PFX DRV_MODULE_NAME“: ”
#define DRV_MODULE_VERSION“ 2.0”
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
NETIF_MSG_PROBE | \
NETIF_MSG_LINK | \
NETIF_MSG_TIMER | \
NETIF_MSG_IFDOWN | \
NETIF_MSG_IFUP | \
NETIF_MSG_RX_ERR | \
NETIF_MSG_TX_ERR)
#define B44_TX_TIMEOUT(5 * HZ)
#define B44_MIN_MTU60
#define B44_MAX_MTU1500
#define B44_RX_RING_SIZE512
#define B44_DEF_RX_RING_PENDING200
#define B44_RX_RING_BYTES(sizeof(struct dma_desc)* \
B44_RX_RING_SIZE)
#define B44_TX_RING_SIZE512
#define B44_DEF_TX_RING_PENDING(B44_TX_RING_SIZE-1)
#define B44_TX_RING_BYTES(sizeof(struct dma_desc)* \
B44_TX_RING_SIZE)
#define TX_RING_GAP(BP)\
(B44_TX_RING_SIZE-(BP)-> tx_pending)
#define TX_BUFFS_AVAIL(BP)\
((((BP)-> tx_cons <=(BP)-> tx_prod)?\
(BP)-> tx_cons +(BP)-> tx_pending-(BP)-> tx_prod: \
(BP)-> tx_cons-(BP)-> tx_prod-TX_RING_GAP(BP))
#define NEXT_TX(N)((((N)+1)&(B44_TX_RING_SIZE-1))
#define RX_PKT_OFFSET30
#define RX_PKT_BUF_SZ(1536 + RX_PKT_OFFSET + 64)

#define B44_TX_WAKEUP_THRESH(B44_TX_RING_SIZE / 4)
#define B44_PATTERN_BASE0x400
#define B44_PATTERN_SIZE0x80
#define B44_PMASK_BASE0x600
#define B44_PMASK_SIZE0x10
#define B44_MAX_PATTERNS16
#define B44_ETHIPV6UDP_HLEN62
#define B44_ETHIPV4UDP_HLEN42
静态字符版本[] __devinitdata =
DRV_MODULE_NAME“ .c: v” DRV_MODULE_VERSION“ \ n”;
MODULE_AUTHOR(“费利克斯·菲特考,弗洛里安·希尔默,佩卡·皮蒂卡伊宁,大卫·米勒”);
MODULE_DESCRIPTION(“ Broadcom 44xx / 47xx 10/100 PCI以太网驱动程序”);
MODULE_LICENSE(“ GPL”);
MODULE_VERSION(DRV_MODULE_VERSION);
static int b44_debug = -1;
module_param(b44_debug,int,0);
MODULE_PARM_DESC(b44_debug,“ B44位图调试消息启用值”);
#ifdef CONFIG_B44_PCI
静态const struct pci_device_id b44_pci_tbl [] = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,PCI_DEVICE_ID_BCM4401)}网卡驱动代码,
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,PCI_DEVICE_ID_BCM4401B0)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM,PCI_DEVICE_ID_BCM4401B1)},
{0}
};
MODULE_DEVICE_TABLE(pci,b44_pci_tbl);
静态结构pci_driver b44_pci_driver = {
.name = DRV_MODULE_NAME,
.id_table = b44_pci_tbl,
};
#endif
//关于device_id: PCI设备符合PCI标准. 本节中的所有PCI设备均相同. 每个PCI设备都有一个寄存器来存储配置空间. 此部分的格式相同.
//例如,第一个寄存器始终是制造商编号. 例如,Realtek是10ec,Intel是另一个数字. 这些都是由标准组织等企业应用的,它们肯定是不同的.
//我可以通过配置空间识别制造商和设备编号,无论您使用的是x86还是ppc平台,它们都是相同的标准格式.
//此处b44_ssb_tbl用于匹配配置空间. 如果b44_ssb_tbl与配置空间相同,则表明该驱动程序用于驱动该设备.
静态const struct ssb_device_id b44_ssb_tbl [] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM,SSB_DEV_ETHERNET,SSB_ANY_REV),
SSB_DEVTABLE_END
};
. . . . . .
//超时功能
静态无效b44_tx_timeout(结构net_device * dev)
{
struct b44 * bp = netdev_priv(dev);
printk(KERN_ERR PFX“%s: 发送超时,重置\ n”,
dev->名称);
spin_lock_irq(和bp->锁定);
b44_halt(bp); //终止网卡
b44_init_rings(bp);
b44_init_hw(bp,B44_FULL_RESET);
spin_unlock_irq(和bp->锁定);
b44_enable_ints(bp);
netif_wake_queue(dev); //唤醒网卡等待队列
}
. . . . . . . . . .
//打开设备功能
//此功能通常用于注册所有系统资源,包括IO端口,IRQ DMA等.
static int b44_open(结构net_device * dev)
{
struct b44 * bp = netdev_priv(dev); //获取网卡的私有数据地址
int err;

err = b44_alloc_consistent(bp,GFP_KERNEL);
如果(错误)
出去;
napi_enable(&bp-> napi); // napi通过轮询接受数据包,请参见设备驱动程序p518
b44_init_rings(bp);
b44_init_hw(bp,B44_FULL_RESET); //做硬件初始化
b44_check_phy(bp);
err = request_irq(dev-> irq,b44_interrupt,IRQF_SHARED,dev->名称,dev); //注册中断
if(不太可能是(错误<0)){
napi_disable(&bp-> napi);
b44_chip_reset(bp,B44_CHIP_RESET_PARTIAL);
b44_free_rings(bp);
b44_free_consistent(bp);
出去;
}
init_timer(&bp->计时器);
bp-> timer.expires = jiffies + HZ;
bp-> timer.data =(unsigned long)bp;
bp-> timer.function = b44_timer;
add_timer(&bp->计时器);
b44_enable_ints(bp);
netif_start_queue(dev);
退出:
返回错误;
}
. . . . . . . . . . . . . .
//此函数初始化并注册net_device结构
static int __devinit b44_init_one(结构ssb_device * sdev,
const struct ssb_device_id * ent)
{
static int b44_version_printed = 0;
struct net_device * dev; // net_device指针
结构b44 * bp; //网卡信息结构的指针是net_device结构的成员,该结构是Linux设备驱动程序中描述的priv结构.
//代表不同网卡的私有数据. 例如,内核中的net_device代表Intel的网卡和Realtek的网卡.
//但是它们是不同的. 例如,Intel和Realtek具有不同的方法来实现相同的功能. 这些由priv反映.
//因此,这与net_device相同. 分配内存时,net_device中除priv以外的成员是固定的.
// priv的大小可以是任意的,因此priv的大小必须在分配期间传递.
// priv为空* net_device结构中的priv; void类型指针可以指向任何类型的priv结构
int err;
DECLARE_MAC_BUF(mac);
实例++;
如果(b44_version_printed ++ == 0)
printk(KERN_INFO“%s”,版本);
//分配net_device结构空间,参数是priv的大小
//该函数是alloc_netdev的包装器网卡驱动代码,不仅分配空间会进行一些必要的初始化
dev = alloc_etherdev(sizeof(* bp));
如果(!dev){
dev_err(sdev-> dev,“ Etherdev分配失败,正在中止. \ n”);
err = -ENOMEM;
出去;
}
SET_NETDEV_DEV(dev,sdev-> dev);
dev->功能| = 0;
bp = netdev_priv(dev);
bp-> sdev = sdev;
bp-> dev = dev;
bp-> msg_enable = netif_msg_init(b44_debug,B44_DEF_MSG_ENABLE);
spin_lock_init(&bp->锁定);
bp-> rx_pending = B44_DEF_RX_RING_PENDING;
bp-> tx_pending = B44_DEF_TX_RING_PENDING;
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-145256-1.html
有人好办事啊
非主流哥哥
我相信没错