#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/io.h>
/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
/* #define PACKETBUF_MEMSIZE 0x40 */
+#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
};
{"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 */
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+ {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */
+#endif
{"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
{NULL,}
};
#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_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+# 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 void ne_block_output(struct net_device *dev, const int count,
const unsigned char *buf, const int start_page);
-\f
+
/* Probe for various non-shared-memory ethercards.
NEx000-clone boards have a Station Address PROM (SAPROM) in the packet
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. <cough> */
if (base_addr > 0x1ff) /* Check a single specified location. */
return ne_probe1(dev, base_addr);
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];
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)
{
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];
int neX000, ctron, copam, bad_card;
int reg0, ret;
static unsigned version_printed;
+ DECLARE_MAC_BUF(mac);
if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
return -EBUSY;
if (ei_debug && version_printed++ == 0)
printk(KERN_INFO "%s" KERN_INFO "%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
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;
{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);
}
/* 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)
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("%s\n", print_mac(mac, 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
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:
/* 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;
}
#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);
return;
}
-\f
+static int __init ne_drv_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct resource *res;
+ int err, irq;
+
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!res || irq < 0)
+ return -ENODEV;
+
+ dev = alloc_ei_netdev();
+ if (!dev)
+ return -ENOMEM;
+ dev->irq = irq;
+ dev->base_addr = res->start;
+ err = do_ne_probe(dev);
+ if (err) {
+ free_netdev(dev);
+ return err;
+ }
+ platform_set_drvdata(pdev, dev);
+ return 0;
+}
+
+static int __exit ne_drv_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ unregister_netdev(dev);
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, NE_IO_EXTENT);
+ free_netdev(dev);
+ return 0;
+}
+
+#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))
+ netif_device_detach(dev);
+ return 0;
+}
+
+static int ne_drv_resume(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ if (netif_running(dev)) {
+ ne_reset_8390(dev);
+ NS8390_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 = __exit_p(ne_drv_remove),
+ .suspend = ne_drv_suspend,
+ .resume = ne_drv_resume,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ne_init(void)
+{
+ return platform_driver_probe(&ne_driver, ne_drv_probe);
+}
+
+static void __exit ne_exit(void)
+{
+ platform_driver_unregister(&ne_driver);
+}
+
#ifdef MODULE
#define MAX_NE_CARDS 4 /* Max number of NE cards per module */
static struct net_device *dev_ne[MAX_NE_CARDS];
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. */
-int init_module(void)
+int __init init_module(void)
{
int this_dev, found = 0;
+ int plat_found = !ne_init();
for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
struct net_device *dev = alloc_ei_netdev();
continue;
}
free_netdev(dev);
- if (found)
+ if (found || plat_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]);
printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
return -ENXIO;
}
- if (found)
+ if (found || plat_found)
return 0;
return -ENODEV;
}
-void cleanup_module(void)
+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);
+}
+
+void __exit cleanup_module(void)
{
int this_dev;
+ ne_exit();
for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
struct net_device *dev = dev_ne[this_dev];
if (dev) {
}
}
}
+#else /* MODULE */
+module_init(ne_init);
+module_exit(ne_exit);
#endif /* MODULE */