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;