X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fne.c;h=b8e2923a1d69e4d50fe7c9e47620c69b42a1005f;hb=HEAD;hp=496433902adee0740c94f251d7519ea26f8fddb0;hpb=1da177e4c3f41524e886b7f1b8a0c1fc7321cac2;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 4964339..b8e2923 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -50,6 +50,8 @@ static const char version2[] = #include #include #include +#include +#include #include #include @@ -62,6 +64,25 @@ static const char version2[] = /* Do we support clones that don't adhere to 14,15 of the SAprom ? */ #define SUPPORT_NE_BAD_CLONES +/* 0xbad = bad sig or no reset ack */ +#define BAD 0xbad + +#define MAX_NE_CARDS 4 /* Max number of NE cards per module */ +static struct platform_device *pdev_ne[MAX_NE_CARDS]; +static int io[MAX_NE_CARDS]; +static int irq[MAX_NE_CARDS]; +static int bad[MAX_NE_CARDS]; + +#ifdef MODULE +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(bad, int, NULL, 0); +MODULE_PARM_DESC(io, "I/O base address(es),required"); +MODULE_PARM_DESC(irq, "IRQ number(s)"); +MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures"); +MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver"); +MODULE_LICENSE("GPL"); +#endif /* MODULE */ /* Do we perform extra sanity checks on stuff ? */ /* #define NE_SANITY_CHECK */ @@ -72,8 +93,17 @@ static const char version2[] = /* Do we have a non std. amount of memory? (in units of 256 byte pages) */ /* #define PACKETBUF_MEMSIZE 0x40 */ +/* This is set up so that no ISA autoprobe takes place. We can't guarantee +that the ne2k probe is the last 8390 based probe to take place (as it +is at boot) and so the probe will get confused by any other 8390 cards. +ISA device autoprobes on a running machine are not recommended anyway. */ +#if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R)) +/* Do we need a portlist for the ISA auto-probe ? */ +#define NEEDS_PORTLIST +#endif + /* A zero-terminated list of I/O addresses to be probed at boot. */ -#ifndef MODULE +#ifdef NEEDS_PORTLIST static unsigned int netcard_portlist[] __initdata = { 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0 }; @@ -111,6 +141,9 @@ bad_clone_list[] __initdata = { {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ +#ifdef CONFIG_MACH_TX49XX + {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ +#endif {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ {NULL,} }; @@ -129,20 +162,18 @@ bad_clone_list[] __initdata = { #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ -#ifdef CONFIG_PLAT_MAPPI +#if defined(CONFIG_PLAT_MAPPI) # define DCR_VAL 0x4b -#elif CONFIG_PLAT_OAKS32R -# define DCR_VAL 0x48 +#elif defined(CONFIG_PLAT_OAKS32R) || \ + defined(CONFIG_MACH_TX49XX) +# define DCR_VAL 0x48 /* 8-bit mode */ #else # define DCR_VAL 0x49 #endif -static int ne_probe1(struct net_device *dev, int ioaddr); +static int ne_probe1(struct net_device *dev, unsigned long ioaddr); static int ne_probe_isapnp(struct net_device *dev); -static int ne_open(struct net_device *dev); -static int ne_close(struct net_device *dev); - static void ne_reset_8390(struct net_device *dev); static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); @@ -151,7 +182,7 @@ static void ne_block_input(struct net_device *dev, int count, static void ne_block_output(struct net_device *dev, const int count, const unsigned char *buf, const int start_page); - + /* Probe for various non-shared-memory ethercards. NEx000-clone boards have a Station Address PROM (SAPROM) in the packet @@ -175,16 +206,19 @@ static void ne_block_output(struct net_device *dev, const int count, static int __init do_ne_probe(struct net_device *dev) { - unsigned int base_addr = dev->base_addr; -#ifndef MODULE + unsigned long base_addr = dev->base_addr; +#ifdef NEEDS_PORTLIST int orig_irq = dev->irq; #endif - SET_MODULE_OWNER(dev); - /* First check any supplied i/o locations. User knows best. */ - if (base_addr > 0x1ff) /* Check a single specified location. */ - return ne_probe1(dev, base_addr); + if (base_addr > 0x1ff) { /* Check a single specified location. */ + int ret = ne_probe1(dev, base_addr); + if (ret) + printk(KERN_WARNING "ne.c: No NE*000 card found at " + "i/o = %#lx\n", base_addr); + return ret; + } else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; @@ -192,7 +226,7 @@ static int __init do_ne_probe(struct net_device *dev) if (isapnp_present() && (ne_probe_isapnp(dev) == 0)) return 0; -#ifndef MODULE +#ifdef NEEDS_PORTLIST /* Last resort. The semi-risky ISA auto-probe. */ for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) { int ioaddr = netcard_portlist[base_addr]; @@ -205,42 +239,6 @@ static int __init do_ne_probe(struct net_device *dev) return -ENODEV; } -static void cleanup_card(struct net_device *dev) -{ - struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; - if (idev) - pnp_device_detach(idev); - free_irq(dev->irq, dev); - release_region(dev->base_addr, NE_IO_EXTENT); -} - -#ifndef MODULE -struct net_device * __init ne_probe(int unit) -{ - struct net_device *dev = alloc_ei_netdev(); - int err; - - if (!dev) - return ERR_PTR(-ENOMEM); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - - err = do_ne_probe(dev); - if (err) - goto out; - err = register_netdev(dev); - if (err) - goto out1; - return dev; -out1: - cleanup_card(dev); -out: - free_netdev(dev); - return ERR_PTR(err); -} -#endif - static int __init ne_probe_isapnp(struct net_device *dev) { int i; @@ -286,7 +284,7 @@ static int __init ne_probe_isapnp(struct net_device *dev) return -ENODEV; } -static int __init ne_probe1(struct net_device *dev, int ioaddr) +static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) { int i; unsigned char SA_prom[32]; @@ -323,9 +321,9 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) } if (ei_debug && version_printed++ == 0) - printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2); + printk(KERN_INFO "%s%s", version1, version2); - printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr); + printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr); /* A user with a poor card that fails to ack the reset, or that does not have a valid 0x57,0x57 signature can still use this @@ -333,7 +331,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) with an otherwise unused dev->mem_end value of "0xBAD" will cause the driver to skip these parts of the probe. */ - bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad)); + bad_card = ((dev->base_addr != 0) && (dev->mem_end == BAD)); /* Reset card. Who knows what dain-bramaged state it was left in. */ @@ -344,7 +342,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0) - if (jiffies - reset_start_time > 2*HZ/100) { + if (time_after(jiffies, reset_start_time + 2*HZ/100)) { if (bad_card) { printk(" (warning: no reset ack)"); break; @@ -359,7 +357,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) } /* Read the 16 bytes of station address PROM. - We must first initialize registers, similar to NS8390_init(eifdev, 0). + We must first initialize registers, similar to NS8390p_init(eifdev, 0). We can't reliably read the SAPROM address without this. (I learned the hard way!). */ { @@ -380,7 +378,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) {E8390_RREAD+E8390_START, E8390_CMD}, }; - for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) + for (i = 0; i < ARRAY_SIZE(program_seq); i++) outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); } @@ -398,10 +396,22 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) /* We must set the 8390 for word mode. */ outb_p(DCR_VAL, ioaddr + EN0_DCFG); start_page = NESM_START_PG; - stop_page = NESM_STOP_PG; + + /* + * Realtek RTL8019AS datasheet says that the PSTOP register + * shouldn't exceed 0x60 in 8-bit mode. + * This chip can be identified by reading the signature from + * the remote byte count registers (otherwise write-only)... + */ + if ((DCR_VAL & 0x01) == 0 && /* 8-bit mode */ + inb(ioaddr + EN0_RCNTLO) == 0x50 && + inb(ioaddr + EN0_RCNTHI) == 0x70) + stop_page = 0x60; + else + stop_page = NESM_STOP_PG; } else { start_page = NE1SM_START_PG; - stop_page = NE1SM_STOP_PG; + stop_page = NE1SM_STOP_PG; } #if defined(CONFIG_PLAT_MAPPI) || defined(CONFIG_PLAT_OAKS32R) @@ -482,7 +492,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ - ret = request_irq(dev->irq, ei_interrupt, 0, name, dev); + ret = request_irq(dev->irq, eip_interrupt, 0, name, dev); if (ret) { printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret); goto err_out; @@ -496,26 +506,21 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) for (i = 0 ; i < ETHER_ADDR_LEN ; i++) { dev->dev_addr[i] = SA_prom[i] = inb_p(ioaddr + EN1_PHYS_SHIFT(i)); - printk(" %2.2x", SA_prom[i]); } #else for(i = 0; i < ETHER_ADDR_LEN; i++) { - printk(" %2.2x", SA_prom[i]); dev->dev_addr[i] = SA_prom[i]; } #endif - printk("\n%s: %s found at %#x, using IRQ %d.\n", - dev->name, name, ioaddr, dev->irq); + printk("%pM\n", dev->dev_addr); ei_status.name = name; ei_status.tx_start_page = start_page; ei_status.stop_page = stop_page; -#ifdef CONFIG_PLAT_OAKS32R - ei_status.word16 = 0; -#else - ei_status.word16 = (wordlength == 2); -#endif + + /* Use 16-bit mode only if this wasn't overridden by DCR_VAL */ + ei_status.word16 = (wordlength == 2 && (DCR_VAL & 0x01)); ei_status.rx_start_page = start_page + TX_PAGES; #ifdef PACKETBUF_MEMSIZE @@ -528,33 +533,24 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) ei_status.block_output = &ne_block_output; ei_status.get_8390_hdr = &ne_get_8390_hdr; ei_status.priv = 0; - dev->open = &ne_open; - dev->stop = &ne_close; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = ei_poll; -#endif - NS8390_init(dev, 0); + + dev->netdev_ops = &eip_netdev_ops; + NS8390p_init(dev, 0); + + ret = register_netdev(dev); + if (ret) + goto out_irq; + printk(KERN_INFO "%s: %s found at %#lx, using IRQ %d.\n", + dev->name, name, ioaddr, dev->irq); return 0; +out_irq: + free_irq(dev->irq, dev); err_out: release_region(ioaddr, NE_IO_EXTENT); return ret; } -static int ne_open(struct net_device *dev) -{ - ei_open(dev); - return 0; -} - -static int ne_close(struct net_device *dev) -{ - if (ei_debug > 1) - printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); - ei_close(dev); - return 0; -} - /* Hard reset the card. This used to pause for the same period that a 8390 reset command required, but that shouldn't be necessary. */ @@ -573,7 +569,7 @@ static void ne_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (jiffies - reset_start_time > 2*HZ/100) { + if (time_after(jiffies, reset_start_time + 2*HZ/100)) { printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); break; } @@ -780,83 +776,231 @@ retry: #endif while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ + if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); ne_reset_8390(dev); - NS8390_init(dev,1); + NS8390p_init(dev, 1); break; } outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ ei_status.dmaing &= ~0x01; - return; } - -#ifdef MODULE -#define MAX_NE_CARDS 4 /* Max number of NE cards per module */ -static struct net_device *dev_ne[MAX_NE_CARDS]; -static int io[MAX_NE_CARDS]; -static int irq[MAX_NE_CARDS]; -static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */ - -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param_array(bad, int, NULL, 0); -MODULE_PARM_DESC(io, "I/O base address(es),required"); -MODULE_PARM_DESC(irq, "IRQ number(s)"); -MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures"); -MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver"); -MODULE_LICENSE("GPL"); +static int __init ne_drv_probe(struct platform_device *pdev) +{ + struct net_device *dev; + int err, this_dev = pdev->id; + struct resource *res; -/* This is set up so that no ISA autoprobe takes place. We can't guarantee -that the ne2k probe is the last 8390 based probe to take place (as it -is at boot) and so the probe will get confused by any other 8390 cards. -ISA device autoprobes on a running machine are not recommended anyway. */ + dev = alloc_eip_netdev(); + if (!dev) + return -ENOMEM; + + /* ne.c doesn't populate resources in platform_device, but + * rbtx4927_ne_init and rbtx4938_ne_init do register devices + * with resources. + */ + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (res) { + dev->base_addr = res->start; + dev->irq = platform_get_irq(pdev, 0); + } else { + if (this_dev < 0 || this_dev >= MAX_NE_CARDS) + return -EINVAL; + dev->base_addr = io[this_dev]; + dev->irq = irq[this_dev]; + dev->mem_end = bad[this_dev]; + } + err = do_ne_probe(dev); + if (err) { + free_netdev(dev); + return err; + } + platform_set_drvdata(pdev, dev); + + /* Update with any values found by probing, don't update if + * resources were specified. + */ + if (!res) { + io[this_dev] = dev->base_addr; + irq[this_dev] = dev->irq; + } + return 0; +} -int init_module(void) +static int ne_drv_remove(struct platform_device *pdev) { - int this_dev, found = 0; + struct net_device *dev = platform_get_drvdata(pdev); + + if (dev) { + struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; + netif_device_detach(dev); + unregister_netdev(dev); + if (idev) + pnp_device_detach(idev); + /* Careful ne_drv_remove can be called twice, once from + * the platform_driver.remove and again when the + * platform_device is being removed. + */ + ei_status.priv = 0; + free_irq(dev->irq, dev); + release_region(dev->base_addr, NE_IO_EXTENT); + free_netdev(dev); + platform_set_drvdata(pdev, NULL); + } + return 0; +} +/* Remove unused devices or all if true. */ +static void ne_loop_rm_unreg(int all) +{ + int this_dev; + struct platform_device *pdev; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct net_device *dev = alloc_ei_netdev(); - if (!dev) - break; - dev->irq = irq[this_dev]; - dev->mem_end = bad[this_dev]; - dev->base_addr = io[this_dev]; - if (do_ne_probe(dev) == 0) { - if (register_netdev(dev) == 0) { - dev_ne[found++] = dev; - continue; - } - cleanup_card(dev); + pdev = pdev_ne[this_dev]; + /* No network device == unused */ + if (pdev && (!platform_get_drvdata(pdev) || all)) { + ne_drv_remove(pdev); + platform_device_unregister(pdev); + pdev_ne[this_dev] = NULL; } - free_netdev(dev); - if (found) - break; - if (io[this_dev] != 0) - printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]); - else - printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); - return -ENXIO; } - if (found) - return 0; - return -ENODEV; } -void cleanup_module(void) +#ifdef CONFIG_PM +static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct net_device *dev = platform_get_drvdata(pdev); + + if (netif_running(dev)) { + struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; + netif_device_detach(dev); + if (idev) + pnp_stop_dev(idev); + } + return 0; +} + +static int ne_drv_resume(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + + if (netif_running(dev)) { + struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; + if (idev) + pnp_start_dev(idev); + ne_reset_8390(dev); + NS8390p_init(dev, 1); + netif_device_attach(dev); + } + return 0; +} +#else +#define ne_drv_suspend NULL +#define ne_drv_resume NULL +#endif + +static struct platform_driver ne_driver = { + .remove = ne_drv_remove, + .suspend = ne_drv_suspend, + .resume = ne_drv_resume, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static void __init ne_add_devices(void) +{ + int this_dev; + struct platform_device *pdev; + + for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { + if (pdev_ne[this_dev]) + continue; + pdev = platform_device_register_simple( + DRV_NAME, this_dev, NULL, 0); + if (IS_ERR(pdev)) + continue; + pdev_ne[this_dev] = pdev; + } +} + +#ifdef MODULE +int __init init_module(void) +{ + int retval; + ne_add_devices(); + retval = platform_driver_probe(&ne_driver, ne_drv_probe); + if (retval) { + if (io[0] == 0) + printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\"" + " value(s) for ISA cards.\n"); + ne_loop_rm_unreg(1); + return retval; + } + + /* Unregister unused platform_devices. */ + ne_loop_rm_unreg(0); + return retval; +} +#else /* MODULE */ +static int __init ne_init(void) +{ + int retval = platform_driver_probe(&ne_driver, ne_drv_probe); + + /* Unregister unused platform_devices. */ + ne_loop_rm_unreg(0); + return retval; +} +module_init(ne_init); + +struct net_device * __init ne_probe(int unit) { int this_dev; + struct net_device *dev; + + /* Find an empty slot, that is no net_device and zero io port. */ + this_dev = 0; + while ((pdev_ne[this_dev] && platform_get_drvdata(pdev_ne[this_dev])) || + io[this_dev]) { + if (++this_dev == MAX_NE_CARDS) + return ERR_PTR(-ENOMEM); + } + + /* Get irq, io from kernel command line */ + dev = alloc_eip_netdev(); + if (!dev) + return ERR_PTR(-ENOMEM); + + sprintf(dev->name, "eth%d", unit); + netdev_boot_setup_check(dev); + + io[this_dev] = dev->base_addr; + irq[this_dev] = dev->irq; + bad[this_dev] = dev->mem_end; + + free_netdev(dev); + ne_add_devices(); + + /* return the first device found */ for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct net_device *dev = dev_ne[this_dev]; - if (dev) { - unregister_netdev(dev); - cleanup_card(dev); - free_netdev(dev); + if (pdev_ne[this_dev]) { + dev = platform_get_drvdata(pdev_ne[this_dev]); + if (dev) + return dev; } } + + return ERR_PTR(-ENODEV); } #endif /* MODULE */ + +static void __exit ne_exit(void) +{ + platform_driver_unregister(&ne_driver); + ne_loop_rm_unreg(1); +} +module_exit(ne_exit);