Hi,

this isn't really my kettle of fish, but I post it anyway unless Petr
complains :-)

This is what makes it possible for me to test 2.6 builds on the
emulator...

Should be signed off by Petr, really.

        Michael
--- linux-2.6.19-m68k-cvs/arch/m68k/atari/config.c      2006-12-02 
00:16:50.000000000 +0100
+++ linux-2.6.19-m68k/arch/m68k/atari/config.c  2006-12-08 18:49:02.000000000 
+0100
@@ -32,6 +32,10 @@
 #include <linux/ioport.h>
 #include <linux/vt_kern.h>
 
+#ifdef CONFIG_NATFEAT
+#include "natfeat.h"
+#endif
+
 #include <asm/bootinfo.h>
 #include <asm/setup.h>
 #include <asm/atarihw.h>
@@ -207,6 +211,12 @@
     }
 }
 
+void atari_poweroff(void)
+{
+#ifdef CONFIG_NATFEAT
+    nf_shutdown();
+#endif
+}
 
     /*
      *  Setup the Atari configuration info
@@ -218,6 +228,10 @@
 
     memset(&atari_hw_present, 0, sizeof(atari_hw_present));
 
+#ifdef CONFIG_NATFEAT
+    nf_init();
+#endif
+
     atari_debug_init();
 
     ioport_resource.end  = 0xFFFFFFFF;  /* Change size of I/O space from 64KB
@@ -229,6 +243,8 @@
     mach_get_hardware_list = atari_get_hardware_list;
     mach_gettimeoffset   = atari_gettimeoffset;
     mach_reset           = atari_reset;
+    mach_halt            = atari_poweroff;
+    mach_power_off       = atari_poweroff;
     mach_max_dma_address = 0xffffff;
 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
     mach_beep          = atari_mksound;
@@ -614,6 +630,11 @@
 
 static void atari_get_model(char *model)
 {
+#ifdef CONFIG_NATFEAT
+    if (nf_name1(model, 80)) { // char model[80] defined in kernel/setup.c
+       return;
+    }
+#endif
     strcpy(model, "Atari ");
     switch (atari_mch_cookie >> 16) {
        case ATARI_MCH_ST:
--- linux-2.6.19-m68k-cvs/arch/m68k/atari/Makefile      2003-02-10 
20:34:25.000000000 +0100
+++ linux-2.6.19-m68k/arch/m68k/atari/Makefile  2006-12-08 18:49:02.000000000 
+0100
@@ -3,8 +3,12 @@
 #
 
 obj-y          := config.o time.o debug.o ataints.o stdma.o \
-                       atasound.o stram.o atari_ksyms.o
+                       atakeyb.o atasound.o stram.o atari_ksyms.o
 
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_HADES)    += hades-pci.o
 endif
+
+ifeq ($(CONFIG_NATFEAT),y)
+obj-$(CONFIG_NATFEAT)  += natfeat.o
+endif
--- linux-2.6.19-m68k-cvs/arch/m68k/atari/natfeat.h     2006-12-08 
18:49:02.000000000 +0100
+++ linux-2.6.19-m68k/arch/m68k/atari/natfeat.h 2006-12-08 18:49:02.000000000 
+0100
@@ -0,0 +1,35 @@
+/*
+ * ARAnyM hardware support via Native Features (natfeats)
+ *
+ * Copyright (c) 2005 Petr Stehlik of ARAnyM dev team
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ */
+
+#ifndef _natfeat_h
+#define _natfeat_h
+
+struct nf_ops
+{
+       long (*get_id)(const char *);
+       long (*call)(long id, ...);
+       long res[3];
+};
+
+struct nf_ops *nf_init(void);
+
+int nf_name(char *buf, int bufsize);
+int nf_debug(const char *msg);
+int nf_shutdown(void);
+
+int nf_ethernet_check_version(char *errmsg, int errmsglen);
+int nf_ethernet_get_irq(void);
+int nf_ethernet_get_hw_addr(int ethX, char *buffer, int bufsize);
+int nf_ethernet_interrupt(int bit);
+int nf_ethernet_read_packet_len(int ethX);
+void nf_ethernet_read_block(int ethX, char *buffer, int len);
+void nf_ethernet_write_block(int ethX, char *buffer, int len);
+void nf_ethernet_xif_start(int ethX);
+void nf_ethernet_xif_stop(int ethX);
+# endif /* _natfeat_h */
--- linux-2.6.19-m68k-cvs/arch/m68k/atari/ethernet_nfapi.h      2006-12-08 
18:49:02.000000000 +0100
+++ linux-2.6.19-m68k/arch/m68k/atari/ethernet_nfapi.h  2006-12-08 
18:49:02.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ * ARAnyM ethernet driver - header file.
+ *
+ * Copyright (c) 2002-2004 Standa and Petr of ARAnyM dev team (see AUTHORS)
+ * 
+ * This file is part of the ARAnyM project which builds a new and powerful
+ * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
+ *
+ * ARAnyM is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ARAnyM is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ARAnyM; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ARAETHER_NFAPI_H
+#define _ARAETHER_NFAPI_H
+
+/*
+   The code for the FreeMiNT driver was moved to the FreeMiNT CVS:
+   freemint/sys/sockets/xif/nfeth.
+
+   If you edit this file then you would need to synchronize it with the
+   driver in the freemint CVS (nfeth_nfapi.h).
+
+   if you change anything in the enum {} below you have to increase 
+   this ARAETHER_NFAPI_VERSION!
+*/
+#define ARAETHER_NFAPI_VERSION 0x00000005
+
+enum {
+       GET_VERSION = 0,        /* no parameters, return NFAPI_VERSION in d0 */
+       XIF_INTLEVEL,           /* no parameters, return Interrupt Level in d0 
*/
+       XIF_IRQ,                        /* acknowledge interrupt from host */
+       XIF_START,                      /* (ethX), called on 'ifup', start 
receiver thread */
+       XIF_STOP,                       /* (ethX), called on 'ifdown', stop the 
thread */
+       XIF_READLENGTH,         /* (ethX), return size of network data block to 
read */
+       XIF_READBLOCK,          /* (ethX, buffer, size), read block of network 
data */
+       XIF_WRITEBLOCK,         /* (ethX, buffer, size), write block of network 
data */
+       XIF_GET_MAC,            /* (ethX, buffer, size), return MAC HW addr in 
buffer */
+       XIF_GET_IPHOST,         /* (ethX, buffer, size), return IP address of 
host */
+       XIF_GET_IPATARI,        /* (ethX, buffer, size), return IP address of 
atari */
+       XIF_GET_NETMASK         /* (ethX, buffer, size), return IP netmask */
+};
+
+#define ETH(a) (nfEtherID + a)
+
+#endif /* _ARAETHER_NFAPI_H */
--- linux-2.6.19-m68k-cvs/arch/m68k/atari/natfeat.c     2006-12-08 
18:49:02.000000000 +0100
+++ linux-2.6.19-m68k/arch/m68k/atari/natfeat.c 2006-12-08 18:49:02.000000000 
+0100
@@ -0,0 +1,231 @@
+/*
+ * natfeat.c - ARAnyM hardware support via Native Features (natfeats)
+ *
+ * Copyright (c) 2005 Petr Stehlik of ARAnyM dev team
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ */
+
+// #include <linux/config.h>
+#include <linux/types.h>
+#include <linux/string.h> // strncpy()
+#include <linux/kernel.h> // snprintf()
+#include <asm/io.h> // virt_to_phys()
+
+#include "natfeat.h"
+
+#ifdef CONFIG_ATARI_NFETH
+#include "natfeat_ethernet_nfapi.h"
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+static unsigned long nf_get_id_instr = 0x73004e75UL;
+static unsigned long nf_call_instr = 0x73014e75UL;
+
+static struct nf_ops _nf_ops = { &nf_get_id_instr, &nf_call_instr }; 
+static struct nf_ops *nf_ops = NULL; 
+
+#define NF_GETID(a)            nf_ops->get_id(virt_to_phys(a))
+
+int detect_native_features(void)
+{
+    int                ret;
+    long       save_sp, save_vbr;
+    static long tmp_vectors[5];
+    static char *nf_version = "NF_VERSION";
+       
+    __asm__ __volatile__
+       (       "movec  %/vbr,%2\n\t"   /* save vbr value            */
+               "movel  #Liierr,%3@(0x10)\n\t" /* set Illegal Insn vec */
+               "movec  %3,%/vbr\n\t"   /* set up temporary vectors  */
+               "movel  %/sp,%1\n\t"    /* save sp                   */
+               "moveq  #0,%0\n\t"              /* assume no NatFeats        */
+               "clrl   %/d0\n\t"               /* clear ID value register   */
+               "movel  %4,%/[EMAIL PROTECTED]"
+               "subql  #4,%/sp\n\t"
+               "dc     0x7300\n\t"                     /* call NatFeat GetID   
     */
+               "tstl   %/d0\n\t"               /* check ID value register   */
+               "sne    %0\n\t"                 /* if non-zero NatFeats work */
+               "Liierr:\n\t"
+               "movel  %1,%/sp\n\t"    /* restore sp                */
+               "movec  %2,%/vbr"               /* restore vbr               */
+               : "=&d" (ret), "=&r" (save_sp), "=&r" (save_vbr)
+               : "a" (tmp_vectors), "a" (virt_to_phys(nf_version))
+               : "d0"                                  /* reg d0 used by 
NatFeats   */
+        );
+
+    return( ret );
+}
+
+struct nf_ops * nf_init(void)
+{
+       if (detect_native_features()) {
+               nf_ops = &_nf_ops;
+               nf_debug("NatFeats found\n");
+               return nf_ops;
+       }
+       
+       return NULL;
+}
+
+/****************/
+/* NF Basic Set */
+int nf_name1(char *buf, int bufsize)
+{
+       if (nf_ops) {
+               static long nfid_name = 0;
+               if (nfid_name == 0) {
+                       nfid_name = NF_GETID("NF_NAME");
+               }
+
+               if (nfid_name) {
+                       nf_ops->call(nfid_name+1, virt_to_phys(buf), bufsize); 
// TODO: lock buf to prevent swap out
+                       return TRUE;
+               }
+       }
+        
+       return FALSE;
+}
+
+int nf_debug(const char *msg)
+{
+       if (nf_ops) {
+               static long nfid_stderr = 0;
+               if (nfid_stderr == 0) {
+                       nfid_stderr = NF_GETID("NF_STDERR");
+               }
+               
+               if (nfid_stderr) {
+                       nf_ops->call(nfid_stderr, virt_to_phys(msg)); // TODO: 
lock msg to prevent swap out
+                       return TRUE;
+               }
+       }
+       
+       return FALSE;
+}
+
+int nf_shutdown(void)
+{
+       if (nf_ops) {
+               long shutdown_id = NF_GETID("NF_SHUTDOWN");
+               
+               if (shutdown_id) {
+                       nf_ops->call(shutdown_id);
+                       return TRUE; /* never returns actually */
+               }
+       }
+
+       return FALSE;
+}
+
+#ifdef CONFIG_ATARI_NFETH
+
+/****************************/
+/* NatFeat Ethernet support */
+static long nfEtherID = 0;
+
+static int is_nf_eth(void)
+{
+       if (nf_ops) {
+               if (nfEtherID == 0) {
+                       nfEtherID = NF_GETID("ETHERNET");
+               }
+       }
+       return (nfEtherID != 0);
+}
+
+int nf_ethernet_check_version(char *errmsg, int errmsglen)
+{
+       if (is_nf_eth()) {
+               static unsigned long host_ver = 0;
+               if (host_ver == 0) {
+                       host_ver = nf_ops->call(ETH(GET_VERSION));
+               }
+               if (host_ver == ARAETHER_NFAPI_VERSION) {
+                       return TRUE;
+               }
+               else {
+                       // API version mismatch
+                       if (errmsg != NULL) {
+                               snprintf(errmsg, errmsglen,
+                                       "NatFeat Ethernet API: expected %d, got 
%ld",
+                                       ARAETHER_NFAPI_VERSION, host_ver);
+                       }
+                       return FALSE;
+               }
+       }
+       if (errmsg != NULL) {
+               strncpy(errmsg, "NatFeat Ethernet support not found", 
errmsglen);
+       }
+       return FALSE;
+}
+
+int nf_ethernet_get_irq(void)
+{
+       return is_nf_eth() ? nf_ops->call(ETH(XIF_INTLEVEL)) : 0;
+}
+
+int nf_ethernet_get_hw_addr(int ethX, char *buffer, int bufsize)
+{
+       if (is_nf_eth()) {
+               return nf_ops->call(ETH(XIF_GET_MAC), (unsigned long)ethX, 
virt_to_phys(buffer), (unsigned long)bufsize); // TODO: lock buffer to prevent 
swap out
+       }
+       return FALSE;
+}
+
+int nf_ethernet_interrupt(int bit)
+{
+       if (is_nf_eth()) {
+               return nf_ops->call(ETH(XIF_IRQ), (unsigned long)bit);
+       }
+       return 0;
+}
+
+int nf_ethernet_read_packet_len(int ethX)
+{
+       if (is_nf_eth()) {
+               return nf_ops->call(ETH(XIF_READLENGTH), (unsigned long)ethX);
+       }
+       return 0;
+}
+
+void nf_ethernet_read_block(int ethX, char *buffer, int len)
+{
+       if (is_nf_eth()) {
+               nf_ops->call(ETH(XIF_READBLOCK), (unsigned long)ethX, 
virt_to_phys(buffer), (unsigned long)len); // TODO: lock buffer to prevent swap 
out
+       }
+}
+
+void nf_ethernet_write_block(int ethX, char *buffer, int len)
+{
+       if (is_nf_eth()) {
+               nf_ops->call(ETH(XIF_WRITEBLOCK), (unsigned long)ethX, 
virt_to_phys(buffer), (unsigned long)len); // TODO: lock buffer to prevent swap 
out
+       }
+}
+
+void nf_ethernet_xif_start(int ethX)
+{
+       if (is_nf_eth()) {
+               nf_ops->call(ETH(XIF_START), (unsigned long)ethX);
+       }
+}
+
+void nf_ethernet_xif_stop(int ethX)
+{
+       if (is_nf_eth()) {
+               nf_ops->call(ETH(XIF_STOP), (unsigned long)ethX);
+       }
+}
+#endif // CONFIG_ATARI_NFETH
+
+/*
+vim:ts=4:sw=4:
+*/
--- linux-2.6.19-m68k-cvs/arch/m68k/atari/natfeat_ethernet_nfapi.h      
2006-12-08 18:49:02.000000000 +0100
+++ linux-2.6.19-m68k/arch/m68k/atari/natfeat_ethernet_nfapi.h  2006-12-08 
18:49:02.000000000 +0100
@@ -0,0 +1,56 @@
+/*
+ * ARAnyM ethernet driver - header file.
+ *
+ * Copyright (c) 2002-2004 Standa and Petr of ARAnyM dev team (see AUTHORS)
+ * 
+ * This file is part of the ARAnyM project which builds a new and powerful
+ * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
+ *
+ * ARAnyM is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ARAnyM is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ARAnyM; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ARAETHER_NFAPI_H
+#define _ARAETHER_NFAPI_H
+
+/*
+   The code for the FreeMiNT driver was moved to the FreeMiNT CVS:
+   freemint/sys/sockets/xif/nfeth.
+
+   If you edit this file then you would need to synchronize it with the
+   driver in the freemint CVS (nfeth_nfapi.h).
+
+   if you change anything in the enum {} below you have to increase 
+   this ARAETHER_NFAPI_VERSION!
+*/
+#define ARAETHER_NFAPI_VERSION 0x00000005
+
+enum {
+       GET_VERSION = 0,        /* no parameters, return NFAPI_VERSION in d0 */
+       XIF_INTLEVEL,           /* no parameters, return Interrupt Level in d0 
*/
+       XIF_IRQ,                        /* acknowledge interrupt from host */
+       XIF_START,                      /* (ethX), called on 'ifup', start 
receiver thread */
+       XIF_STOP,                       /* (ethX), called on 'ifdown', stop the 
thread */
+       XIF_READLENGTH,         /* (ethX), return size of network data block to 
read */
+       XIF_READBLOCK,          /* (ethX, buffer, size), read block of network 
data */
+       XIF_WRITEBLOCK,         /* (ethX, buffer, size), write block of network 
data */
+       XIF_GET_MAC,            /* (ethX, buffer, size), return MAC HW addr in 
buffer */
+       XIF_GET_IPHOST,         /* (ethX, buffer, size), return IP address of 
host */
+       XIF_GET_IPATARI,        /* (ethX, buffer, size), return IP address of 
atari */
+       XIF_GET_NETMASK         /* (ethX, buffer, size), return IP netmask */
+};
+
+#define ETH(a) (nfEtherID + a)
+
+#endif /* _ARAETHER_NFAPI_H */
--- linux-2.6.19-m68k-cvs/arch/m68k/Kconfig     2006-09-03 17:54:52.000000000 
+0200
+++ linux-2.6.19-m68k/arch/m68k/Kconfig 2006-12-09 17:12:36.000000000 +0100
@@ -132,6 +132,31 @@
          information about which PCI hardware does work under Linux and which
          doesn't.
 
