[PATCH] 2.6.19 m68k Atari: ARAnyM support

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

 



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,%/sp@\n\t"
+		"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:
+*/

[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux