netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Ethernet driver for EISA only SNI RM200/RM400 machines
@ 2007-06-22 19:53 Thomas Bogendoerfer
  2007-06-23 16:53 ` Andrew Morton
  0 siblings, 1 reply; 2+ messages in thread
From: Thomas Bogendoerfer @ 2007-06-22 19:53 UTC (permalink / raw)
  To: netdev; +Cc: akpm, jgarzik

Hi,

This is new ethernet driver, which use the code taken out of lasi_82596
(done by the other patch I just sent).

Thomas.


Ethernet driver for EISA only SNI RM200/RM400 machines

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b0d0d73..af5c90f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -435,6 +435,13 @@ config LASI_82596
 	  Say Y here to support the builtin Intel 82596 ethernet controller
 	  found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
 
+config SNI_82596
+	tristate "SNI RM ethernet"
+	depends on NET_ETHERNET && SNI_RM
+	help
+	  Say Y here to support the on-board Intel 82596 ethernet controller
+	  built into SNI RM machines.
+
 config MIPS_JAZZ_SONIC
 	tristate "MIPS JAZZ onboard SONIC Ethernet support"
 	depends on NET_ETHERNET && MACH_JAZZ
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index d268b49..b03270c 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -161,6 +161,7 @@ obj-$(CONFIG_ELPLUS) += 3c505.o
 obj-$(CONFIG_AC3200) += ac3200.o 8390.o
 obj-$(CONFIG_APRICOT) += 82596.o
 obj-$(CONFIG_LASI_82596) += lasi_82596.o
+obj-$(CONFIG_SNI_82596) += sni_82596.o
 obj-$(CONFIG_MVME16x_NET) += 82596.o
 obj-$(CONFIG_BVME6000_NET) += 82596.o
 obj-$(CONFIG_SC92031) += sc92031.o
diff --git a/drivers/net/sni_82596.c b/drivers/net/sni_82596.c
new file mode 100644
index 0000000..a37d08a
--- /dev/null
+++ b/drivers/net/sni_82596.c
@@ -0,0 +1,204 @@
+/*
+ * sni_82596.c -- driver for intel 82596 ethernet controller, as
+ *  		  used in older SNI RM machines
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#define SNI_82596_DRIVER_VERSION "SNI RM 82596 driver - Revision: 0.01"
+
+static char sni_82596_string[] = "snirm_82596";
+
+#define DMA_ALLOC                      dma_alloc_coherent
+#define DMA_FREE                       dma_free_coherent
+#define DMA_WBACK(priv, addr, len)     do { } while (0)
+#define DMA_INV(priv, addr, len)       do { } while (0)
+#define DMA_WBACK_INV(priv, addr, len) do { } while (0)
+
+#define SYSBUS      0x00004400
+
+/* big endian CPU, 82596 little endian */
+#define SWAP32(x)   cpu_to_le32((u32)(x))
+#define SWAP16(x)   cpu_to_le16((u16)(x))
+
+#define OPT_MPU_16BIT    0x01
+
+static inline void CA(struct net_device *dev);
+static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x);
+
+#include "lib82596.c"
+
+MODULE_AUTHOR("Thomas Bogendoerfer");
+MODULE_DESCRIPTION("i82596 driver");
+MODULE_LICENSE("GPL");
+module_param(i596_debug, int, 0);
+MODULE_PARM_DESC(i596_debug, "82596 debug mask");
+
+static inline void CA(struct net_device *dev)
+{
+	struct i596_private *lp = netdev_priv(dev);
+	
+	writel(0, lp->ca);
+}
+
+
+static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x)
+{
+	struct i596_private *lp = netdev_priv(dev);
+
+	u32 v = (u32) (c) | (u32) (x);
+	
+	if (lp->options & OPT_MPU_16BIT) {
+		writew(v & 0xffff, lp->mpu_port);
+		wmb(); udelay(1); /* order writes to MPU port */
+		writew(v >> 16, lp->mpu_port);
+	} else {
+		writel(v, lp->mpu_port);
+		wmb(); udelay(1); /* order writes to MPU port */
+		writel(v, lp->mpu_port);
+	}
+}
+
+
+static int __devinit sni_82596_probe(struct platform_device *dev)
+{
+	struct	net_device *netdevice;
+	struct i596_private *lp;
+	struct  resource *res, *ca, *idprom, *options;
+	int	retval = -ENODEV;
+	static int init;
+	void __iomem *mpu_addr = NULL;
+	void __iomem *ca_addr = NULL;
+	u8 __iomem *eth_addr = NULL;
+	
+	if (init == 0) {
+		printk(KERN_INFO SNI_82596_DRIVER_VERSION "\n");
+		init++;
+	}
+	
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res)
+		goto probe_failed;
+	mpu_addr = ioremap_nocache(res->start, 4);
+	if (!mpu_addr) {
+		retval = -ENOMEM;
+		goto probe_failed;
+	}
+	ca = platform_get_resource(dev, IORESOURCE_MEM, 1);
+	if (!ca)
+		goto probe_failed;
+	ca_addr = ioremap_nocache(ca->start, 4);
+	if (!ca_addr) {
+		retval = -ENOMEM;
+		goto probe_failed;
+	}
+	idprom = platform_get_resource(dev, IORESOURCE_MEM, 2);
+	if (!idprom)
+		goto probe_failed;
+	eth_addr = ioremap_nocache(idprom->start, 0x10);
+	if (!eth_addr) {
+		retval = -ENOMEM;
+		goto probe_failed;
+	}
+	options = platform_get_resource(dev, 0, 0);
+	if (!options)
+		goto probe_failed;
+
+	printk(KERN_INFO "Found i82596 at 0x%x\n", res->start);
+
+	netdevice = alloc_etherdev(sizeof(struct i596_private));
+	if (!netdevice) {
+		retval = -ENOMEM;
+		goto probe_failed;
+	}
+	SET_NETDEV_DEV(netdevice, &dev->dev);
+	platform_set_drvdata (dev, netdevice);
+
+	netdevice->base_addr = res->start;
+	netdevice->irq = platform_get_irq(dev, 0);
+		
+	/* someone seams to like messed up stuff */
+	netdevice->dev_addr[0] = readb(eth_addr + 0x0b);
+	netdevice->dev_addr[1] = readb(eth_addr + 0x0a);
+	netdevice->dev_addr[2] = readb(eth_addr + 0x09);
+	netdevice->dev_addr[3] = readb(eth_addr + 0x08);
+	netdevice->dev_addr[4] = readb(eth_addr + 0x07);
+	netdevice->dev_addr[5] = readb(eth_addr + 0x06);
+	iounmap(eth_addr);
+	
+	if (!netdevice->irq) {
+		printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
+			__FILE__, netdevice->base_addr);
+		goto probe_failed;
+	}
+	
+	lp = netdev_priv(netdevice);
+	lp->options = options->flags & IORESOURCE_BITS;
+	lp->ca = ca_addr;
+	lp->mpu_port = mpu_addr;
+	
+	retval = i82596_probe(netdevice);
+	if (retval) {
+		free_netdev(netdevice);
+probe_failed:
+		if (mpu_addr)
+			iounmap(mpu_addr);
+		if (ca_addr)
+			iounmap(ca_addr);
+		if (eth_addr)
+			iounmap(ca_addr);
+	}
+	return retval;
+}
+
+static int __devexit sni_82596_driver_remove (struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct i596_private *lp = netdev_priv(dev);
+
+	unregister_netdev (dev);
+	DMA_FREE(dev->dev.parent, sizeof(struct i596_private),
+		 lp->dma, lp->dma_addr);
+	iounmap(lp->ca);
+	iounmap(lp->mpu_port);
+	free_netdev (dev);
+	return 0;
+}
+
+static struct platform_driver sni_82596_driver = {
+	.probe	= sni_82596_probe,
+	.remove	= __devexit_p(sni_82596_driver_remove),
+	.driver	= {
+		.name	= sni_82596_string,
+	},
+};
+
+static int __devinit sni_82596_init(void)
+{
+	return platform_driver_register(&sni_82596_driver);
+}
+
+
+static void __exit sni_82596_exit(void)
+{
+	platform_driver_unregister(&sni_82596_driver);
+}
+
+module_init(sni_82596_init);
+module_exit(sni_82596_exit);



-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.                                                [ RFC1925, 2.3 ]

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] Ethernet driver for EISA only SNI RM200/RM400 machines
  2007-06-22 19:53 [PATCH] Ethernet driver for EISA only SNI RM200/RM400 machines Thomas Bogendoerfer
@ 2007-06-23 16:53 ` Andrew Morton
  0 siblings, 0 replies; 2+ messages in thread
From: Andrew Morton @ 2007-06-23 16:53 UTC (permalink / raw)
  To: Thomas Bogendoerfer; +Cc: netdev, jgarzik

> On Fri, 22 Jun 2007 21:53:58 +0200 tsbogend@alpha.franken.de (Thomas Bogendoerfer) wrote:
> Hi,
> 
> This is new ethernet driver, which use the code taken out of lasi_82596
> (done by the other patch I just sent).
> 
> Thomas.
> 
> 
> Ethernet driver for EISA only SNI RM200/RM400 machines
> 
> ...
>
> +static char sni_82596_string[] = "snirm_82596";

const?

> +
> +#define DMA_ALLOC                      dma_alloc_coherent
> +#define DMA_FREE                       dma_free_coherent
> +#define DMA_WBACK(priv, addr, len)     do { } while (0)
> +#define DMA_INV(priv, addr, len)       do { } while (0)
> +#define DMA_WBACK_INV(priv, addr, len) do { } while (0)
> +
> +#define SYSBUS      0x00004400
> +
> +/* big endian CPU, 82596 little endian */
> +#define SWAP32(x)   cpu_to_le32((u32)(x))
> +#define SWAP16(x)   cpu_to_le16((u16)(x))
> +
> +#define OPT_MPU_16BIT    0x01
> +
> +static inline void CA(struct net_device *dev);
> +static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x);

These two function's implementations could be moved to before the #include,
s we wouldn't need to forward-declare them?

> +#include "lib82596.c"

ugh.  Is this really unavoidable?

> +MODULE_AUTHOR("Thomas Bogendoerfer");
> +MODULE_DESCRIPTION("i82596 driver");
> +MODULE_LICENSE("GPL");
> +module_param(i596_debug, int, 0);
> +MODULE_PARM_DESC(i596_debug, "82596 debug mask");
> +
> +static inline void CA(struct net_device *dev)
> +{
> +	struct i596_private *lp = netdev_priv(dev);
> +	
> +	writel(0, lp->ca);
> +}
> +
> +
> +static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x)
> +{
> +	struct i596_private *lp = netdev_priv(dev);
> +
> +	u32 v = (u32) (c) | (u32) (x);
> +	
> +	if (lp->options & OPT_MPU_16BIT) {
> +		writew(v & 0xffff, lp->mpu_port);
> +		wmb(); udelay(1); /* order writes to MPU port */

Nope, please put these on separate lines.  No exceptions..

> +		writew(v >> 16, lp->mpu_port);
> +	} else {
> +		writel(v, lp->mpu_port);
> +		wmb(); udelay(1); /* order writes to MPU port */
> +		writel(v, lp->mpu_port);
> +	}
> +}

Three callsites: This looks too large to inline.

I see no reason why this and CA() are have upper-case names?

> +
> +static int __devinit sni_82596_probe(struct platform_device *dev)
> +{
> +	struct	net_device *netdevice;
> +	struct i596_private *lp;
> +	struct  resource *res, *ca, *idprom, *options;
> +	int	retval = -ENODEV;
> +	static int init;
> +	void __iomem *mpu_addr = NULL;
> +	void __iomem *ca_addr = NULL;
> +	u8 __iomem *eth_addr = NULL;
> +	
> +	if (init == 0) {
> +		printk(KERN_INFO SNI_82596_DRIVER_VERSION "\n");
> +		init++;
> +	}

Might as well do this message in the module_init() function?  There's a
per-probed-device message later on anwyay.

The patchset tries to add rather a lot of new trailing whitespace btw.

> +	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		goto probe_failed;
> +	mpu_addr = ioremap_nocache(res->start, 4);
> +	if (!mpu_addr) {
> +		retval = -ENOMEM;
> +		goto probe_failed;
> +	}
> +	ca = platform_get_resource(dev, IORESOURCE_MEM, 1);
> +	if (!ca)
> +		goto probe_failed;
> +	ca_addr = ioremap_nocache(ca->start, 4);
> +	if (!ca_addr) {
> +		retval = -ENOMEM;
> +		goto probe_failed;
> +	}
> +	idprom = platform_get_resource(dev, IORESOURCE_MEM, 2);
> +	if (!idprom)
> +		goto probe_failed;
> +	eth_addr = ioremap_nocache(idprom->start, 0x10);
> +	if (!eth_addr) {
> +		retval = -ENOMEM;
> +		goto probe_failed;
> +	}
> +	options = platform_get_resource(dev, 0, 0);
> +	if (!options)
> +		goto probe_failed;
> +
> +	printk(KERN_INFO "Found i82596 at 0x%x\n", res->start);
> +
> +	netdevice = alloc_etherdev(sizeof(struct i596_private));
> +	if (!netdevice) {
> +		retval = -ENOMEM;
> +		goto probe_failed;
> +	}
> +	SET_NETDEV_DEV(netdevice, &dev->dev);
> +	platform_set_drvdata (dev, netdevice);
> +
> +	netdevice->base_addr = res->start;
> +	netdevice->irq = platform_get_irq(dev, 0);
> +		
> +	/* someone seams to like messed up stuff */
> +	netdevice->dev_addr[0] = readb(eth_addr + 0x0b);
> +	netdevice->dev_addr[1] = readb(eth_addr + 0x0a);
> +	netdevice->dev_addr[2] = readb(eth_addr + 0x09);
> +	netdevice->dev_addr[3] = readb(eth_addr + 0x08);
> +	netdevice->dev_addr[4] = readb(eth_addr + 0x07);
> +	netdevice->dev_addr[5] = readb(eth_addr + 0x06);
> +	iounmap(eth_addr);
> +	
> +	if (!netdevice->irq) {
> +		printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
> +			__FILE__, netdevice->base_addr);
> +		goto probe_failed;
> +	}
> +	
> +	lp = netdev_priv(netdevice);
> +	lp->options = options->flags & IORESOURCE_BITS;
> +	lp->ca = ca_addr;
> +	lp->mpu_port = mpu_addr;
> +	
> +	retval = i82596_probe(netdevice);
> +	if (retval) {
> +		free_netdev(netdevice);
> +probe_failed:
> +		if (mpu_addr)
> +			iounmap(mpu_addr);
> +		if (ca_addr)
> +			iounmap(ca_addr);
> +		if (eth_addr)
> +			iounmap(ca_addr);
> +	}
> +	return retval;
> +}
> +
> +static int __devexit sni_82596_driver_remove (struct platform_device *pdev)

Extraneous space                               ^ here

> +{
> +	struct net_device *dev = platform_get_drvdata(pdev);
> +	struct i596_private *lp = netdev_priv(dev);
> +
> +	unregister_netdev (dev);

and                      ^ here

checkpatch.pl will find these things.

> +	DMA_FREE(dev->dev.parent, sizeof(struct i596_private),
> +		 lp->dma, lp->dma_addr);
> +	iounmap(lp->ca);
> +	iounmap(lp->mpu_port);
> +	free_netdev (dev);
> +	return 0;
> +}
> +
> +static struct platform_driver sni_82596_driver = {
> +	.probe	= sni_82596_probe,
> +	.remove	= __devexit_p(sni_82596_driver_remove),
> +	.driver	= {
> +		.name	= sni_82596_string,
> +	},
> +};
> +
> +static int __devinit sni_82596_init(void)
> +{
> +	return platform_driver_register(&sni_82596_driver);
> +}
> +
> +
> +static void __exit sni_82596_exit(void)
> +{
> +	platform_driver_unregister(&sni_82596_driver);
> +}
> +
> +module_init(sni_82596_init);
> +module_exit(sni_82596_exit);


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-06-23 16:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-22 19:53 [PATCH] Ethernet driver for EISA only SNI RM200/RM400 machines Thomas Bogendoerfer
2007-06-23 16:53 ` Andrew Morton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).