网卡驱动DM9000(1)

从网卡驱动说起:dm9000

staticint __init
dm9000_init(
void)
{
printk(KERN_INFO
"%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);

return platform_driver_register(&dm9000_driver); //注册平台驱动
}

staticvoid __exit
dm9000_cleanup(
void)
{
platform_driver_unregister(
&dm9000_driver);
}

为什么要有平台驱动这个玩意儿?

人多了就要归类,驱动多了也要归类。同一类别的东西共用相同的东西,也可能是相同的框架。好比这里的驱动:加载的方式,设备的resource都是有模子可循di...

这里的模子就是这个platform_driver_register的参数类型:
    struct platform_driver *drv

staticstruct platform_driver dm9000_driver = {
.driver
= {
.name
="dm9000",    //奶名
.owner = THIS_MODULE, //一般就这么个默认值
.pm =&dm9000_drv_pm_ops, //电源管理的东西,值钱的技术
},
.probe
= dm9000_probe,
.remove
= __devexit_p(dm9000_drv_remove),
};

  probe,平台驱动的特点,加载驱动后执行此函数:

 

 1 staticint __devinit
2 dm9000_probe(struct platform_device *pdev)
3 {
4 struct dm9000_plat_data *pdata = pdev->dev.platform_data;
5 struct board_info *db;
6 struct net_device *ndev;
7 const unsigned char*mac_src;
8 int ret =0;
9 int iosize;
10 int i;
11 u32 id_val;
12
13 /* Init network device */
14 ndev = alloc_etherdev(sizeof(struct board_info)); //分配资源
15 if (!ndev) {
16 dev_err(&pdev->dev, "could not allocate device.\n");
17 return-ENOMEM;
18 }
19
20 SET_NETDEV_DEV(ndev, &pdev->dev);
21
22 dev_dbg(&pdev->dev, "dm9000_probe()\n");
23
24 /* setup board info structure */
25 db = netdev_priv(ndev); //找其私有数据

 

  etdev_priv :

#define ALIGN(x, a)    __ALIGN_KERNEL((x), (a))

#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)

#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))


static inline void*netdev_priv(conststruct net_device *dev)
{
return (char*)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
}

 

 

关于这里为何根据32位对齐去找私有数据,自然是当初如何分配,现在就如何去找咯。
那就去瞧瞧当初的样子。

#define alloc_netdev(sizeof_priv, name, setup) \
    alloc_netdev_mqs(sizeof_priv, name, setup, 1, 1)

 

struct net_device *alloc_netdev_mqs(int sizeof_priv,   constchar*name,
void (*setup)(struct net_device *),
unsigned
int txqs, unsigned int rxqs)
{
... ...

alloc_size
=sizeof(struct net_device);
if (sizeof_priv) {
/* ensure 32-byte alignment of private area */
alloc_size
= ALIGN(alloc_size, NETDEV_ALIGN);
alloc_size
+= sizeof_priv; //这里的priv分配的位置很明显
}
/* ensure 32-byte alignment of whole construct */
alloc_size
+= NETDEV_ALIGN -1;


p
= kzalloc(alloc_size, GFP_KERNEL);
if (!p) {
printk(KERN_ERR
"alloc_netdev: Unable to allocate device.\n");
return NULL;
}

... ...

}

 

私有数据、net_device一同分配,有考虑效率的因素,这么找,就得到我们需要的db

 

得到db之后,就是赋值,先来看看这个db到底是个什么:

View Code
typedef struct board_info {

/*dm9000的两个“大门“寄存器,映射后的虚拟地址*/
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 queue_ip_summed;
u16 dbug_cnt;
u8 io_mode;
/* 0:word, 2:byte */
u8 phy_addr;
u8 imr_all;

unsigned
int flags;
unsigned
int in_suspend :1;
unsigned
int wake_supported :1;
int debug_level;

enum dm9000_type type; //TYPE_DM9000E,TYPE_DM9000A, TYPE_DM9000B

/*回调函数*/
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 device *dev; /* parent device */

struct resource *addr_res; /*数据、地址gpio的信息*/
struct resource *data_res;
struct resource *addr_req; /* resources requested */
struct resource *data_req;
struct resource *irq_res;

int irq_wake;

struct mutex addr_lock; /* phy and eeprom access lock */

struct delayed_work phy_poll;
struct net_device *ndev;

spinlock_t
lock;

struct mii_if_info mii;
u32 msg_enable;
u32 wake_state;

int rx_csum;
int can_csum;
int ip_summed;

} board_info_t;

 

继续:

  1     db->dev =&pdev->dev;
2 db->ndev = ndev;
3
4 spin_lock_init(&db->lock);
5 mutex_init(&db->addr_lock);
6
7 INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
8
9 db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
10 db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
11 db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
12
13 if (db->addr_res == NULL || db->data_res == NULL ||
14 db->irq_res == NULL) {
15 dev_err(db->dev, "insufficient resources\n");
16 ret =-ENOENT;
17 gotoout;
18 }
19
20 db->irq_wake = platform_get_irq(pdev, 1);
21 if (db->irq_wake >=0) {
22 dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);
23
24 ret = request_irq(db->irq_wake, dm9000_wol_interrupt,
25 IRQF_SHARED, dev_name(db->dev), ndev);
26 if (ret) {
27 dev_err(db->dev, "cannot get wakeup irq (%d)\n", ret);
28 } else {
29
30 /* test to see if irq is really wakeup capable */
31 ret = irq_set_irq_wake(db->irq_wake, 1);
32 if (ret) {
33 dev_err(db->dev, "irq %d cannot set wakeup (%d)\n",
34 db->irq_wake, ret);
35 ret =0;
36 } else {
37 irq_set_irq_wake(db->irq_wake, 0);
38 db->wake_supported =1;
39 }
40 }
41 }
42
43 iosize = resource_size(db->addr_res);
44 db->addr_req = request_mem_region(db->addr_res->start, iosize, pdev->name);
45 if (db->addr_req == NULL) {
46 dev_err(db->dev, "cannot claim address reg area\n");
47 ret =-EIO;
48 gotoout;
49 }
50 /*映射 addr_res*/
51 db->io_addr = ioremap(db->addr_res->start, iosize);
52 if (db->io_addr == NULL) {
53 dev_err(db->dev, "failed to ioremap address reg\n");
54 ret =-EINVAL;
55 gotoout;
56 }
57
58 iosize = resource_size(db->data_res);
59 db->data_req = request_mem_region(db->data_res->start, iosize, pdev->name);
60 if (db->data_req == NULL) {
61 dev_err(db->dev, "cannot claim data reg area\n");
62 ret =-EIO;
63 gotoout;
64 }
65 /*映射 data_res*/
66 db->io_data = ioremap(db->data_res->start, iosize);
67 if (db->io_data == NULL) {
68 dev_err(db->dev, "failed to ioremap data reg\n");
69 ret =-EINVAL;
70 gotoout;
71 }
72
73 /* fill in parameters for net-dev structure */
74 ndev->base_addr = (unsigned long)db->io_addr;
75 ndev->irq = db->irq_res->start;
76 /*以上主要就是对addr,data寄存器做些处理,然后让net_device也赋上同样的值*/
77
78
79
80 /*设置传输带宽8位,16位,32位*/
81 dm9000_set_io(db, iosize);
82 if (pdata != NULL) {
83 /* check to see if the driver wants to over-ride the
84 * default IO width */
85
86 if (pdata->flags & DM9000_PLATF_8BITONLY)
87 dm9000_set_io(db, 1);
88
89 if (pdata->flags & DM9000_PLATF_16BITONLY)
90 dm9000_set_io(db, 2);
91
92 if (pdata->flags & DM9000_PLATF_32BITONLY)
93 dm9000_set_io(db, 4);
94
95 /* check to see if there are any IO routine
96 * over-rides */
97
98 if (pdata->inblk != NULL)
99 db->inblk = pdata->inblk;
100
101 if (pdata->outblk != NULL)
102 db->outblk = pdata->outblk;
103
104 if (pdata->dumpblk != NULL)
105 db->dumpblk = pdata->dumpblk;
106
107 db->flags = pdata->flags;
108 }
109
110 #ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL
111 db->flags |= DM9000_PLATF_SIMPLE_PHY;
112 #endif
113 /*之后,就是遵照dm9000's datasheet 先reset,后比较id,若一致,则成功连通*/
114 dm9000_reset(db);
115
116 /* try multiple times, DM9000 sometimes gets the read wrong */
117 for (i =0; i <8; i++) {
118 id_val = ior(db, DM9000_VIDL);
119 id_val |= (u32)ior(db, DM9000_VIDH) <<8;
120 id_val |= (u32)ior(db, DM9000_PIDL) <<16;
121 id_val |= (u32)ior(db, DM9000_PIDH) <<24;
122
123 if (id_val == DM9000_ID)
124 break;
125 dev_err(db->dev, "read wrong id 0x%08x\n", id_val);
126 }
127
128 if (id_val != DM9000_ID) {
129 dev_err(db->dev, "wrong id: 0x%08x\n", id_val);
130 ret =-ENODEV;
131 gotoout;
132 }
133
134 /* Identify what type of DM9000 we are working on */
135
136 id_val = ior(db, DM9000_CHIPR);
137 dev_dbg(db->dev, "dm9000 revision 0x%02x\n", id_val);
138
139 switch (id_val) {
140 case CHIPR_DM9000A:
141 db->type = TYPE_DM9000A;
142 break;
143 case CHIPR_DM9000B:
144 db->type = TYPE_DM9000B;
145 break;
146 default:
147 dev_dbg(db->dev, "ID %02x => defaulting to DM9000E\n", id_val);
148 db->type = TYPE_DM9000E;
149 }
150
151 /* dm9000a/b are capable of hardware checksum offload */
152 if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {
153 db->can_csum =1;
154 db->rx_csum =1;
155 ndev->features |= NETIF_F_IP_CSUM;
156 }
157
158 /*硬件连通的基础上,才可以谈得上进一步的初始化赋值*/
159
160 /* driver system function */
161 ether_setup(ndev); /*初始化net_device中有关以太网的变量*/
162
163 /*网卡操作配置*/
164 ndev->netdev_ops =&dm9000_netdev_ops;
165 ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
166 ndev->ethtool_ops =&dm9000_ethtool_ops;
167
168 /*mii相关*/
169 db->msg_enable = NETIF_MSG_LINK;
170 db->mii.phy_id_mask =0x1f;
171 db->mii.reg_num_mask =0x1f;
172 db->mii.force_media =0;
173 db->mii.full_duplex =0;
174 db->mii.dev = ndev;
175 db->mii.mdio_read = dm9000_phy_read;
176 db->mii.mdio_write = dm9000_phy_write;
177
178 mac_src ="eeprom";
179
180 /* 获取网卡上EEPROM9346的内容,走EERPOM接口 */
181 for (i =0; i <6; i +=2)
182 dm9000_read_eeprom(db, i /2, ndev->dev_addr+i);
183
184 if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
185 mac_src ="platform data";
186 memcpy(ndev->dev_addr, pdata->dev_addr, 6);
187 }
188
189 /*验证获取的MAC地址是否合法*/
190 if (!is_valid_ether_addr(ndev->dev_addr)) {
191 /*不合法,重新从DM9000的内部寄存器获取MAC,不走EEPROM接口*/
192 mac_src ="chip";
193 for (i =0; i <6; i++)
194 ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
195 }
196 /*两种方式都失败,提示用ifconfig,驱动没有对应接口!*/
197 if (!is_valid_ether_addr(ndev->dev_addr)) {
198 dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
199 "set using ifconfig\n", ndev->name);
200
201 random_ether_addr(ndev->dev_addr);
202 mac_src ="random";
203 }
204
205
206 platform_set_drvdata(pdev, ndev); //pdev->dev->p->driver_data = ndev
207
208 /*注册接口到系统中,状态默认down,不可用*/
209 ret = register_netdev(ndev);
210
211 if (ret ==0)
212 printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)\n",
213 ndev->name, dm9000_type_to_char(db->type),
214 db->io_addr, db->io_data, ndev->irq,
215 ndev->dev_addr, mac_src);
216 return0;
217
218 out:
219 dev_err(db->dev, "not found (%d).\n", ret);
220
221 dm9000_release_board(pdev, db);
222 free_netdev(ndev);
223
224 return ret;
225 }

 

  

