0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <linux/kernel.h>
0023 #include <linux/module.h>
0024 #include <linux/types.h>
0025 #include <linux/fcntl.h>
0026 #include <linux/gfp.h>
0027 #include <linux/interrupt.h>
0028 #include <linux/ioport.h>
0029 #include <linux/in.h>
0030 #include <linux/string.h>
0031 #include <linux/delay.h>
0032 #include <linux/errno.h>
0033 #include <linux/netdevice.h>
0034 #include <linux/etherdevice.h>
0035 #include <linux/skbuff.h>
0036 #include <linux/platform_device.h>
0037 #include <linux/dma-mapping.h>
0038 #include <linux/slab.h>
0039 #include <linux/pgtable.h>
0040
0041 #include <asm/bootinfo.h>
0042 #include <asm/io.h>
0043 #include <asm/dma.h>
0044 #include <asm/jazz.h>
0045 #include <asm/jazzdma.h>
0046
0047 static char jazz_sonic_string[] = "jazzsonic";
0048
0049 #define SONIC_MEM_SIZE 0x100
0050
0051 #include "sonic.h"
0052
0053
0054
0055
0056 #define SONIC_READ(reg) (*((volatile unsigned int *)dev->base_addr+reg))
0057
0058 #define SONIC_WRITE(reg,val) \
0059 do { \
0060 *((volatile unsigned int *)dev->base_addr+(reg)) = (val); \
0061 } while (0)
0062
0063
0064
0065
0066
0067
0068 static unsigned short known_revisions[] =
0069 {
0070 0x04,
0071 0xffff
0072 };
0073
0074 static int jazzsonic_open(struct net_device* dev)
0075 {
0076 int retval;
0077
0078 retval = request_irq(dev->irq, sonic_interrupt, 0, "sonic", dev);
0079 if (retval) {
0080 printk(KERN_ERR "%s: unable to get IRQ %d.\n",
0081 dev->name, dev->irq);
0082 return retval;
0083 }
0084
0085 retval = sonic_open(dev);
0086 if (retval)
0087 free_irq(dev->irq, dev);
0088 return retval;
0089 }
0090
0091 static int jazzsonic_close(struct net_device* dev)
0092 {
0093 int err;
0094 err = sonic_close(dev);
0095 free_irq(dev->irq, dev);
0096 return err;
0097 }
0098
0099 static const struct net_device_ops sonic_netdev_ops = {
0100 .ndo_open = jazzsonic_open,
0101 .ndo_stop = jazzsonic_close,
0102 .ndo_start_xmit = sonic_send_packet,
0103 .ndo_get_stats = sonic_get_stats,
0104 .ndo_set_rx_mode = sonic_multicast_list,
0105 .ndo_tx_timeout = sonic_tx_timeout,
0106 .ndo_validate_addr = eth_validate_addr,
0107 .ndo_set_mac_address = eth_mac_addr,
0108 };
0109
0110 static int sonic_probe1(struct net_device *dev)
0111 {
0112 unsigned int silicon_revision;
0113 unsigned int val;
0114 struct sonic_local *lp = netdev_priv(dev);
0115 int err = -ENODEV;
0116 int i;
0117 unsigned char addr[ETH_ALEN];
0118
0119 if (!request_mem_region(dev->base_addr, SONIC_MEM_SIZE, jazz_sonic_string))
0120 return -EBUSY;
0121
0122
0123
0124
0125
0126
0127 silicon_revision = SONIC_READ(SONIC_SR);
0128 i = 0;
0129 while (known_revisions[i] != 0xffff &&
0130 known_revisions[i] != silicon_revision)
0131 i++;
0132
0133 if (known_revisions[i] == 0xffff) {
0134 pr_info("SONIC ethernet controller not found (0x%4x)\n",
0135 silicon_revision);
0136 goto out;
0137 }
0138
0139
0140
0141
0142
0143 SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
0144 SONIC_WRITE(SONIC_CEP,0);
0145 for (i=0; i<3; i++) {
0146 val = SONIC_READ(SONIC_CAP0-i);
0147 addr[i*2] = val;
0148 addr[i*2+1] = val >> 8;
0149 }
0150 eth_hw_addr_set(dev, addr);
0151
0152 lp->dma_bitmode = SONIC_BITMODE32;
0153
0154 err = sonic_alloc_descriptors(dev);
0155 if (err)
0156 goto out;
0157
0158 dev->netdev_ops = &sonic_netdev_ops;
0159 dev->watchdog_timeo = TX_TIMEOUT;
0160
0161
0162
0163
0164 SONIC_WRITE(SONIC_CRCT,0xffff);
0165 SONIC_WRITE(SONIC_FAET,0xffff);
0166 SONIC_WRITE(SONIC_MPT,0xffff);
0167
0168 return 0;
0169 out:
0170 release_mem_region(dev->base_addr, SONIC_MEM_SIZE);
0171 return err;
0172 }
0173
0174
0175
0176
0177
0178 static int jazz_sonic_probe(struct platform_device *pdev)
0179 {
0180 struct net_device *dev;
0181 struct sonic_local *lp;
0182 struct resource *res;
0183 int err = 0;
0184
0185 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0186 if (!res)
0187 return -ENODEV;
0188
0189 dev = alloc_etherdev(sizeof(struct sonic_local));
0190 if (!dev)
0191 return -ENOMEM;
0192
0193 lp = netdev_priv(dev);
0194 lp->device = &pdev->dev;
0195 SET_NETDEV_DEV(dev, &pdev->dev);
0196 platform_set_drvdata(pdev, dev);
0197
0198 dev->base_addr = res->start;
0199 dev->irq = platform_get_irq(pdev, 0);
0200 err = sonic_probe1(dev);
0201 if (err)
0202 goto out;
0203
0204 pr_info("SONIC ethernet @%08lx, MAC %pM, IRQ %d\n",
0205 dev->base_addr, dev->dev_addr, dev->irq);
0206
0207 sonic_msg_init(dev);
0208
0209 err = register_netdev(dev);
0210 if (err)
0211 goto undo_probe1;
0212
0213 return 0;
0214
0215 undo_probe1:
0216 dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
0217 lp->descriptors, lp->descriptors_laddr);
0218 release_mem_region(dev->base_addr, SONIC_MEM_SIZE);
0219 out:
0220 free_netdev(dev);
0221
0222 return err;
0223 }
0224
0225 MODULE_DESCRIPTION("Jazz SONIC ethernet driver");
0226 MODULE_ALIAS("platform:jazzsonic");
0227
0228 #include "sonic.c"
0229
0230 static int jazz_sonic_device_remove(struct platform_device *pdev)
0231 {
0232 struct net_device *dev = platform_get_drvdata(pdev);
0233 struct sonic_local* lp = netdev_priv(dev);
0234
0235 unregister_netdev(dev);
0236 dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
0237 lp->descriptors, lp->descriptors_laddr);
0238 release_mem_region(dev->base_addr, SONIC_MEM_SIZE);
0239 free_netdev(dev);
0240
0241 return 0;
0242 }
0243
0244 static struct platform_driver jazz_sonic_driver = {
0245 .probe = jazz_sonic_probe,
0246 .remove = jazz_sonic_device_remove,
0247 .driver = {
0248 .name = jazz_sonic_string,
0249 },
0250 };
0251
0252 module_platform_driver(jazz_sonic_driver);