+config ATARI_ROM_ISA
+       bool "Atari ROM port ISA adapter support"
+       depends on ATARI
+       help
+         This option enables support for the ROM port ISA adapter used to 
+         operate ISA cards on Atari. Only 8  bit cards are supported, and
+         no interrupt lines are connected. 
+         The only driver currently using this adapter is the EtherNEC
+         driver for RTL8019AS based NE2000 compatible network cards.
+
+config ARANYM
+       bool "ARAnyM emulator support "
+       depends on ATARI
+       help
+         This option enables support for the ARAnyM emulator support
+         features. To use this kernel on ARAnyM, say Y here; otherwise say N.
+
+config NATFEAT
+       bool
+       depends on ARANYM
+       default y
+       help
+         This option enables support for ARAnyM native features, such as 
+         access to a disk image as /dev/hda. Useful with the ARANYM option.
+
 config MAC
        bool "Macintosh support"
        depends on !MMU_SUN3
--- linux-2.6.19-m68k-cvs/drivers/net/Makefile  2006-12-02 01:02:10.000000000 
+0100
+++ linux-2.6.19-m68k/drivers/net/Makefile      2006-12-09 17:13:01.000000000 
+0100
@@ -177,6 +177,8 @@
 obj-$(CONFIG_ATARILANCE) += atarilance.o
 obj-$(CONFIG_ATARI_BIONET) += atari_bionet.o
 obj-$(CONFIG_ATARI_PAMSNET) += atari_pamsnet.o
