* [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).