[PATCH] m68k/atari: EtherNEC - rewrite to use mainstream ne.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Hi.

after much prodding from Geert, and a bit of bouncing ideas back and forth, I've rewritten the Atari EtherNEC ethercard driver to use work with only minimal patches to ne.c (instead of duplicating ne.c as atari_ethernec.c).

The EtherNEC adapter is a solution to use a RTL8019 ISA card on the cartridge (ROM) port of m68k Atari computers. The cartridge port does not support generating interrupts. To service card interrupts, the 8390 interrupt handler is called periodically from a dedicated hardware timer which needs to be shared with other users (the SMC91C111 EtherNAT driver, and a dummy handler dedicated to preventing interference from the interrupt watchdog if the card is idle).

netdev subscribers please focus on the patch to ne.c at the top. Changes to ne.c are twofold: to select 8-bit mode for the driver, and to ensure the interrupt can be shared with aforementioned other users if the driver is used on Atari.

This patch applies on top of Geert's current linux-m68k. It won't cleanly apply on top of, or work if built from Linus' tree, as it relies on further patches relating to bus access quirks that are pending in Geert's tree.

The old EtherNEC driver is retained as-is, to be removed from Geert's tree after this code has been accepted. It can still be built by selecting the CONFIG_ATARI_ETHERNEC_OLD option.

Comments to linux-m68k or me, please - I'm not subscribed to netdev.

Cheers,

  Michael


diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c
index f92ea2a..28b8781 100644
--- a/drivers/net/ethernet/8390/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -55,6 +55,9 @@ static const char version2[] =

 #include <asm/system.h>
 #include <asm/io.h>
+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC)
+#include <asm/atariints.h>
+#endif

 #include "8390.h"

@@ -165,7 +168,8 @@ bad_clone_list[] __initdata = {
 #if defined(CONFIG_PLAT_MAPPI)
 #  define DCR_VAL 0x4b
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
-   defined(CONFIG_MACH_TX49XX)
+   defined(CONFIG_MACH_TX49XX) || \
+   IS_ENABLED(CONFIG_ATARI_ETHERNEC)
 #  define DCR_VAL 0x48        /* 8-bit mode */
 #else
 #  define DCR_VAL 0x49
@@ -492,7 +496,16 @@ static int __init ne_probe1(struct net_device *dev, unsigned long 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, eip_interrupt, 0, name, dev);
+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC)
+    if (MACH_IS_ATARI) {
+        /* Atari EtherNEC emulates the card interrupt via a timer -
+           this needs to be shared with the smc91C111 driver and with
+           a dummy handler to catch unhandled interrupts ! */
+        ret = request_irq(dev->irq, eip_interrupt, IRQF_SHARED, name, dev);
+    } else
+#endif
+        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;
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index af78731..3ff7231 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -687,13 +687,67 @@ static struct platform_device smc91x_device = {
     .resource    = smc91x_resources,
 };

+
+#define ATARI_ETHERNEC_BASE 0x300
+#define ATARI_ETHERNEC_IRQ IRQ_MFP_TIMD
+
+
+static struct resource rtl8019_resources[] = {
+    [0] = {
+        .name    = "rtl9019-regs",
+        .start    = ATARI_ETHERNEC_BASE,
+        .end    = ATARI_ETHERNEC_BASE + 0x20 - 1,
+        .flags    = IORESOURCE_IO,
+    },
+    [1] = {
+        .name    = "rtl9019-irq",
+        .start    = ATARI_ETHERNEC_IRQ,
+        .end    = ATARI_ETHERNEC_IRQ,
+        .flags    = IORESOURCE_IRQ,
+    },
+};
+
+static struct platform_device rtl8019_device = {
+    .name        = "ne",
+    .id        = -1,
+    .num_resources    = ARRAY_SIZE(rtl8019_resources),
+    .resource    = rtl8019_resources,
+};
+
+
 static struct platform_device *atari_platform_devices[] __initdata = {
- &smc91x_device
+ &smc91x_device,
+ &rtl8019_device
 };

+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC) || IS_ENABLED(CONFIG_ATARI_ETHERNAT)
+irqreturn_t atari_timerd_interrupt(int irq, void *dev_id)
+{
+    return IRQ_HANDLED;
+}
+#endif
+
 int __init atari_platform_init(void)
 {
- return platform_add_devices(atari_platform_devices, ARRAY_SIZE(atari_platform_devices));
+
+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC) || IS_ENABLED(CONFIG_ATARI_ETHERNAT)
+    if (hwreg_present(0xfffa0000) || hwreg_present(0x80000000)) {
+        int ret;
+        const char *name = "Timer D dummy interrupt";
+        /* timer routine set up in atari_ethernec_probe() */
+        /* set Timer D data Register */
+        st_mfp.tim_dt_d = 123;    /* 200 Hz */
+        /* start timer D, div = 1:100 */
+        st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 0xf0) | 0x6;
+        /* Must make this shared in case other timer ints are needed */
+ ret = request_irq(IRQ_MFP_TIMD, atari_timerd_interrupt, IRQF_SHARED, name, atari_timerd_interrupt);
+        if (ret) {
+ printk(KERN_ERR "atari_platform_init: failed to register dummy timer interrupt for EtherNEC/EtherNAT!\n");
+        }
+ return platform_add_devices(atari_platform_devices, ARRAY_SIZE(atari_platform_devices));
+    }
+#endif
+    return 0;
 }

 arch_initcall(atari_platform_init);
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 6e86de1..5f8e91f 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -201,7 +201,7 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_ATARILANCE=y
 CONFIG_ATARI_ETHERNAT=m