+obj-$(CONFIG_ATARI_NFETH) += atari_nfeth.o
+obj-$(CONFIG_ATARI_ETHERNEC) += atari_ethernec.o 8390.o
 obj-$(CONFIG_A2065) += a2065.o
 obj-$(CONFIG_HYDRA) += hydra.o 8390.o
 obj-$(CONFIG_ARIADNE) += ariadne.o
--- linux-2.6.19-m68k-cvs/drivers/net/Kconfig   2006-12-02 03:51:45.000000000 
+0100
+++ linux-2.6.19-m68k/drivers/net/Kconfig       2006-12-09 17:13:01.000000000 
+0100
@@ -397,6 +397,22 @@
          ACSI port ("ACSI node"). The driver works (has to work...) with a
          polled I/O scheme, so it's rather slow :-(
 
+config ATARI_NFETH
+       tristate "Atari NatFeat Ethernet support"
+       depends on NET_ETHERNET && ATARI && NATFEAT
+       help
+         Say Y to include support for the ARAnyM NatFeat network device
+         which will emulate a regular ethernet device while presenting an
+         ethertap device to the host system.
+
+config ATARI_ETHERNEC
+       tristate "Atari EtherNEC Ethernet support"
+       depends on NET_ETHERNET && ATARI && 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 SUN3LANCE
        tristate "Sun3/Sun3x on-board LANCE support"
        depends on NET_ETHERNET && (SUN3 || SUN3X)
