1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/kernel.h>
17#include <linux/sched.h>
18#include <linux/types.h>
19#include <linux/fcntl.h>
20#include <linux/interrupt.h>
21#include <linux/ioport.h>
22#include <linux/in.h>
23#include <linux/slab.h>
24#include <linux/string.h>
25#include <linux/errno.h>
26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28#include <linux/skbuff.h>
29#include <linux/delay.h>
30#include <linux/init.h>
31#include <linux/crc32.h>
32
33#include <asm/system.h>
34#include <asm/bitops.h>
35#include <asm/irq.h>
36#include <asm/io.h>
37#include <asm/dma.h>
38
39#define TX_BUFFERS 15
40#define RX_BUFFERS 25
41
42#include "am79c961a.h"
43
44static void am79c961_interrupt (int irq, void *dev_id, struct pt_regs *regs);
45
46static unsigned int net_debug = NET_DEBUG;
47
48static const char version[] =
49 "am79c961 ethernet driver (C) 1995-2001 Russell King v0.04\n";
50
51
52
53#ifdef __arm__
54static void write_rreg(u_long base, u_int reg, u_int val)
55{
56 __asm__("str%?h %1, [%2] @ NET_RAP
57 str%?h %0, [%2, #-4] @ NET_RDP
58 " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
59}
60
61static inline unsigned short read_rreg(u_long base_addr, u_int reg)
62{
63 unsigned short v;
64 __asm__("str%?h %1, [%2] @ NET_RAP
65 ldr%?h %0, [%2, #-4] @ NET_RDP
66 " : "=r" (v): "r" (reg), "r" (ISAIO_BASE + 0x0464));
67 return v;
68}
69
70static inline void write_ireg(u_long base, u_int reg, u_int val)
71{
72 __asm__("str%?h %1, [%2] @ NET_RAP
73 str%?h %0, [%2, #8] @ NET_IDP
74 " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
75}
76
77#define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
78#define am_readword(dev,off) __raw_readw(ISAMEM_BASE + ((off) << 1))
79
80static inline void
81am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
82{
83 offset = ISAMEM_BASE + (offset << 1);
84 length = (length + 1) & ~1;
85 if ((int)buf & 2) {
86 __asm__ __volatile__("str%?h %2, [%0], #4"
87 : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
88 buf += 2;
89 length -= 2;
90 }
91 while (length > 8) {
92 unsigned int tmp, tmp2;
93 __asm__ __volatile__("
94 ldm%?ia %1!, {%2, %3}
95 str%?h %2, [%0], #4
96 mov%? %2, %2, lsr #16
97 str%?h %2, [%0], #4
98 str%?h %3, [%0], #4
99 mov%? %3, %3, lsr #16
100 str%?h %3, [%0], #4
101 " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
102 : "0" (offset), "1" (buf));
103 length -= 8;
104 }
105 while (length > 0) {
106 __asm__ __volatile__("str%?h %2, [%0], #4"
107 : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
108 buf += 2;
109 length -= 2;
110 }
111}
112
113static inline void
114am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
115{
116 offset = ISAMEM_BASE + (offset << 1);
117 length = (length + 1) & ~1;
118 if ((int)buf & 2) {
119 unsigned int tmp;
120 __asm__ __volatile__("
121 ldr%?h %2, [%0], #4
122 str%?b %2, [%1], #1
123 mov%? %2, %2, lsr #8
124 str%?b %2, [%1], #1
125 " : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
126 length -= 2;
127 }
128 while (length > 8) {
129 unsigned int tmp, tmp2, tmp3;
130 __asm__ __volatile__("
131 ldr%?h %2, [%0], #4
132 ldr%?h %3, [%0], #4
133 orr%? %2, %2, %3, lsl #16
134 ldr%?h %3, [%0], #4
135 ldr%?h %4, [%0], #4
136 orr%? %3, %3, %4, lsl #16
137 stm%?ia %1!, {%2, %3}
138 " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
139 : "0" (offset), "1" (buf));
140 length -= 8;
141 }
142 while (length > 0) {
143 unsigned int tmp;
144 __asm__ __volatile__("
145 ldr%?h %2, [%0], #4
146 str%?b %2, [%1], #1
147 mov%? %2, %2, lsr #8
148 str%?b %2, [%1], #1
149 " : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
150 length -= 2;
151 }
152}
153#else
154#error Not compatable
155#endif
156
157static int
158am79c961_ramtest(struct net_device *dev, unsigned int val)
159{
160 unsigned char *buffer = kmalloc (65536, GFP_KERNEL);
161 int i, error = 0, errorcount = 0;
162
163 if (!buffer)
164 return 0;
165 memset (buffer, val, 65536);
166 am_writebuffer(dev, 0, buffer, 65536);
167 memset (buffer, val ^ 255, 65536);
168 am_readbuffer(dev, 0, buffer, 65536);
169 for (i = 0; i < 65536; i++) {
170 if (buffer[i] != val && !error) {
171 printk ("%s: buffer error (%02X %02X) %05X - ", dev->name, val, buffer[i], i);
172 error = 1;
173 errorcount ++;
174 } else if (error && buffer[i] == val) {
175 printk ("%05X\n", i);
176 error = 0;
177 }
178 }
179 if (error)
180 printk ("10000\n");
181 kfree (buffer);
182 return errorcount;
183}
184
185static void
186am79c961_init_for_open(struct net_device *dev)
187{
188 struct dev_priv *priv = (struct dev_priv *)dev->priv;
189 unsigned long flags;
190 unsigned char *p;
191 u_int hdr_addr, first_free_addr;
192 int i;
193
194
195
196
197 spin_lock_irqsave(priv->chip_lock, flags);
198 write_rreg (dev->base_addr, CSR0, CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|CSR0_TINT|CSR0_RINT|CSR0_STOP);
199 spin_unlock_irqrestore(priv->chip_lock, flags);
200
201 write_ireg (dev->base_addr, 5, 0x00a0);
202 write_ireg (dev->base_addr, 6, 0x0081);
203 write_ireg (dev->base_addr, 7, 0x0090);
204 write_ireg (dev->base_addr, 2, 0x0000);
205
206 for (i = LADRL; i <= LADRH; i++)
207 write_rreg (dev->base_addr, i, 0);
208
209 for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2)
210 write_rreg (dev->base_addr, i, p[0] | (p[1] << 8));
211
212 i = MODE_PORT_10BT;
213 if (dev->flags & IFF_PROMISC)
214 i |= MODE_PROMISC;
215
216 write_rreg (dev->base_addr, MODE, i);
217 write_rreg (dev->base_addr, POLLINT, 0);
218 write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS);
219 write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS);
220
221 first_free_addr = RX_BUFFERS * 8 + TX_BUFFERS * 8 + 16;
222 hdr_addr = 0;
223
224 priv->rxhead = 0;
225 priv->rxtail = 0;
226 priv->rxhdr = hdr_addr;
227
228 for (i = 0; i < RX_BUFFERS; i++) {
229 priv->rxbuffer[i] = first_free_addr;
230 am_writeword (dev, hdr_addr, first_free_addr);
231 am_writeword (dev, hdr_addr + 2, RMD_OWN);
232 am_writeword (dev, hdr_addr + 4, (-1600));
233 am_writeword (dev, hdr_addr + 6, 0);
234 first_free_addr += 1600;
235 hdr_addr += 8;
236 }
237 priv->txhead = 0;
238 priv->txtail = 0;
239 priv->txhdr = hdr_addr;
240 for (i = 0; i < TX_BUFFERS; i++) {
241 priv->txbuffer[i] = first_free_addr;
242 am_writeword (dev, hdr_addr, first_free_addr);
243 am_writeword (dev, hdr_addr + 2, TMD_STP|TMD_ENP);
244 am_writeword (dev, hdr_addr + 4, 0xf000);
245 am_writeword (dev, hdr_addr + 6, 0);
246 first_free_addr += 1600;
247 hdr_addr += 8;
248 }
249
250 write_rreg (dev->base_addr, BASERXL, priv->rxhdr);
251 write_rreg (dev->base_addr, BASERXH, 0);
252 write_rreg (dev->base_addr, BASETXL, priv->txhdr);
253 write_rreg (dev->base_addr, BASERXH, 0);
254 write_rreg (dev->base_addr, CSR0, CSR0_STOP);
255 write_rreg (dev->base_addr, CSR3, CSR3_IDONM|CSR3_BABLM|CSR3_DXSUFLO);
256 write_rreg (dev->base_addr, CSR0, CSR0_IENA|CSR0_STRT);
257}
258
259
260
261
262static int
263am79c961_open(struct net_device *dev)
264{
265 struct dev_priv *priv = (struct dev_priv *)dev->priv;
266 int ret;
267
268 memset (&priv->stats, 0, sizeof (priv->stats));
269
270 ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev);
271 if (ret)
272 return ret;
273
274 am79c961_init_for_open(dev);
275
276 netif_start_queue(dev);
277
278 return 0;
279}
280
281
282
283
284static int
285am79c961_close(struct net_device *dev)
286{
287 struct dev_priv *priv = (struct dev_priv *)dev->priv;
288 unsigned long flags;
289
290 netif_stop_queue(dev);
291
292 spin_lock_irqsave(priv->chip_lock, flags);
293 write_rreg (dev->base_addr, CSR0, CSR0_STOP);
294 write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
295 spin_unlock_irqrestore(priv->chip_lock, flags);
296
297 free_irq (dev->irq, dev);
298
299 return 0;
300}
301
302
303
304
305static struct net_device_stats *am79c961_getstats (struct net_device *dev)
306{
307 struct dev_priv *priv = (struct dev_priv *)dev->priv;
308 return &priv->stats;
309}
310
311static void am79c961_mc_hash(struct dev_mc_list *dmi, unsigned short *hash)
312{
313 if (dmi->dmi_addrlen == ETH_ALEN && dmi->dmi_addr[0] & 0x01) {
314 int idx, bit;
315 u32 crc;
316
317 crc = ether_crc_le(ETH_ALEN, dmi->dmi_addr);
318
319 idx = crc >> 30;
320 bit = (crc >> 26) & 15;
321
322 hash[idx] |= 1 << bit;
323 }
324}
325
326
327
328
329static void am79c961_setmulticastlist (struct net_device *dev)
330{
331 struct dev_priv *priv = (struct dev_priv *)dev->priv;
332 unsigned long flags;
333 unsigned short multi_hash[4], mode;
334 int i, stopped;
335
336 mode = MODE_PORT_10BT;
337
338 if (dev->flags & IFF_PROMISC) {
339 mode |= MODE_PROMISC;
340 } else if (dev->flags & IFF_ALLMULTI) {
341 memset(multi_hash, 0xff, sizeof(multi_hash));
342 } else {
343 struct dev_mc_list *dmi;
344
345 memset(multi_hash, 0x00, sizeof(multi_hash));
346
347 for (dmi = dev->mc_list; dmi; dmi = dmi->next)
348 am79c961_mc_hash(dmi, multi_hash);
349 }
350
351 spin_lock_irqsave(priv->chip_lock, flags);
352
353 stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
354
355 if (!stopped) {
356
357
358
359 write_rreg(dev->base_addr, CTRL1, CTRL1_SPND);
360
361
362
363
364 while ((read_rreg(dev->base_addr, CTRL1) & CTRL1_SPND) == 0) {
365 spin_unlock_irqrestore(priv->chip_lock, flags);
366 nop();
367 spin_lock_irqsave(priv->chip_lock, flags);
368 }
369 }
370
371
372
373
374 for (i = 0; i < sizeof(multi_hash) / sizeof(multi_hash[0]); i++)
375 write_rreg(dev->base_addr, i + LADRL, multi_hash[i]);
376
377
378
379
380 write_rreg(dev->base_addr, MODE, mode);
381
382 if (!stopped) {
383
384
385
386 write_rreg(dev->base_addr, CTRL1, 0);
387 }
388
389 spin_unlock_irqrestore(priv->chip_lock, flags);
390}
391
392static void am79c961_timeout(struct net_device *dev)
393{
394 printk(KERN_WARNING "%s: transmit timed out, network cable problem?\n",
395 dev->name);
396
397
398
399
400
401 netif_wake_queue(dev);
402}
403
404
405
406
407static int
408am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
409{
410 struct dev_priv *priv = (struct dev_priv *)dev->priv;
411 unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
412 unsigned int hdraddr, bufaddr;
413 unsigned int head;
414 unsigned long flags;
415
416 head = priv->txhead;
417 hdraddr = priv->txhdr + (head << 3);
418 bufaddr = priv->txbuffer[head];
419 head += 1;
420 if (head >= TX_BUFFERS)
421 head = 0;
422
423 am_writebuffer (dev, bufaddr, skb->data, length);
424 am_writeword (dev, hdraddr + 4, -length);
425 am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP);
426 priv->txhead = head;
427
428 spin_lock_irqsave(priv->chip_lock, flags);
429 write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
430 dev->trans_start = jiffies;
431 spin_unlock_irqrestore(priv->chip_lock, flags);
432
433
434
435
436
437
438 if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN)
439 netif_stop_queue(dev);
440
441 dev_kfree_skb(skb);
442
443 return 0;
444}
445
446
447
448
449static void
450am79c961_rx(struct net_device *dev, struct dev_priv *priv)
451{
452 do {
453 struct sk_buff *skb;
454 u_int hdraddr;
455 u_int pktaddr;
456 u_int status;
457 int len;
458
459 hdraddr = priv->rxhdr + (priv->rxtail << 3);
460 pktaddr = priv->rxbuffer[priv->rxtail];
461
462 status = am_readword (dev, hdraddr + 2);
463 if (status & RMD_OWN)
464 break;
465
466 priv->rxtail ++;
467 if (priv->rxtail >= RX_BUFFERS)
468 priv->rxtail = 0;
469
470 if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) {
471 am_writeword (dev, hdraddr + 2, RMD_OWN);
472 priv->stats.rx_errors ++;
473 if (status & RMD_ERR) {
474 if (status & RMD_FRAM)
475 priv->stats.rx_frame_errors ++;
476 if (status & RMD_CRC)
477 priv->stats.rx_crc_errors ++;
478 } else if (status & RMD_STP)
479 priv->stats.rx_length_errors ++;
480 continue;
481 }
482
483 len = am_readword(dev, hdraddr + 6);
484 skb = dev_alloc_skb(len + 2);
485
486 if (skb) {
487 skb->dev = dev;
488 skb_reserve(skb, 2);
489
490 am_readbuffer(dev, pktaddr, skb_put(skb, len), len);
491 am_writeword(dev, hdraddr + 2, RMD_OWN);
492 skb->protocol = eth_type_trans(skb, dev);
493 netif_rx(skb);
494 dev->last_rx = jiffies;
495 priv->stats.rx_bytes += len;
496 priv->stats.rx_packets ++;
497 } else {
498 am_writeword (dev, hdraddr + 2, RMD_OWN);
499 printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name);
500 priv->stats.rx_dropped ++;
501 break;
502 }
503 } while (1);
504}
505
506
507
508
509static void
510am79c961_tx(struct net_device *dev, struct dev_priv *priv)
511{
512 do {
513 u_int hdraddr;
514 u_int status;
515
516 hdraddr = priv->txhdr + (priv->txtail << 3);
517 status = am_readword (dev, hdraddr + 2);
518 if (status & TMD_OWN)
519 break;
520
521 priv->txtail ++;
522 if (priv->txtail >= TX_BUFFERS)
523 priv->txtail = 0;
524
525 if (status & TMD_ERR) {
526 u_int status2;
527
528 priv->stats.tx_errors ++;
529
530 status2 = am_readword (dev, hdraddr + 6);
531
532
533
534
535 am_writeword (dev, hdraddr + 6, 0);
536
537 if (status2 & TST_RTRY)
538 priv->stats.collisions += 16;
539 if (status2 & TST_LCOL)
540 priv->stats.tx_window_errors ++;
541 if (status2 & TST_LCAR)
542 priv->stats.tx_carrier_errors ++;
543 if (status2 & TST_UFLO)
544 priv->stats.tx_fifo_errors ++;
545 continue;
546 }
547 priv->stats.tx_packets ++;
548 } while (priv->txtail != priv->txhead);
549
550 netif_wake_queue(dev);
551}
552
553static void
554am79c961_interrupt(int irq, void *dev_id, struct pt_regs *regs)
555{
556 struct net_device *dev = (struct net_device *)dev_id;
557 struct dev_priv *priv = (struct dev_priv *)dev->priv;
558 u_int status;
559
560 status = read_rreg(dev->base_addr, CSR0);
561 write_rreg(dev->base_addr, CSR0, status & (CSR0_TINT|CSR0_RINT|CSR0_MISS|CSR0_IENA));
562
563 if (status & CSR0_RINT)
564 am79c961_rx(dev, priv);
565 if (status & CSR0_TINT)
566 am79c961_tx(dev, priv);
567 if (status & CSR0_MISS)
568 priv->stats.rx_dropped ++;
569}
570
571
572
573
574
575static int
576am79c961_hw_init(struct net_device *dev)
577{
578 struct dev_priv *priv = (struct dev_priv *)dev->priv;
579
580 spin_lock_irq(priv->chip_lock);
581 write_rreg (dev->base_addr, CSR0, CSR0_STOP);
582 write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
583 spin_unlock_irq(priv->chip_lock);
584
585 am79c961_ramtest(dev, 0x66);
586 am79c961_ramtest(dev, 0x99);
587
588 return 0;
589}
590
591static void __init am79c961_banner(void)
592{
593 static unsigned version_printed;
594
595 if (net_debug && version_printed++ == 0)
596 printk(KERN_INFO "%s", version);
597}
598
599static int __init am79c961_init(void)
600{
601 struct net_device *dev;
602 struct dev_priv *priv;
603 int i, ret;
604
605 dev = init_etherdev(NULL, sizeof(struct dev_priv));
606 ret = -ENOMEM;
607 if (!dev)
608 goto out;
609
610 priv = dev->priv;
611
612
613
614
615
616
617 dev->base_addr = 0x220;
618 dev->irq = IRQ_EBSA110_ETHERNET;
619
620
621
622
623 inb(dev->base_addr + NET_RESET);
624 udelay(5);
625
626
627
628
629
630 ret = -ENODEV;
631 if (inb(dev->base_addr) != 0x08 ||
632 inb(dev->base_addr + 2) != 0x00 ||
633 inb(dev->base_addr + 4) != 0x2b)
634 goto nodev;
635
636 if (!request_region(dev->base_addr, 0x18, dev->name))
637 goto nodev;
638
639 am79c961_banner();
640 printk(KERN_INFO "%s: ether address ", dev->name);
641
642
643 for (i = 0; i < 6; i++) {
644 dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff;
645 printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]);
646 }
647
648 if (am79c961_hw_init(dev))
649 goto release;
650
651 dev->open = am79c961_open;
652 dev->stop = am79c961_close;
653 dev->hard_start_xmit = am79c961_sendpacket;
654 dev->get_stats = am79c961_getstats;
655 dev->set_multicast_list = am79c961_setmulticastlist;
656 dev->tx_timeout = am79c961_timeout;
657
658 return 0;
659
660release:
661 release_region(dev->base_addr, 0x18);
662nodev:
663 unregister_netdev(dev);
664 kfree(dev);
665out:
666 return ret;
667}
668
669__initcall(am79c961_init);
670