Broadcom网卡驱动程序代码分析说明

电脑杂谈  发布时间:2020-03-19 21:12:51  来源:网络整理

驱动人生5 网卡版_网卡驱动代码_联想官网下载的网卡 驱动怎么安装

//注释者: 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)

网卡驱动代码_驱动人生5 网卡版_联想官网下载的网卡 驱动怎么安装

#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;

联想官网下载的网卡 驱动怎么安装_网卡驱动代码_驱动人生5 网卡版

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

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...