--- linux-2.6.19-m68k-cvs/drivers/net/Space.c   2006-12-02 01:02:11.000000000 
+0100
+++ linux-2.6.19-m68k/drivers/net/Space.c       2006-12-09 17:13:01.000000000 
+0100
@@ -74,6 +74,8 @@
 extern struct net_device *seeq8005_probe(int unit);
 extern struct net_device *smc_init(int unit);
 extern struct net_device *atarilance_probe(int unit);
+extern struct net_device *atari_ethernec_probe(int unit);
+extern struct net_device *atari_nfeth_probe(struct net_device *);
 extern struct net_device *sun3lance_probe(int unit);
 extern struct net_device *sun3_82586_probe(int unit);
 extern struct net_device *apne_probe(int unit);
@@ -261,6 +263,12 @@
 #ifdef CONFIG_ATARILANCE       /* Lance-based Atari ethernet boards */
        {atarilance_probe, 0},
 #endif
+#ifdef CONFIG_ATARI_NFETH      /* ARAnyM tun/tap device */
+       {atari_nfeth_probe, 0},
+#endif
+#ifdef CONFIG_ATARI_ETHERNEC   /* NE2000 based ROM port ethernet cards */
+       {atari_ethernec_probe, 0},
+#endif
 #ifdef CONFIG_SUN3LANCE         /* sun3 onboard Lance chip */
        {sun3lance_probe, 0},
 #endif
