This source file includes following definitions.
- a2065_probe
- a2065_open
- a2065_init_ring
- a2065_close
- a2065_interrupt
- a2065_start_xmit
- a2065_rx
- a2065_get_stats
- set_multicast_list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <stddef.h>
41
42 #include <linux/kernel.h>
43 #include <linux/sched.h>
44 #include <linux/string.h>
45 #include <linux/ptrace.h>
46 #include <linux/errno.h>
47 #include <linux/ioport.h>
48 #include <linux/malloc.h>
49 #include <linux/interrupt.h>
50 #include <linux/netdevice.h>
51 #include <linux/etherdevice.h>
52 #include <linux/skbuff.h>
53
54 #include <asm/bitops.h>
55 #include <asm/io.h>
56 #include <asm/irq.h>
57
58 #include <asm/bootinfo.h>
59 #include <asm/amigaints.h>
60 #include <asm/amigahw.h>
61 #include <asm/zorro.h>
62
63 #include "a2065.h"
64
65 #ifdef A2065_DEBUG
66 int a2065_debug = A2065_DEBUG;
67 #else
68 int a2065_debug = 1;
69 #endif
70
71
72
73
74
75
76 #define LANCE_LOG_TX_BUFFERS (2)
77 #define LANCE_LOG_RX_BUFFERS (4)
78
79 #define TX_RING_SIZE (1<<LANCE_LOG_TX_BUFFERS)
80 #define RX_RING_SIZE (1<<LANCE_LOG_RX_BUFFERS)
81
82 #define TX_RING_MOD_MASK (TX_RING_SIZE-1)
83 #define RX_RING_MOD_MASK (RX_RING_SIZE-1)
84
85 #define PKT_BUF_SIZE (1520)
86
87
88
89
90
91
92 struct a2065_private {
93 struct A2065Board *board;
94 struct TDRE *tx_ring[TX_RING_SIZE];
95 struct RDRE *rx_ring[RX_RING_SIZE];
96 u_char *tx_buff[TX_RING_SIZE];
97 u_char *rx_buff[RX_RING_SIZE];
98 int cur_tx, cur_rx;
99 int dirty_tx;
100 struct enet_statistics stats;
101 char tx_full;
102 unsigned long lock;
103 };
104
105
106
107
108
109
110 struct lancedata {
111 struct InitBlock init;
112 struct TDRE tx_ring[TX_RING_SIZE];
113 struct RDRE rx_ring[RX_RING_SIZE];
114 u_char tx_buff[TX_RING_SIZE][PKT_BUF_SIZE];
115 u_char rx_buff[RX_RING_SIZE][PKT_BUF_SIZE];
116 };
117
118
119 static int a2065_open(struct device *dev);
120 static void a2065_init_ring(struct device *dev);
121 static int a2065_start_xmit(struct sk_buff *skb, struct device *dev);
122 static int a2065_rx(struct device *dev);
123 static void a2065_interrupt(int irq, struct pt_regs *fp, void *data);
124 static int a2065_close(struct device *dev);
125 static struct enet_statistics *a2065_get_stats(struct device *dev);
126 static void set_multicast_list(struct device *dev);
127
128
129 int a2065_probe(struct device *dev)
130 {
131 int key1, key2;
132 struct ConfigDev *cd;
133 u_long board;
134 u_long sn;
135 struct a2065_private *priv;
136
137 if ((key1 = zorro_find(MANUF_COMMODORE, PROD_A2065, 0, 0)) ||
138 (key2 = zorro_find(MANUF_AMERISTAR, PROD_AMERISTAR2065, 0, 0))) {
139 cd = zorro_get_board(key1 ? key1 : key2);
140 if ((board = (u_long)cd->cd_BoardAddr)) {
141 sn = cd->cd_Rom.er_SerialNumber;
142 if (key1) {
143 dev->dev_addr[0] = 0x00;
144 dev->dev_addr[1] = 0x80;
145 dev->dev_addr[2] = 0x10;
146 } else {
147 dev->dev_addr[0] = 0x00;
148 dev->dev_addr[1] = 0x00;
149 dev->dev_addr[2] = 0x9f;
150 }
151 dev->dev_addr[3] = (sn>>16) & 0xff;
152 dev->dev_addr[4] = (sn>>8) & 0xff;
153 dev->dev_addr[5] = sn & 0xff;
154 printk("%s: A2065 at 0x%08lx, Ethernet Address %02x:%02x:%02x:%02x:%02x:%02x\n",
155 dev->name, board, dev->dev_addr[0],
156 dev->dev_addr[1], dev->dev_addr[2],
157 dev->dev_addr[3], dev->dev_addr[4],
158 dev->dev_addr[5]);
159
160 init_etherdev(dev, 0);
161
162 dev->priv = kmalloc(sizeof(struct
163 a2065_private),
164 GFP_KERNEL);
165 priv = (struct a2065_private *)dev->priv;
166 memset(priv, 0, sizeof(struct a2065_private));
167
168 priv->board = (struct A2065Board *)ZTWO_VADDR(board);
169
170 dev->open = &a2065_open;
171 dev->stop = &a2065_close;
172 dev->hard_start_xmit = &a2065_start_xmit;
173 dev->get_stats = &a2065_get_stats;
174 dev->set_multicast_list = &set_multicast_list;
175
176 zorro_config_board(key1 ? key1 : key2, 0);
177 return(0);
178 }
179 }
180 return(ENODEV);
181 }
182
183
184 static int a2065_open(struct device *dev)
185 {
186 struct a2065_private *priv = (struct a2065_private *)dev->priv;
187 struct A2065Board *board = priv->board;
188 static int interruptinstalled = 0;
189 struct lancedata *lancedata;
190 struct lancedata *alancedata;
191
192 lancedata = (struct lancedata *)offsetof(struct A2065Board, RAM);
193 alancedata = (struct lancedata *)board->RAM;
194
195
196 board->Lance.RAP = CSR0;
197 board->Lance.RDP = STOP;
198
199
200 board->Lance.RAP = CSR3;
201 board->Lance.RDP = BSWP;
202
203
204 board->Lance.RAP = CSR1;
205 board->Lance.RDP = (u_long)&lancedata->init;
206 board->Lance.RAP = CSR2;
207 board->Lance.RDP = 0x0000;
208
209
210 alancedata->init.Mode = 0;
211
212
213
214 alancedata->init.PADR[0] = dev->dev_addr[1];
215 alancedata->init.PADR[1] = dev->dev_addr[0];
216 alancedata->init.PADR[2] = dev->dev_addr[3];
217 alancedata->init.PADR[3] = dev->dev_addr[2];
218 alancedata->init.PADR[4] = dev->dev_addr[5];
219 alancedata->init.PADR[5] = dev->dev_addr[4];
220
221
222
223 alancedata->init.LADRF[0] = 0x00000000;
224
225 alancedata->init.LADRF[1] = 0x00000000;
226
227
228 alancedata->init.RDRA = (u_long)&lancedata->rx_ring;
229 alancedata->init.RLEN = LANCE_LOG_RX_BUFFERS << 13;
230 alancedata->init.TDRA = (u_long)&lancedata->tx_ring;
231 alancedata->init.TLEN = LANCE_LOG_TX_BUFFERS << 13;
232
233
234 a2065_init_ring(dev);
235
236
237
238 if (!interruptinstalled) {
239 if (!add_isr(IRQ_AMIGA_PORTS, a2065_interrupt, 0, dev,
240 "a2065 Ethernet"))
241 return(-EAGAIN);
242 interruptinstalled = 1;
243 }
244
245
246 board->Lance.RAP = CSR0;
247 board->Lance.RDP = INEA|INIT;
248
249 dev->tbusy = 0;
250 dev->interrupt = 0;
251 dev->start = 1;
252
253 return(0);
254 }
255
256
257 static void a2065_init_ring(struct device *dev)
258 {
259 struct a2065_private *priv = (struct a2065_private *)dev->priv;
260 struct A2065Board *board = priv->board;
261 struct lancedata *lancedata;
262 struct lancedata *alancedata;
263 int i;
264
265 priv->lock = 0, priv->tx_full = 0;
266 priv->cur_rx = priv->cur_tx = 0;
267 priv->dirty_tx = 0;
268
269 lancedata = (struct lancedata *)offsetof(struct A2065Board, RAM);
270 alancedata = (struct lancedata *)board->RAM;
271
272
273 for (i = 0; i < TX_RING_SIZE; i++) {
274 alancedata->tx_ring[i].TMD0 = (u_long)lancedata->tx_buff[i];
275 alancedata->tx_ring[i].TMD1 = TF_STP|TF_ENP;
276 alancedata->tx_ring[i].TMD2 = -PKT_BUF_SIZE;
277 alancedata->tx_ring[i].TMD3 = 0x0000;
278 priv->tx_ring[i] = &alancedata->tx_ring[i];
279 priv->tx_buff[i] = alancedata->tx_buff[i];
280 #if 0
281 printk("TX Entry %2d @ 0x%08x (LANCE 0x%08x), Buf @ 0x%08x (LANCE 0x%08x)\n", i,
282 (int)&alancedata->tx_ring[i],
283 (int)&lancedata->tx_ring[i],
284 (int)alancedata->tx_buff[i],
285 (int)lancedata->tx_buff[i]);
286 #endif
287 }
288
289
290 for (i = 0; i < RX_RING_SIZE; i++) {
291 alancedata->rx_ring[i].RMD0 = (u_long)lancedata->rx_buff[i];
292 alancedata->rx_ring[i].RMD1 = RF_OWN;
293 alancedata->rx_ring[i].RMD2 = -PKT_BUF_SIZE;
294 alancedata->rx_ring[i].RMD3 = 0x0000;
295 priv->rx_ring[i] = &alancedata->rx_ring[i];
296 priv->rx_buff[i] = alancedata->rx_buff[i];
297 #if 0
298 printk("RX Entry %2d @ 0x%08x (LANCE 0x%08x), Buf @ 0x%08x (LANCE 0x%08x)\n", i,
299 (int)&alancedata->rx_ring[i],
300 (int)&lancedata->rx_ring[i],
301 (int)alancedata->rx_buff[i],
302 (int)lancedata->rx_buff[i]);
303 #endif
304 }
305 }
306
307
308 static int a2065_close(struct device *dev)
309 {
310 struct a2065_private *priv = (struct a2065_private *)dev->priv;
311 struct A2065Board *board = priv->board;
312
313 dev->start = 0;
314 dev->tbusy = 1;
315
316 board->Lance.RAP = CSR0;
317
318 if (a2065_debug > 1) {
319 printk("%s: Shutting down ethercard, status was %2.2x.\n",
320 dev->name, board->Lance.RDP);
321 printk("%s: %d packets missed\n", dev->name,
322 priv->stats.rx_missed_errors);
323 }
324
325
326 board->Lance.RDP = STOP;
327
328 return(0);
329 }
330
331
332 static void a2065_interrupt(int irq, struct pt_regs *fp, void *data)
333 {
334 struct device *dev = (struct device *)data;
335 struct a2065_private *priv;
336 struct A2065Board *board;
337 int csr0, boguscnt = 10;
338
339 if (dev == NULL) {
340 printk("a2065_interrupt(): irq for unknown device.\n");
341 return;
342 }
343
344 priv = (struct a2065_private *)dev->priv;
345 board = priv->board;
346
347 board->Lance.RAP = CSR0;
348
349 if (!(board->Lance.RDP & INTR))
350
351 return;
352
353 if (dev->interrupt)
354 printk("%s: Re-entering the interrupt handler.\n", dev->name);
355
356 dev->interrupt = 1;
357
358 while ((csr0 = board->Lance.RDP) & (ERR|RINT|TINT) && --boguscnt >= 0){
359
360 board->Lance.RDP = csr0 & ~(INEA|TDMD|STOP|STRT|INIT);
361
362 #if 0
363 if (a2065_debug > 5) {
364 printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.",
365 dev->name, csr0, board->Lance.RDP);
366 printk("[");
367 if (csr0 & INTR)
368 printk(" INTR");
369 if (csr0 & INEA)
370 printk(" INEA");
371 if (csr0 & RXON)
372 printk(" RXON");
373 if (csr0 & TXON)
374 printk(" TXON");
375 if (csr0 & TDMD)
376 printk(" TDMD");
377 if (csr0 & STOP)
378 printk(" STOP");
379 if (csr0 & STRT)
380 printk(" STRT");
381 if (csr0 & INIT)
382 printk(" INIT");
383 if (csr0 & ERR)
384 printk(" ERR");
385 if (csr0 & BABL)
386 printk(" BABL");
387 if (csr0 & CERR)
388 printk(" CERR");
389 if (csr0 & MISS)
390 printk(" MISS");
391 if (csr0 & MERR)
392 printk(" MERR");
393 if (csr0 & RINT)
394 printk(" RINT");
395 if (csr0 & TINT)
396 printk(" TINT");
397 if (csr0 & IDON)
398 printk(" IDON");
399 printk(" ]\n");
400 }
401 #endif
402
403 if (csr0 & RINT)
404 a2065_rx(dev);
405
406 if (csr0 & TINT) {
407 int dirty_tx = priv->dirty_tx;
408
409 while (dirty_tx < priv->cur_tx) {
410 int entry = dirty_tx % TX_RING_SIZE;
411 int status =
412 priv->tx_ring[entry]->TMD1 & 0xff00;
413
414 if (status & TF_OWN)
415 break;
416
417 priv->tx_ring[entry]->TMD1 &= 0x00ff;
418
419 if (status & TF_ERR) {
420
421 int err_status =
422 priv->tx_ring[entry]->TMD3;
423 priv->stats.tx_errors++;
424 if (err_status & EF_RTRY)
425 priv->stats.tx_aborted_errors++;
426 if (err_status & EF_LCAR)
427 priv->stats.tx_carrier_errors++;
428 if (err_status & EF_LCOL)
429 priv->stats.tx_window_errors++;
430 if (err_status & EF_UFLO) {
431
432 priv->stats.tx_fifo_errors++;
433
434 printk("%s: Tx FIFO error! Status %4.4x.\n", dev->name, csr0);
435
436 board->Lance.RDP = STRT;
437 }
438 } else {
439 if (status & (TF_MORE|TF_ONE))
440 priv->stats.collisions++;
441 priv->stats.tx_packets++;
442 }
443 dirty_tx++;
444 }
445
446 #ifndef final_version
447 if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) {
448 printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
449 dirty_tx, priv->cur_tx, priv->tx_full);
450 dirty_tx += TX_RING_SIZE;
451 }
452 #endif
453
454 if (priv->tx_full && dev->tbusy && dirty_tx >
455 priv->cur_tx - TX_RING_SIZE + 2) {
456
457 priv->tx_full = 0;
458 dev->tbusy = 0;
459 mark_bh(NET_BH);
460 }
461
462 priv->dirty_tx = dirty_tx;
463 }
464
465
466 if (csr0 & BABL)
467 priv->stats.tx_errors++;
468 if (csr0 & MISS)
469 priv->stats.rx_errors++;
470 if (csr0 & MERR) {
471 printk("%s: Bus master arbitration failure, status %4.4x.\n", dev->name, csr0);
472
473 board->Lance.RDP = STRT;
474 }
475 }
476
477
478 board->Lance.RAP = CSR0;
479 board->Lance.RDP = INEA|BABL|CERR|MISS|MERR|IDON;
480
481 #if 0
482 if (a2065_debug > 4)
483 printk("%s: exiting interrupt, csr%d=%#4.4x.\n",
484 dev->name, board->Lance.RAP, board->Lance.RDP);
485 #endif
486
487 dev->interrupt = 0;
488 return;
489 }
490
491
492 static int a2065_start_xmit(struct sk_buff *skb, struct device *dev)
493 {
494 struct a2065_private *priv = (struct a2065_private *)dev->priv;
495 struct A2065Board *board = priv->board;
496 int entry;
497
498
499 if (dev->tbusy) {
500 int tickssofar = jiffies - dev->trans_start;
501 if (tickssofar < 20)
502 return(1);
503 board->Lance.RAP = CSR0;
504 printk("%s: transmit timed out, status %4.4x, resetting.\n", dev->name, board->Lance.RDP);
505 board->Lance.RDP = STOP;
506
507
508 board->Lance.RAP = CSR3;
509 board->Lance.RDP = BSWP;
510
511 priv->stats.tx_errors++;
512 #ifndef final_version
513 {
514 int i;
515 printk(" Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
516 priv->dirty_tx, priv->cur_tx, priv->tx_full ?
517 " (full)" : "", priv->cur_rx);
518 for (i = 0 ; i < RX_RING_SIZE; i++)
519 printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
520 ((priv->rx_ring[i]->RMD1)<<16) |
521 priv->rx_ring[i]->RMD0,
522 -priv->rx_ring[i]->RMD2, priv->rx_ring[i]->RMD3);
523 for (i = 0 ; i < TX_RING_SIZE; i++)
524 printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
525 ((priv->tx_ring[i]->TMD1)<<16) |
526 priv->tx_ring[i]->TMD0,
527 -priv->tx_ring[i]->TMD2, priv->tx_ring[i]->TMD3);
528 printk("\n");
529 }
530 #endif
531 a2065_init_ring(dev);
532 board->Lance.RDP = INEA|INIT;
533
534 dev->tbusy = 0;
535 dev->trans_start = jiffies;
536
537 return(0);
538 }
539
540 if (skb == NULL) {
541 dev_tint(dev);
542 return(0);
543 }
544
545 if (skb->len <= 0)
546 return(0);
547
548 #if 0
549 if (a2065_debug > 3) {
550 board->Lance.RAP = CSR0;
551 printk("%s: a2065_start_xmit() called, csr0 %4.4x.\n",
552 dev->name, board->Lance.RDP);
553 board->Lance.RDP = 0x0000;
554 }
555 #endif
556
557
558
559
560
561 if (set_bit(0, (void*)&dev->tbusy) != 0) {
562 printk("%s: Transmitter access conflict.\n", dev->name);
563 return(1);
564 }
565
566 if (set_bit(0, (void*)&priv->lock) != 0) {
567 if (a2065_debug > 0)
568 printk("%s: tx queue lock!.\n", dev->name);
569
570 return(1);
571 }
572
573
574
575 #if 0
576 printk("TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]);
577 {
578 int i;
579 u_char *ptr = &((u_char *)skb->data)[6];
580 for (i = 0; i < 6; i++)
581 printk("%02x", ptr[i]);
582 }
583 printk(" to ");
584 {
585 int i;
586 u_char *ptr = (u_char *)skb->data;
587 for (i = 0; i < 6; i++)
588 printk("%02x", ptr[i]);
589 }
590 printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len);
591 #endif
592
593 entry = priv->cur_tx % TX_RING_SIZE;
594
595 priv->tx_ring[entry]->TMD2 = -(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
596 priv->tx_ring[entry]->TMD3 = 0x0000;
597 memcpy(priv->tx_buff[entry], skb->data, skb->len);
598
599 #if 0
600 {
601 int i, len;
602
603 len = skb->len > 64 ? 64 : skb->len;
604 for (i = 0; i < len; i += 8) {
605 int j;
606 printk("%02x:", i);
607 for (j = 0; (j < 16) && ((i+j) < len); j++) {
608 if (!(j & 1))
609 printk(" ");
610 printk("%02x", priv->tx_buff[entry][i+j]);
611 }
612 printk("\n");
613 }
614 }
615 #endif
616
617 priv->tx_ring[entry]->TMD1 = (priv->tx_ring[entry]->TMD1 &
618 0x00ff)|TF_OWN|TF_STP|TF_ENP;
619
620 dev_kfree_skb(skb, FREE_WRITE);
621
622 priv->cur_tx++;
623 if ((priv->cur_tx >= TX_RING_SIZE)&&(priv->dirty_tx >= TX_RING_SIZE)){
624
625 #if 0
626 printk("*** Subtracting TX_RING_SIZE from cur_tx (%d) and dirty_tx (%d)\n",
627 priv->cur_tx, priv->dirty_tx);
628 #endif
629
630 priv->cur_tx -= TX_RING_SIZE;
631 priv->dirty_tx -= TX_RING_SIZE;
632 }
633
634
635 board->Lance.RAP = CSR0;
636 board->Lance.RDP = INEA|TDMD;
637
638 dev->trans_start = jiffies;
639
640 cli();
641 priv->lock = 0;
642 if ((priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1 & 0xff00) == 0)
643 dev->tbusy = 0;
644 else
645 priv->tx_full = 1;
646 sti();
647
648 return(0);
649 }
650
651
652 static int a2065_rx(struct device *dev)
653 {
654 struct a2065_private *priv = (struct a2065_private *)dev->priv;
655 int entry = priv->cur_rx % RX_RING_SIZE;
656 int i;
657
658
659 while (!(priv->rx_ring[entry]->RMD1 & RF_OWN)) {
660 int status = priv->rx_ring[entry]->RMD1 & 0xff00;
661
662 if (status != (RF_STP|RF_ENP)) {
663
664
665
666
667 if (status & RF_ENP)
668
669 priv->stats.rx_errors++;
670 if (status & RF_FRAM)
671 priv->stats.rx_frame_errors++;
672 if (status & RF_OFLO)
673 priv->stats.rx_over_errors++;
674 if (status & RF_CRC)
675 priv->stats.rx_crc_errors++;
676 if (status & RF_BUFF)
677 priv->stats.rx_fifo_errors++;
678 priv->rx_ring[entry]->RMD1 &= 0x00ff|RF_STP|RF_ENP;
679 } else {
680
681 short pkt_len = priv->rx_ring[entry]->RMD3;
682 struct sk_buff *skb;
683
684 if(pkt_len<60)
685 {
686 printk("%s: Runt packet!\n",dev->name);
687 priv->stats.rx_errors++;
688 }
689 else
690 {
691 skb = dev_alloc_skb(pkt_len+2);
692 if (skb == NULL) {
693 printk("%s: Memory squeeze, deferring packet.\n", dev->name);
694 for (i = 0; i < RX_RING_SIZE; i++)
695 if (priv->rx_ring[(entry+i) % RX_RING_SIZE]->RMD1 & RF_OWN)
696 break;
697
698 if (i > RX_RING_SIZE-2) {
699 priv->stats.rx_dropped++;
700 priv->rx_ring[entry]->RMD1 |= RF_OWN;
701 priv->cur_rx++;
702 }
703 break;
704 }
705 skb->dev = dev;
706 skb_reserve(skb,2);
707 skb_put(skb,pkt_len);
708 eth_copy_and_sum(skb,
709 priv->rx_buff[entry],
710 pkt_len,0);
711 skb->protocol=eth_type_trans(skb,dev);
712 #if 0
713 printk("RX pkt type 0x%04x from ",
714 ((u_short *)skb->data)[6]);
715 {
716 int i;
717 u_char *ptr = &((u_char *)skb->data)[6];
718 for (i = 0; i < 6; i++)
719 printk("%02x", ptr[i]);
720 }
721 printk(" to ");
722 {
723 int i;
724 u_char *ptr = (u_char *)skb->data;
725 for (i = 0; i < 6; i++)
726 printk("%02x", ptr[i]);
727 }
728 printk(" data 0x%08x len %d\n",
729 (int)skb->data, (int)skb->len);
730 #endif
731
732 netif_rx(skb);
733 priv->stats.rx_packets++;
734 }
735 }
736 priv->rx_ring[entry]->RMD1 |= RF_OWN;
737 entry = (++priv->cur_rx) % RX_RING_SIZE;
738 }
739
740 priv->cur_rx = priv->cur_rx % RX_RING_SIZE;
741
742
743
744
745 return(0);
746 }
747
748
749 static struct enet_statistics *a2065_get_stats(struct device *dev)
750 {
751 struct a2065_private *priv = (struct a2065_private *)dev->priv;
752
753 return(&priv->stats);
754 }
755
756
757
758
759 static void set_multicast_list(struct device *dev)
760 {
761 struct a2065_private *priv = (struct a2065_private *)dev->priv;
762 struct A2065Board *board = priv->board;
763 struct lancedata *alancedata;
764 alancedata = (struct lancedata *)board->RAM;
765
766
767 board->Lance.RAP = CSR0;
768 board->Lance.RDP = STOP;
769
770
771 board->Lance.RAP = CSR3;
772 board->Lance.RDP = BSWP;
773
774 if (dev->flags&IFF_PROMISC) {
775
776 printk("%s: Promiscuous mode enabled.\n", dev->name);
777 alancedata->init.Mode = PROM;
778 } else {
779 short multicast_table[4];
780 int num_addrs=dev->mc_count;
781 if(dev->flags&IFF_ALLMULTI)
782 num_addrs=1;
783
784
785
786
787 memset(multicast_table, (num_addrs == 0) ? 0 : -1,
788 sizeof(multicast_table));
789 alancedata->init.LADRF[0] = multicast_table[0]<<16 |
790 multicast_table[1];
791 alancedata->init.LADRF[1] = multicast_table[2]<<16 |
792 multicast_table[3];
793 alancedata->init.Mode = 0x0000;
794 }
795
796 board->Lance.RAP = CSR0;
797 board->Lance.RDP = INEA|STRT|IDON|INIT;
798 }