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

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

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

spin_lock_irqsave(&db->lock,flags);

reg_save = readb(db->io_addr);

iow(db, DM9000_EPCR, 0x0);

ret = (ior(db, DM9000_EPDRH) < 8) | ior(db, DM9000_EPDRL);

writeb(reg_save, db->io_addr);

spin_unlock_irqrestore(&db->lock,flags);

mutex_unlock(&db->addr_lock);

dm9000_dbg(db, 5, "phy_read[x] -> x\n", reg, ret);

return ret;

}

static void

dm9000_phy_write(struct net_device *dev,

int phyaddr_unused, int reg, int value)

{

board_info_t *db = netdev_priv(dev);

unsigned long flags;

unsigned long reg_save;

dm9000_dbg(db, 5, "phy_write[x] = x\n", reg, value);

mutex_lock(&db->addr_lock);

spin_lock_irqsave(&db->lock,flags);

reg_save = readb(db->io_addr);

iow(db, DM9000_EPAR, DM9000_PHY | reg);

iow(db, DM9000_EPDRL, value);

iow(db, DM9000_EPDRH, value >> 8);

iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);

writeb(reg_save, db->io_addr);

spin_unlock_irqrestore(&db->lock, flags);

dm9000_msleep(db, 1);

spin_lock_irqsave(&db->lock,flags);

reg_save = readb(db->io_addr);

iow(db, DM9000_EPCR, 0x0);

writeb(reg_save, db->io_addr);

spin_unlock_irqrestore(&db->lock, flags);

mutex_unlock(&db->addr_lock);

}

static void

dm9000_shutdown(struct net_device *dev)

{

board_info_t *db = netdev_priv(dev);

dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET);

iow(db, DM9000_GPR, 0x01);

iow(db, DM9000_IMR, IMR_PAR);

iow(db, DM9000_RCR, 0x00);

}

static int

dm9000_stop(struct net_device *ndev)

{

board_info_t *db = netdev_priv(ndev);

if (netif_msg_ifdown(db))

dev_dbg(db->dev, "shutting down %s\n", ndev->name);

cancel_delayed_work_sync(&db->phy_poll);

netif_stop_queue(ndev);

netif_carrier_off(ndev);

free_irq(ndev->irq, ndev);

dm9000_shutdown(ndev);

return 0;

}

static const struct net_device_ops dm9000_netdev_ops = {

.ndo_open = dm9000_open,

.ndo_stop = dm9000_stop,

.ndo_start_xmit = dm9000_start_xmit,

.ndo_tx_timeout = dm9000_timeout,

.ndo_set_multicast_list = dm9000_hash_table,

.ndo_do_ioctl = dm9000_ioctl,

.ndo_change_mtu = eth_change_mtu,

.ndo_validate_addr = eth_validate_addr,

.ndo_set_mac_address = eth_mac_addr,

#ifdef CONFIG_NET_POLL_CONTROLLER

.ndo_poll_controller = dm9000_poll_controller,

#endif

};

static int __devinit

dm9000_probe(struct platform_device *pdev)

{

struct dm9000_plat_data *pdata = pdev->dev.platform_data;

struct board_info *db;

struct net_device *ndev;

const unsigned char *mac_src;

int ret = 0;

int iosize;

int i;

u32 id_val;

unsigned char ne_def_eth_mac_addr[]={0x00,0x12,0x34,0x56,0x80,0x49};

static void *bwscon;

static void *gpfcon;

static void *extint0;

static void *intmsk;

#define BWSCON (0x48000000)

#define GPFCON (0x56000050)

#define EXTINT0 (0x56000088)

#define INTMSK (0x4A000008)

bwscon=ioremap_nocache(BWSCON,0x0000004);

gpfcon=ioremap_nocache(GPFCON,0x0000004);

extint0=ioremap_nocache(EXTINT0,0x0000004);

intmsk=ioremap_nocache(INTMSK,0x0000004);

writel( readl(bwscon)|0xc0000,bwscon);

writel( (readl(gpfcon) & ~(0x3 < 14)) | (0x2 < 14), gpfcon);

writel( readl(gpfcon) | (0x1 < 7), gpfcon); // Disable pull-up,不使能上拉

writel( (readl(extint0) & ~(0xf < 28)) | (0x4 < 28), extint0); //rising edge,设置上升沿触发中断

writel( (readl(intmsk)) & ~0x80, intmsk);

ndev = alloc_etherdev(sizeof(struct board_info));

if (!ndev) {

dev_err(&pdev->dev, "could not allocate device.\n");

return -ENOMEM;

}

SET_NETDEV_DEV(ndev, &pdev->dev);

dev_dbg(&pdev->dev, "dm9000_probe()\n");

db = netdev_priv(ndev);

db->dev = &pdev->dev;

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

网站地图

Top