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