1/* 2 * sni_82596.c -- driver for intel 82596 ethernet controller, as 3 * used in older SNI RM machines 4 */ 5 6#include <linux/module.h> 7#include <linux/kernel.h> 8#include <linux/string.h> 9#include <linux/errno.h> 10#include <linux/ioport.h> 11#include <linux/interrupt.h> 12#include <linux/delay.h> 13#include <linux/netdevice.h> 14#include <linux/etherdevice.h> 15#include <linux/skbuff.h> 16#include <linux/types.h> 17#include <linux/bitops.h> 18#include <linux/platform_device.h> 19#include <linux/io.h> 20#include <linux/irq.h> 21 22#define SNI_82596_DRIVER_VERSION "SNI RM 82596 driver - Revision: 0.01" 23 24static const char sni_82596_string[] = "snirm_82596"; 25 26#define DMA_ALLOC dma_alloc_coherent 27#define DMA_FREE dma_free_coherent 28#define DMA_WBACK(priv, addr, len) do { } while (0) 29#define DMA_INV(priv, addr, len) do { } while (0) 30#define DMA_WBACK_INV(priv, addr, len) do { } while (0) 31 32#define SYSBUS 0x00004400 33 34/* big endian CPU, 82596 little endian */ 35#define SWAP32(x) cpu_to_le32((u32)(x)) 36#define SWAP16(x) cpu_to_le16((u16)(x)) 37 38#define OPT_MPU_16BIT 0x01 39 40#include "lib82596.c" 41 42MODULE_AUTHOR("Thomas Bogendoerfer"); 43MODULE_DESCRIPTION("i82596 driver"); 44MODULE_LICENSE("GPL"); 45MODULE_ALIAS("platform:snirm_82596"); 46module_param(i596_debug, int, 0); 47MODULE_PARM_DESC(i596_debug, "82596 debug mask"); 48 49static inline void ca(struct net_device *dev) 50{ 51 struct i596_private *lp = netdev_priv(dev); 52 53 writel(0, lp->ca); 54} 55 56 57static void mpu_port(struct net_device *dev, int c, dma_addr_t x) 58{ 59 struct i596_private *lp = netdev_priv(dev); 60 61 u32 v = (u32) (c) | (u32) (x); 62 63 if (lp->options & OPT_MPU_16BIT) { 64 writew(v & 0xffff, lp->mpu_port); 65 wmb(); /* order writes to MPU port */ 66 udelay(1); 67 writew(v >> 16, lp->mpu_port); 68 } else { 69 writel(v, lp->mpu_port); 70 wmb(); /* order writes to MPU port */ 71 udelay(1); 72 writel(v, lp->mpu_port); 73 } 74} 75 76 77static int sni_82596_probe(struct platform_device *dev) 78{ 79 struct net_device *netdevice; 80 struct i596_private *lp; 81 struct resource *res, *ca, *idprom, *options; 82 int retval = -ENOMEM; 83 void __iomem *mpu_addr; 84 void __iomem *ca_addr; 85 u8 __iomem *eth_addr; 86 87 res = platform_get_resource(dev, IORESOURCE_MEM, 0); 88 ca = platform_get_resource(dev, IORESOURCE_MEM, 1); 89 options = platform_get_resource(dev, 0, 0); 90 idprom = platform_get_resource(dev, IORESOURCE_MEM, 2); 91 if (!res || !ca || !options || !idprom) 92 return -ENODEV; 93 mpu_addr = ioremap_nocache(res->start, 4); 94 if (!mpu_addr) 95 return -ENOMEM; 96 ca_addr = ioremap_nocache(ca->start, 4); 97 if (!ca_addr) 98 goto probe_failed_free_mpu; 99 100 printk(KERN_INFO "Found i82596 at 0x%x\n", res->start); 101 102 netdevice = alloc_etherdev(sizeof(struct i596_private)); 103 if (!netdevice) 104 goto probe_failed_free_ca; 105 106 SET_NETDEV_DEV(netdevice, &dev->dev); 107 platform_set_drvdata (dev, netdevice); 108 109 netdevice->base_addr = res->start; 110 netdevice->irq = platform_get_irq(dev, 0); 111 112 eth_addr = ioremap_nocache(idprom->start, 0x10); 113 if (!eth_addr) 114 goto probe_failed; 115 116 /* someone seems to like messed up stuff */ 117 netdevice->dev_addr[0] = readb(eth_addr + 0x0b); 118 netdevice->dev_addr[1] = readb(eth_addr + 0x0a); 119 netdevice->dev_addr[2] = readb(eth_addr + 0x09); 120 netdevice->dev_addr[3] = readb(eth_addr + 0x08); 121 netdevice->dev_addr[4] = readb(eth_addr + 0x07); 122 netdevice->dev_addr[5] = readb(eth_addr + 0x06); 123 iounmap(eth_addr); 124 125 if (!netdevice->irq) { 126 printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n", 127 __FILE__, netdevice->base_addr); 128 goto probe_failed; 129 } 130 131 lp = netdev_priv(netdevice); 132 lp->options = options->flags & IORESOURCE_BITS; 133 lp->ca = ca_addr; 134 lp->mpu_port = mpu_addr; 135 136 retval = i82596_probe(netdevice); 137 if (retval == 0) 138 return 0; 139 140probe_failed: 141 free_netdev(netdevice); 142probe_failed_free_ca: 143 iounmap(ca_addr); 144probe_failed_free_mpu: 145 iounmap(mpu_addr); 146 return retval; 147} 148 149static int sni_82596_driver_remove(struct platform_device *pdev) 150{ 151 struct net_device *dev = platform_get_drvdata(pdev); 152 struct i596_private *lp = netdev_priv(dev); 153 154 unregister_netdev(dev); 155 DMA_FREE(dev->dev.parent, sizeof(struct i596_private), 156 lp->dma, lp->dma_addr); 157 iounmap(lp->ca); 158 iounmap(lp->mpu_port); 159 free_netdev (dev); 160 return 0; 161} 162 163static struct platform_driver sni_82596_driver = { 164 .probe = sni_82596_probe, 165 .remove = sni_82596_driver_remove, 166 .driver = { 167 .name = sni_82596_string, 168 }, 169}; 170 171static int sni_82596_init(void) 172{ 173 printk(KERN_INFO SNI_82596_DRIVER_VERSION "\n"); 174 return platform_driver_register(&sni_82596_driver); 175} 176 177 178static void __exit sni_82596_exit(void) 179{ 180 platform_driver_unregister(&sni_82596_driver); 181} 182 183module_init(sni_82596_init); 184module_exit(sni_82596_exit); 185