微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM-Linux驱动--DM9000网卡驱动分析(四)

ARM-Linux驱动--DM9000网卡驱动分析(四)

时间:11-20 来源:互联网 点击:

db->ndev = ndev;

spin_lock_init(&db->lock);

mutex_init(&db->addr_lock);

INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);

db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);

db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

if (db->addr_res == NULL || db->data_res == NULL ||

db->irq_res == NULL) {

dev_err(db->dev, "insufficient resources\n");

ret = -ENOENT;

goto out;

}

db->irq_wake = platform_get_irq(pdev, 1);

if (db->irq_wake >= 0) {

dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);

ret = request_irq(db->irq_wake, dm9000_wol_interrupt,

IRQF_SHARED, dev_name(db->dev), ndev);

if (ret) {

dev_err(db->dev, "cannot get wakeup irq (%d)\n", ret);

} else {

ret = set_irq_wake(db->irq_wake, 1);

if (ret) {

dev_err(db->dev, "irq %d cannot set wakeup (%d)\n",

db->irq_wake, ret);

ret = 0;

} else {

set_irq_wake(db->irq_wake, 0);

db->wake_supported = 1;

}

}

}

iosize = resource_size(db->addr_res);

db->addr_req = request_mem_region(db->addr_res->start, iosize,

pdev->name);

if (db->addr_req == NULL) {

dev_err(db->dev, "cannot claim address reg area\n");

ret = -EIO;

goto out;

}

db->io_addr = ioremap(db->addr_res->start, iosize);

if (db->io_addr == NULL) {

dev_err(db->dev, "failed to ioremap address reg\n");

ret = -EINVAL;

goto out;

}

iosize = resource_size(db->data_res);

db->data_req = request_mem_region(db->data_res->start, iosize,

pdev->name);

if (db->data_req == NULL) {

dev_err(db->dev, "cannot claim data reg area\n");

ret = -EIO;

goto out;

}

db->io_data = ioremap(db->data_res->start, iosize);

if (db->io_data == NULL) {

dev_err(db->dev, "failed to ioremap data reg\n");

ret = -EINVAL;

goto out;

}

ndev->base_addr = (unsigned long)db->io_addr;

ndev->irq = db->irq_res->start;

dm9000_set_io(db, iosize);

if (pdata != NULL) {

if (pdata->flags & DM9000_PLATF_8BITONLY)

dm9000_set_io(db, 1);

if (pdata->flags & DM9000_PLATF_16BITONLY)

dm9000_set_io(db, 2);

if (pdata->flags & DM9000_PLATF_32BITONLY)

dm9000_set_io(db, 4);

if (pdata->inblk != NULL)

db->inblk = pdata->inblk;

if (pdata->outblk != NULL)

db->outblk = pdata->outblk;

if (pdata->dumpblk != NULL)

db->dumpblk = pdata->dumpblk;

db->flags = pdata->flags;

}

#ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL

db->flags |= DM9000_PLATF_SIMPLE_PHY;

#endif

dm9000_reset(db);

for (i = 0; i < 8; i++) {

id_val = ior(db, DM9000_VIDL);

id_val |= (u32)ior(db, DM9000_VIDH) < 8;

id_val |= (u32)ior(db, DM9000_PIDL) < 16;

id_val |= (u32)ior(db, DM9000_PIDH) < 24;

if (id_val == DM9000_ID)

break;

dev_err(db->dev, "read wrong id 0xx\n", id_val);

}

if (id_val != DM9000_ID) {

dev_err(db->dev, "wrong id: 0xx\n", id_val);

ret = -ENODEV;

goto out;

}

id_val = ior(db, DM9000_CHIPR);

dev_dbg(db->dev, "dm9000 revision 0xx\n", id_val);

switch (id_val) {

case CHIPR_DM9000A:

db->type = TYPE_DM9000A;

break;

case CHIPR_DM9000B:

db->type = TYPE_DM9000B;

break;

default:

dev_dbg(db->dev, "ID x => defaulting to DM9000E\n", id_val);

db->type = TYPE_DM9000E;

}

if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {

db->can_csum = 1;

db->rx_csum = 1;

ndev->features |= NETIF_F_IP_CSUM;

}

ether_setup(ndev);

ndev->netdev_ops = &dm9000_netdev_ops;

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top