-CONFIG_ATARI_ETHERNEC=y
+CONFIG_ATARI_ETHERNEC=m
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_PPP=m
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index d5e8882..548b73b 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -243,7 +243,7 @@ static struct devprobe2 m68k_probes[] __initdata = {
 #ifdef CONFIG_ATARILANCE    /* Lance-based Atari ethernet boards */
     {atarilance_probe, 0},
 #endif
-#ifdef CONFIG_ATARI_ETHERNEC    /* NE2000 based ROM port ethernet cards */
+#ifdef CONFIG_ATARI_ETHERNEC_OLD /* NE2000 based ROM port ethernet cards */
     {atari_ethernec_probe, 0},
 #endif
 #ifdef CONFIG_SUN3LANCE         /* sun3 onboard Lance chip */
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig
index b801056..ca5adab 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -223,9 +223,18 @@ config APNE
       To compile this driver as a module, choose M here: the module
       will be called apne.

+config ATARI_ETHERNEC_OLD
+    tristate "Atari EtherNEC Ethernet support - old driver"
+    depends on ATARI_ROM_ISA
+    help
+      Say Y to include support for the EtherNEC network adapter for the
+      ROM port. The driver works by polling instead of interrupts, so it
+      is quite slow.
+
 config ATARI_ETHERNEC
-    tristate "Atari EtherNEC Ethernet support"
+    tristate "Atari EtherNEC Ethernet support - mainstream NE2000 driver"
     depends on ATARI_ROM_ISA
+    select CRC32
     help
       Say Y to include support for the EtherNEC network adapter for the
       ROM port. The driver works by polling instead of interrupts, so it
diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile
index d896466..e620355 100644
--- a/drivers/net/ethernet/8390/Makefile
+++ b/drivers/net/ethernet/8390/Makefile
@@ -6,7 +6,8 @@ obj-$(CONFIG_MAC8390) += mac8390.o
 obj-$(CONFIG_AC3200) += ac3200.o 8390.o
 obj-$(CONFIG_APNE) += apne.o 8390.o
 obj-$(CONFIG_ARM_ETHERH) += etherh.o
-obj-$(CONFIG_ATARI_ETHERNEC) += atari_ethernec.o 8390.o
+obj-$(CONFIG_ATARI_ETHERNEC_OLD) += atari_ethernec.o 8390.o
+obj-$(CONFIG_ATARI_ETHERNEC) += ne.o 8390p.o
 obj-$(CONFIG_AX88796) += ax88796.o
 obj-$(CONFIG_E2100) += e2100.o 8390.o
 obj-$(CONFIG_EL2) += 3c503.o 8390p.o
diff --git a/drivers/net/ethernet/8390/atari_ethernec.c b/drivers/net/ethernet/8390/atari_ethernec.c
index 086d968..e051094 100644
--- a/drivers/net/ethernet/8390/atari_ethernec.c
+++ b/drivers/net/ethernet/8390/atari_ethernec.c
@@ -93,6 +93,7 @@ static const char version2[] =
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/platform_device.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/jiffies.h>
@@ -185,13 +186,13 @@ bad_clone_list[] __initdata = {
 #  define DCR_VAL 0x4b
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) || \
-   defined(CONFIG_ATARI_ETHERNEC) || defined(CONFIG_ATARI_ETHERNEC_MODULE)
+   IS_ENABLED(CONFIG_ATARI_ETHERNEC_OLD)
 #  define DCR_VAL 0x48        /* 8-bit mode */
 #else
 #  define DCR_VAL 0x49
 #endif

-#if defined(CONFIG_ATARI_ETHERNEC) || defined(CONFIG_ATARI_ETHERNEC_MODULE)
+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC_OLD)
 #  define ETHERNEC_RTL_8019_BASE 0x300
 #  define ETHERNEC_RTL_8019_IRQ IRQ_MFP_TIMD
 #endif
@@ -229,7 +230,7 @@ irqreturn_t atari_ei_interrupt(int irq, void *dev_id)
     struct net_device *dev = dev_id;
     if (netif_running(dev))
         return ei_interrupt(dev->irq, dev);
-    return IRQ_NONE;
+    return IRQ_HANDLED;
 }

 static void atari_ethernec_int(struct work_struct *work)
@@ -357,7 +358,7 @@ struct net_device * __init atari_ethernec_probe(int unit)
     sprintf(dev->name, "eth%d", unit);
     netdev_boot_setup_check(dev);

-#if defined(CONFIG_ATARI_ETHERNEC)
+#if IS_ENABLED(CONFIG_ATARI_ETHERNEC_OLD)
     dev->base_addr = ETHERNEC_RTL_8019_BASE;
     dev->irq = ETHERNEC_RTL_8019_IRQ;
 #endif
@@ -456,7 +457,7 @@ 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);

     /* 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
@@ -941,9 +942,10 @@ module_param(use_poll, int, 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_PARM_DESC(use_poll, "Use timer interrupt to poll driver");
+MODULE_PARM_DESC(use_poll, "Use system timer to poll driver");
 MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:8390");

 /* 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

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux Kernel Discussion]     [Ethernet Bridging]     [Linux Wireless Networking]     [Linux Bluetooth Networking]     [Linux Networking Users]     [VLAN]     [Git]     [IETF Annouce]     [Linux Assembly]     [Security]     [Bugtraq]     [Photo]     [Singles Social Networking]     [Yosemite Information]     [MIPS Linux]     [ARM Linux Kernel]     [ARM Linux]     [Linux Virtualization]     [Linux Security]     [Linux IDE]     [Linux RAID]     [Linux SCSI]     [Free Dating]

Add to Google Powered by Linux