当使用ifconfig激活该网络接口时调用:

static int
dm9000_open(struct net_device *dev)
{
    board_info_t *db = netdev_priv(dev);
    unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;

    if (netif_msg_ifup(db))
        dev_dbg(db->dev, "enabling %s\n", dev->name);

    /* If there is no IRQ type specified, default to something that
     * may work, and tell the user that this is a problem */

    if (irqflags == IRQF_TRIGGER_NONE)
        dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");

    irqflags |= IRQF_SHARED;

    /*申请中断*/
    if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
        return -EAGAIN;

    /* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */
    iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */
    mdelay(1); /* delay needs by DM9000B */

    /* Initialize DM9000 board */
    dm9000_reset(db);
    /*配置DM9000芯片内寄存器,使其能工作*/
    dm9000_init_dm9000(dev);

    /* Init driver variable */
    db->dbug_cnt = 0; 

    /*检查mii接口状态*/
    mii_check_media(&db->mii, netif_msg_link(db), 1);
    /*启动发送队列*/
    netif_start_queue(dev);
    
    dm9000_schedule_poll(db);	//与dm9000E相关,现在基本不用

    return 0;
}

  

posted @ 2011-07-21 19:51  郝壹贰叁  阅读(382)  评论(0编辑  收藏  举报