diff options
author | Ulf Carlsson <md1ulfc@mdstud.chalmers.se> | 2000-05-31 09:02:29 +0000 |
---|---|---|
committer | Ulf Carlsson <md1ulfc@mdstud.chalmers.se> | 2000-05-31 09:02:29 +0000 |
commit | 6814b559ef9780880b59f828c2d4414ca99525b2 (patch) | |
tree | 5020d03fe4071d19c1e6a11f6f2c462ab5d76dd8 /drivers/net | |
parent | 86503e1fce07cfa5e4d8fbeb172adb0ac704d1d6 (diff) |
Use ether_setup instead of init_etherdev.
Do not allocate a ethX for IOC3's that don't have a PHY attached.
Don't depend on the regular moon phases at return from ioc3_probe.
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ioc3-eth.c | 94 |
1 files changed, 49 insertions, 45 deletions
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 4f33bf1ca..308d40b2d 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -483,53 +483,33 @@ static void ioc3_interrupt(int irq, void *_dev, struct pt_regs *regs) int ioc3_eth_init(struct net_device *dev, struct ioc3_private *ip, struct ioc3 *ioc3) { - u16 word, mii0, mii_status, mii2, mii3, mii4; + u16 mii0, mii_status, mii2, mii3, mii4; u32 vendor, model, rev; - int i, phy; - - ioc3->emcr = EMCR_RST; /* Reset */ - ioc3->emcr; /* flush WB */ - udelay(4); /* Give it time ... */ - ioc3->emcr = 0; spin_lock_irq(&ip->ioc3_lock); - phy = -1; - for (i = 0; i < 32; i++) { - word = mii_read(ioc3, i, 2); - if ((word != 0xffff) & (word != 0x0000)) { - phy = i; - break; /* Found a PHY */ - } - } - if (phy == -1) { - spin_unlock_irq(&ip->ioc3_lock); - printk("Didn't find a PHY, goodbye.\n"); - return -ENODEV; - } - ip->phy = phy; - mii0 = mii_read(ioc3, phy, 0); - mii_status = mii_read(ioc3, phy, 1); - mii2 = mii_read(ioc3, phy, 2); - mii3 = mii_read(ioc3, phy, 3); - mii4 = mii_read(ioc3, phy, 4); + mii0 = mii_read(ioc3, ip->phy, 0); + mii_status = mii_read(ioc3, ip->phy, 1); + mii2 = mii_read(ioc3, ip->phy, 2); + mii3 = mii_read(ioc3, ip->phy, 3); + mii4 = mii_read(ioc3, ip->phy, 4); vendor = (mii2 << 12) | (mii3 >> 4); model = (mii3 >> 4) & 0x3f; rev = mii3 & 0xf; printk("Ok, using PHY %d, vendor 0x%x, model %d, rev %d.\n", - phy, vendor, model, rev); + ip->phy, vendor, model, rev); printk(KERN_INFO "%s: MII transceiver found at MDIO address " "%d, config %4.4x status %4.4x.\n", - dev->name, phy, mii0, mii_status); + dev->name, ip->phy, mii0, mii_status); /* Autonegotiate 100mbit and fullduplex. */ - mii_write(ioc3, phy, 0, mii0 | 0x3100); + mii_write(ioc3, ip->phy, 0, mii0 | 0x3100); spin_unlock_irq(&ip->ioc3_lock); mdelay(1000); /* XXX Yikes XXX */ spin_lock_irq(&ip->ioc3_lock); - mii_status = mii_read(ioc3, phy, 1); + mii_status = mii_read(ioc3, ip->phy, 1); spin_unlock_irq(&ip->ioc3_lock); return 0; /* XXX */ @@ -620,31 +600,51 @@ ioc3_ssram_disc(struct ioc3_private *ip) } } -static void ioc3_init(struct pci_dev *pdev) +static int ioc3_probe1(struct pci_dev *pdev) { struct net_device *dev = NULL; // XXX struct ioc3_private *ip; struct ioc3 *ioc3; unsigned long ioc3_base, ioc3_size; + int phy; + u16 word; - dev = init_etherdev(dev, 0); + ioc3_base = pdev->resource[0].start; + ioc3_size = pdev->resource[0].end - ioc3_base; + ioc3 = (struct ioc3 *) ioremap(ioc3_base, ioc3_size); - /* - * This probably needs to be register_netdevice, or call - * init_etherdev so that it calls register_netdevice. Quick - * hack for now. - */ - netif_device_attach(dev); + /* Probe for a PHY first ... */ + + ioc3->emcr = EMCR_RST; /* Reset */ + ioc3->emcr; /* flush WB */ + udelay(4); /* Give it time ... */ + ioc3->emcr = 0; + + for (phy = 31; phy > 0; phy--) { + word = mii_read(ioc3, phy, 2); + if (word == 0x0000) + return -ENODEV; /* No PHY connected */ + if (word != 0xffff) + break; /* Found a PHY */ + } + if (phy == -1) { + printk("No PHY present?\n"); + return -ENODEV; + } + + dev = init_etherdev(dev, 0); ip = (struct ioc3_private *) kmalloc(sizeof(*ip), GFP_KERNEL); + if (ip == NULL) { + printk(KERN_ERR "ioc3: Unable to allocate memory\n"); + return -ENOMEM; + } memset(ip, 0, sizeof(*ip)); dev->priv = ip; dev->irq = pdev->irq; - ioc3_base = pdev->resource[0].start; - ioc3_size = pdev->resource[0].end - ioc3_base; - ioc3 = (struct ioc3 *) ioremap(ioc3_base, ioc3_size); ip->regs = ioc3; + ip->phy = phy; ioc3_eth_init(dev, ip, ioc3); ioc3_ssram_disc(ip); @@ -676,25 +676,29 @@ static void ioc3_init(struct pci_dev *pdev) dev->get_stats = ioc3_get_stats; dev->do_ioctl = ioc3_ioctl; dev->set_multicast_list = ioc3_set_multicast_list; + + ether_setup(dev); + + return 0; } static int __init ioc3_probe(void) { static int called = 0; - struct ioc3 *ioc3; int cards; if (called) return -ENODEV; called = 1; + cards = 0; if (pci_present()) { struct pci_dev *pdev = NULL; while ((pdev = pci_find_device(PCI_VENDOR_ID_SGI, - PCI_DEVICE_ID_SGI_IOC3, pdev))) { - ioc3_init(pdev); - } + PCI_DEVICE_ID_SGI_IOC3, pdev))) + if (ioc3_probe1(pdev) == 0) + cards++; } return cards ? -ENODEV : 0; |