--- linux-2.6.19-m68k-cvs/drivers/net/atari_nfeth.c     2006-12-08 
18:49:02.000000000 +0100
+++ linux-2.6.19-m68k/drivers/net/atari_nfeth.c 2006-12-08 18:49:02.000000000 
+0100
@@ -0,0 +1,327 @@
+/*
+ * atari_nfeth.c - ARAnyM ethernet card driver for GNU/Linux
+ *
+ * Copyright (c) 2005 Milan Jurik, Petr Stehlik of ARAnyM dev team
+ *
+ * Based on ARAnyM driver for FreeMiNT written by Standa Opichal
+ * 
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <asm/atariints.h>
+
+#include "../../arch/m68k/atari/natfeat.h"
+
+#define DRV_NAME        "atari_nfeth"
+#define DRV_VERSION     "0.3"
+#define DRV_RELDATE     "10/12/2005"
+
+/* These identify the driver base version and may not be removed. */
+static char version[] __devinitdata =
+KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " S.Opichal, M.Jurik, 
P.Stehlik\n"
+KERN_INFO "  http://aranym.atari.org/\n";;
+
+MODULE_AUTHOR("Milan Jurik");
+MODULE_DESCRIPTION("Atari NFeth driver");
+MODULE_LICENSE("GPL");
+/*
+MODULE_PARM(atari_nfeth_debug, "i");
+MODULE_PARM_DESC(atari_nfeth_debug, "atari_nfeth_debug level (1-2)");
+*/
+
+#undef DEBUG
+
+struct atari_nfeth_private {
+       int ethX;
+       struct net_device_stats stats;
+       spinlock_t lock;
+};
+
+static inline int getEthX(struct net_device *dev)
+{
+       return ((struct atari_nfeth_private *)netdev_priv(dev))->ethX;
+}
+
+int atari_nfeth_open(struct net_device *dev);
+int atari_nfeth_stop(struct net_device *dev);
+irqreturn_t atari_nfeth_interrupt(int irq, void *dev_id, struct pt_regs *fp);
+int atari_nfeth_xmit(struct sk_buff *skb, struct net_device *dev);
+
+int atari_nfeth_open(struct net_device *dev)
+{
+       nf_ethernet_xif_start(getEthX(dev));
+
+       /* Set IRQ */
+       dev->irq = nf_ethernet_get_irq();
+       if (request_irq(dev->irq, atari_nfeth_interrupt, IRQ_TYPE_PRIO, 
dev->name, dev)) {
+               printk( DRV_NAME ": request for irq %d failed\n", dev->irq);
+               return( 0 );
+       }
+
+       /* Clean statistics */
+       memset(&(((struct atari_nfeth_private *)netdev_priv(dev))->stats), 0, 
sizeof(((struct atari_nfeth_private *)(dev->priv))->stats));
+
+       spin_lock_init(&(((struct atari_nfeth_private 
*)netdev_priv(dev))->lock));
+
+#ifdef DEBUG
+       printk( DRV_NAME ": open");
+#endif
+
+       /* Ready for data */
+       netif_start_queue(dev);
+
+       return 0;
+}
+
+int atari_nfeth_stop(struct net_device *dev)
+{
+       /* No more data */
+       netif_stop_queue(dev);
+
+       /* Release IRQ */
+       free_irq(dev->irq, dev);
+
+       nf_ethernet_xif_stop(getEthX(dev));
+
+       return 0;
+}
+
+/*
+ * Read a packet out of the adapter and pass it to the upper layers
+ */
+static irqreturn_t inline recv_packet (struct net_device *dev)
+{
+       int handled = 0;
+       unsigned short pktlen;
+       struct sk_buff *skb;
+       struct atari_nfeth_private *anp = (struct atari_nfeth_private 
*)netdev_priv(dev);
+
+       if (dev == NULL) {
+               printk(DRV_NAME " recv_packet(): interrupt for unknown 
device.\n");
+               return IRQ_NONE;
+       }
+
+       /* read packet length (excluding 32 bit crc) */
+       pktlen = nf_ethernet_read_packet_len(getEthX(dev));
+
+#ifdef DEBUG
+       printk(DRV_NAME ": recv_packet: %i", pktlen);
+#endif
+
+       //if (pktlen < 32)
+       if (!pktlen)
+       {
+#ifdef DEBUG
+               printk(DRV_NAME ": recv_packet: pktlen == 0");
+#endif
+               anp->stats.rx_errors++;
+               return IRQ_RETVAL(handled);
+       }
+
+       skb = dev_alloc_skb(pktlen + 2);
+       if (skb == NULL)
+       {
+#ifdef DEBUG
+               printk(DRV_NAME ": recv_packet: out of mem (buf_alloc failed)");
+#endif
+               anp->stats.rx_dropped++;
+               return IRQ_RETVAL(handled);
+       }
+
+       skb->dev = dev;
+       skb_reserve( skb, 2 );          /* 16 Byte align  */
+       skb_put( skb, pktlen ); /* make room */
+       nf_ethernet_read_block(getEthX(dev), skb->data, pktlen);
+
+       skb->protocol = eth_type_trans(skb, dev);
+       netif_rx(skb);
+       dev->last_rx = jiffies;
+       anp->stats.rx_packets++;
+       anp->stats.rx_bytes += pktlen;
+
+       /* and enqueue packet */
+       handled = 1;
+       return IRQ_RETVAL(handled);
+}
+
+irqreturn_t atari_nfeth_interrupt(int irq, void *dev_id, struct pt_regs *fp)
+{
+       struct net_device *dev = dev_id;
+       struct atari_nfeth_private *anp = (struct atari_nfeth_private 
*)netdev_priv(dev);
+       int this_dev_irq_bit;
+       int irq_for_eth_bitmask;
+       if (dev == NULL) {
+#ifdef DEBUG
+               printk(DRV_NAME " atari_nfeth_interrupt(): interrupt for 
unknown device.\n");
+#endif
+               return IRQ_NONE;
+       }
+       spin_lock(&anp->lock);
+       irq_for_eth_bitmask = nf_ethernet_interrupt(0);
+       this_dev_irq_bit = 1 << (anp->ethX);
+       if (this_dev_irq_bit & irq_for_eth_bitmask) {
+               recv_packet(dev);
+               nf_ethernet_interrupt(this_dev_irq_bit);
+       }
+#ifdef DEBUG
+       else {
+               printk(DRV_NAME " atari_nfeth_interrupt(%d): not for me\n", 
anp->ethX);
+       }
+#endif
+       spin_unlock(&anp->lock);
+}
+
+int atari_nfeth_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       int len;
+       char *data, shortpkt[ETH_ZLEN];
+       struct atari_nfeth_private *anp = netdev_priv(dev);
+
+       data = skb->data;
+       len = skb->len;
+       if (len < ETH_ZLEN) {
+               memset(shortpkt, 0, ETH_ZLEN);
+               memcpy(shortpkt, data, len);
+               data = shortpkt;
+               len = ETH_ZLEN;
+       }
+
+       dev->trans_start = jiffies;
+       
+#ifdef DEBUG
+       printk( DRV_NAME ": send %d bytes", len);
+#endif
+       nf_ethernet_write_block(getEthX(dev), data, len);
+
+       anp->stats.tx_packets++;
+       anp->stats.tx_bytes += len;
+
+       dev_kfree_skb(skb);
+       return 0;
+}
+
+static void atari_nfeth_tx_timeout(struct net_device *dev)
+{
+       struct atari_nfeth_private *anp = netdev_priv(dev);
+       anp->stats.tx_errors++;
+       netif_wake_queue(dev);
+}
+
+static struct net_device_stats *atari_nfeth_get_stats(struct net_device *dev)
+{
+       struct atari_nfeth_private *anp = netdev_priv(dev);
+       return &(anp->stats);
+}
+
+// probe1() - HW detection
+// probe() - set module owner, found == 1, probe1()
+// init() - probe()
+
+static int __init atari_nfeth_probe1(struct net_device *dev, int ethX)
+{
+       static int did_version = 0;
+       static int did_notinstall = 0;
+       char errmsg[60];
+
+       if ( ! nf_ethernet_check_version(errmsg, sizeof(errmsg)-1) ) {
+               if (did_notinstall++ == 0)
+                       printk (DRV_NAME " not installed - %s\n", errmsg);
+                return -ENODEV;
+        }
+
+       /* Get MAC address */
+       if (! nf_ethernet_get_hw_addr(ethX, (unsigned char *)&(dev->dev_addr), 
ETH_ALEN)) {
+#ifdef DEBUG
+               printk(DRV_NAME " eth%d not installed - not defined\n", ethX);
+#endif
+               return -ENODEV;
+       }
+
+       ether_setup(dev);
+
+       dev->open = &atari_nfeth_open;
+       dev->stop = &atari_nfeth_stop;
+       dev->hard_start_xmit = &atari_nfeth_xmit;
+       dev->tx_timeout = &atari_nfeth_tx_timeout;
+       dev->get_stats = &atari_nfeth_get_stats;
+       dev->flags |= NETIF_F_NO_CSUM;
+
+       //if ((dev->priv = kmalloc(sizeof(struct atari_nfeth_private), 
GFP_KERNEL)) == NULL)
+       //      return -ENOMEM;
+       ((struct atari_nfeth_private *)(dev->priv))->ethX = ethX; /* index of 
NF NIC */
+
+       if (did_version++ == 0)
+               printk(version);
+
+       return 0;
+}
+
+struct net_device * __init atari_nfeth_probe(int unit)
+{
+        int err;
+       static int found = 0;
+       struct net_device *dev;
+
+       dev = alloc_etherdev(sizeof(struct atari_nfeth_private));
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
+       if (unit >= 0) {
+               sprintf(dev->name, "eth%d", unit);
+               netdev_boot_setup_check(dev);
+       }
+       SET_MODULE_OWNER(dev);
+
+       if (!atari_nfeth_probe1(dev, found++)) {
+               err = register_netdev(dev);
+               if (err == -EIO)  {
+                       printk(DRV_NAME ": NatFeat Ethernet not found. Module 
not loaded.\n");
+               }
+               if (!err)
+                       return dev;
+       }
+
+       return ERR_PTR(-ENODEV);
+}
+
+#ifdef MODULE
+static struct net_device * atari_nfeth_dev;
+
+int atari_nfeth_init(void)
+{
+       // int err;
+
+       if (IS_ERR(atari_nfeth_dev = atari_nfeth_probe(0))) {
+               return PTR_ERR((atarilance_dev);
+       }
+
+       // ? atari_nfeth_dev.init = atari_nfeth_probe;
+#if 0
+       if ((err = register_netdev(&atari_nfeth_dev))) {
+               if (err == -EIO)  {
+                       printk(DRV_NAME ": NatFeat Ethernet not found. Module 
not loaded.\n");
+               }
+               return err;
+       }
+#endif
+
+        return 0;
+}
+
+void atari_nfeth_cleanup(void)
+{
+        unregister_netdev(&atari_nfeth_dev);
+        free_netdev(atari_nfeth_dev); // ?
+}
+
+module_init(atari_nfeth_init);
+module_exit(atari_nfeth_cleanup);
+
+#endif /* MODULE */
+
+/*
+vim:ts=4:sw=4:
+*/

Reply via email to