This source file includes following definitions.
- ni52_close
- ni52_open
- check586
- alloc586
- ni52_probe
- ni52_probe1
- init586
- alloc_rfa
- ni52_interrupt
- ni52_rcv_int
- ni52_rnr_int
- ni52_xmt_int
- startrecv586
- ni52_send_packet
- ni52_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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 #include <linux/kernel.h>
81 #include <linux/sched.h>
82 #include <linux/string.h>
83 #include <linux/errno.h>
84 #include <linux/ioport.h>
85 #include <linux/malloc.h>
86 #include <linux/interrupt.h>
87 #include <linux/delay.h>
88 #include <asm/bitops.h>
89 #include <asm/io.h>
90
91 #include <linux/netdevice.h>
92 #include <linux/etherdevice.h>
93 #include <linux/skbuff.h>
94
95 #include "ni52.h"
96
97 #define DEBUG
98 #define SYSBUSVAL 1
99
100 #define ni_attn586() {outb(0,dev->base_addr+NI52_ATTENTION);}
101 #define ni_reset586() {outb(0,dev->base_addr+NI52_RESET);}
102
103 #define make32(ptr16) (p->memtop + (short) (ptr16) )
104 #define make24(ptr32) ((char *) (ptr32) - p->base)
105 #define make16(ptr32) ((unsigned short) ((unsigned long) (ptr32) - (unsigned long) p->memtop ))
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121 #define RECV_BUFF_SIZE 1524
122 #define XMIT_BUFF_SIZE 1524
123 #define NUM_XMIT_BUFFS 1
124 #define NUM_RECV_BUFFS_8 4
125 #define NUM_RECV_BUFFS_16 9
126 #define NO_NOPCOMMANDS
127
128
129
130 #define DELAY(x) {int i=jiffies; \
131 if(loops_per_sec == 1) \
132 while(i+(x)>jiffies); \
133 else \
134 __delay((loops_per_sec>>5)*x); \
135 }
136
137
138 #define DELAY_16(); { __delay( (loops_per_sec>>16)+1 ); }
139
140
141 #define WAIT_4_SCB_CMD() { int i; \
142 for(i=0;i<1024;i++) { \
143 if(!p->scb->cmd) break; \
144 DELAY_16(); \
145 if(i == 1023) { \
146 printk("%s: scb_cmd timed out .. resetting i82586\n",dev->name); \
147 ni_reset586(); } } }
148
149
150 #define NI52_TOTAL_SIZE 16
151 #define NI52_ADDR0 0x02
152 #define NI52_ADDR1 0x07
153 #define NI52_ADDR2 0x01
154
155 #ifndef HAVE_PORTRESERVE
156 #define check_region(ioaddr, size) 0
157 #define request_region(ioaddr, size,name) do ; while (0)
158 #endif
159
160 static int ni52_probe1(struct device *dev,int ioaddr);
161 static void ni52_interrupt(int irq,struct pt_regs *reg_ptr);
162 static int ni52_open(struct device *dev);
163 static int ni52_close(struct device *dev);
164 static int ni52_send_packet(struct sk_buff *,struct device *);
165 static struct enet_statistics *ni52_get_stats(struct device *dev);
166 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
167
168
169 static int init586(struct device *dev,int num_addrs,void *addrs);
170 static int check586(struct device *dev,char *where,unsigned size);
171 static void alloc586(struct device *dev);
172 static void startrecv586(struct device *dev);
173 static void *alloc_rfa(struct device *dev,void *ptr);
174 static void ni52_rcv_int(struct device *dev);
175 static void ni52_xmt_int(struct device *dev);
176 static void ni52_rnr_int(struct device *dev);
177
178 struct priv
179 {
180 struct enet_statistics stats;
181 unsigned long base;
182 char *memtop;
183 volatile struct rfd_struct *rfd_last,*rfd_top,*rfd_first;
184 volatile struct scp_struct *scp;
185 volatile struct iscp_struct *iscp;
186 volatile struct scb_struct *scb;
187 volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
188 volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
189 #if (NUM_XMIT_BUFFS == 1)
190 volatile struct nop_cmd_struct *nop_cmds[2];
191 #else
192 volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
193 #endif
194 volatile int nop_point,num_recv_buffs;
195 volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
196 volatile int xmit_count,xmit_last;
197 };
198
199
200
201
202
203
204 static int ni52_close(struct device *dev)
205 {
206 free_irq(dev->irq);
207 irq2dev_map[dev->irq] = 0;
208
209 ni_reset586();
210
211 dev->start = 0;
212 dev->tbusy = 0;
213
214 return 0;
215 }
216
217
218
219
220
221 static int ni52_open(struct device *dev)
222 {
223 alloc586(dev);
224 init586(dev,0,NULL);
225 startrecv586(dev);
226
227 if(request_irq(dev->irq, &ni52_interrupt,0,"ni52"))
228 {
229 ni_reset586();
230 return -EAGAIN;
231 }
232 irq2dev_map[dev->irq] = dev;
233
234 dev->interrupt = 0;
235 dev->tbusy = 0;
236 dev->start = 1;
237
238 return 0;
239 }
240
241
242
243
244
245 static int check586(struct device *dev,char *where,unsigned size)
246 {
247 struct priv *p = (struct priv *) dev->priv;
248 char *iscp_addrs[2];
249 int i;
250
251 p->base = (unsigned long) where + size - 0x01000000;
252 p->memtop = where + size;
253 p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
254 memset((char *)p->scp,0, sizeof(struct scp_struct));
255 p->scp->sysbus = SYSBUSVAL;
256
257 iscp_addrs[0] = where;
258 iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
259
260 for(i=0;i<2;i++)
261 {
262 p->iscp = (struct iscp_struct *) iscp_addrs[i];
263 memset((char *)p->iscp,0, sizeof(struct iscp_struct));
264
265 p->scp->iscp = make24(p->iscp);
266 p->iscp->busy = 1;
267
268 ni_reset586();
269 ni_attn586();
270 DELAY(2);
271
272 if(p->iscp->busy)
273 return 0;
274 }
275 return 1;
276 }
277
278
279
280
281
282 void alloc586(struct device *dev)
283 {
284 struct priv *p = (struct priv *) dev->priv;
285
286 ni_reset586();
287 DELAY(2);
288
289 p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
290 p->scb = (struct scb_struct *) (dev->mem_start);
291 p->iscp = (struct iscp_struct *) ((char *)p->scp - sizeof(struct iscp_struct));
292
293 memset((char *) p->iscp,0,sizeof(struct iscp_struct));
294 memset((char *) p->scp ,0,sizeof(struct scp_struct));
295
296 p->scp->iscp = make24(p->iscp);
297 p->scp->sysbus = SYSBUSVAL;
298 p->iscp->scb_offset = make16(p->scb);
299
300 p->iscp->busy = 1;
301 ni_reset586();
302 ni_attn586();
303
304 DELAY(2);
305
306 if(p->iscp->busy)
307 printk("%s: Init-Problems (alloc).\n",dev->name);
308
309 memset((char *)p->scb,0,sizeof(struct scb_struct));
310 }
311
312
313
314
315
316 int ni52_probe(struct device *dev)
317 {
318 int *port, ports[] = {0x300, 0x280, 0x360 , 0x320 , 0x340, 0};
319 int base_addr = dev->base_addr;
320
321 if (base_addr > 0x1ff)
322 if( (inb(base_addr+NI52_MAGIC1) == NI52_MAGICVAL1) &&
323 (inb(base_addr+NI52_MAGIC2) == NI52_MAGICVAL2))
324 return ni52_probe1(dev, base_addr);
325 else if (base_addr > 0)
326 return ENXIO;
327
328 for (port = ports; *port; port++) {
329 int ioaddr = *port;
330 if (check_region(ioaddr, NI52_TOTAL_SIZE))
331 continue;
332 if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
333 !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2))
334 continue;
335
336 dev->base_addr = ioaddr;
337 if (ni52_probe1(dev, ioaddr) == 0)
338 return 0;
339 }
340
341 dev->base_addr = base_addr;
342 return ENODEV;
343 }
344
345 static int ni52_probe1(struct device *dev,int ioaddr)
346 {
347 long memaddrs[] = { 0xd0000,0xd2000,0xc8000,0xca000,0xd4000,0xd6000,0xd8000, 0 };
348 int i,size;
349
350 for(i=0;i<ETH_ALEN;i++)
351 dev->dev_addr[i] = inb(dev->base_addr+i);
352
353 if(dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1
354 || dev->dev_addr[2] != NI52_ADDR2)
355 return ENODEV;
356
357 printk("%s: Ni52 found at %#3lx, ",dev->name,dev->base_addr);
358
359 request_region(ioaddr,NI52_TOTAL_SIZE,"ni52");
360
361 dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
362
363 memset((char *) dev->priv,0,sizeof(struct priv));
364
365
366
367
368 if(dev->mem_start != 0)
369 {
370 size = 0x4000;
371 if(!check586(dev,(char *) dev->mem_start,size)) {
372 size = 0x2000;
373 if(!check586(dev,(char *) dev->mem_start,size)) {
374 printk("?memprobe, Can't find memory at 0x%lx!\n",dev->mem_start);
375 return ENODEV;
376 }
377 }
378 }
379 else
380 {
381 for(i=0;;i++)
382 {
383 if(!memaddrs[i]) {
384 printk("?memprobe, Can't find io-memory!\n");
385 return ENODEV;
386 }
387 dev->mem_start = memaddrs[i];
388 size = 0x2000;
389 if(check586(dev,(char *)dev->mem_start,size))
390 break;
391 size = 0x4000;
392 if(check586(dev,(char *)dev->mem_start,size))
393 break;
394 }
395 }
396 dev->mem_end = dev->mem_start + size;
397
398 ((struct priv *) (dev->priv))->base = dev->mem_start + size - 0x01000000;
399 alloc586(dev);
400
401
402 if(size == 0x2000)
403 ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_8;
404 else
405 ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
406
407 printk("Memaddr: 0x%lx, Memsize: %d, ",dev->mem_start,size);
408
409 if(dev->irq < 2)
410 {
411 autoirq_setup(0);
412 ni_reset586();
413 ni_attn586();
414 if(!(dev->irq = autoirq_report(2)))
415 {
416 printk("?autoirq, Failed to detect IRQ line!\n");
417 return 1;
418 }
419 }
420 else if(dev->irq == 2)
421 dev->irq = 9;
422
423 printk("IRQ %d.\n",dev->irq);
424
425 dev->open = &ni52_open;
426 dev->stop = &ni52_close;
427 dev->get_stats = &ni52_get_stats;
428 dev->hard_start_xmit = &ni52_send_packet;
429 dev->set_multicast_list = &set_multicast_list;
430
431 dev->if_port = 0;
432
433 ether_setup(dev);
434
435 dev->tbusy = 0;
436 dev->interrupt = 0;
437 dev->start = 0;
438
439 return 0;
440 }
441
442
443
444
445
446
447 static int init586(struct device *dev,int num_addrs,void *addrs)
448 {
449 void *ptr;
450 unsigned long s;
451 int i,result=0;
452 struct priv *p = (struct priv *) dev->priv;
453 volatile struct configure_cmd_struct *cfg_cmd;
454 volatile struct iasetup_cmd_struct *ias_cmd;
455 volatile struct tdr_cmd_struct *tdr_cmd;
456 volatile struct mcsetup_cmd_struct *mc_cmd;
457
458 ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
459
460 cfg_cmd = (struct configure_cmd_struct *)ptr;
461 cfg_cmd->cmd_status = 0;
462 cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST;
463 cfg_cmd->cmd_link = 0xffff;
464
465 cfg_cmd->byte_cnt = 0x0a;
466 cfg_cmd->fifo = 0x08;
467 cfg_cmd->sav_bf = 0x40;
468 cfg_cmd->adr_len = 0x2e;
469 cfg_cmd->priority = 0x00;
470 cfg_cmd->ifs = 0x60;
471 cfg_cmd->time_low = 0x00;
472 cfg_cmd->time_high = 0xf2;
473 cfg_cmd->promisc = (num_addrs < 0) ? 1 : 0;
474 cfg_cmd->carr_coll = 0x00;
475
476 p->scb->cbl_offset = make16(cfg_cmd);
477
478 p->scb->cmd = CUC_START;
479 ni_attn586();
480
481 s = jiffies;
482 while(!(cfg_cmd->cmd_status & STAT_COMPL))
483 if(jiffies-s > 30) break;
484
485 if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
486 {
487 printk("%s (ni52): configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
488 return 1;
489 }
490
491
492
493
494 ias_cmd = (struct iasetup_cmd_struct *)ptr;
495
496 ias_cmd->cmd_status = 0;
497 ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST;
498 ias_cmd->cmd_link = 0xffff;
499
500 memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN);
501
502 p->scb->cbl_offset = make16(ias_cmd);
503
504 p->scb->cmd = CUC_START;
505 ni_attn586();
506
507 s = jiffies;
508 while(!(ias_cmd->cmd_status & STAT_COMPL))
509 if(jiffies-s > 30) break;
510
511 if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
512 printk("%s (ni52): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
513 return 1;
514 }
515
516
517
518
519 tdr_cmd = (struct tdr_cmd_struct *)ptr;
520
521 tdr_cmd->cmd_status = 0;
522 tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST;
523 tdr_cmd->cmd_link = 0xffff;
524 tdr_cmd->status = 0;
525
526 p->scb->cbl_offset = make16(tdr_cmd);
527
528 p->scb->cmd = CUC_START;
529 ni_attn586();
530
531 s = jiffies;
532 while(!(tdr_cmd->cmd_status & STAT_COMPL))
533 if(jiffies - s > 30) {
534 printk("%s: Problems while running the TDR.\n",dev->name);
535 result = 1;
536 }
537
538 if(!result)
539 {
540 DELAY(2);
541 result = tdr_cmd->status;
542
543 p->scb->cmd = p->scb->status & STAT_MASK;
544 ni_attn586();
545
546 if(result & TDR_LNK_OK) ;
547 else if(result & TDR_XCVR_PRB)
548 printk("%s: TDR: Transceiver problem!\n",dev->name);
549 else if(result & TDR_ET_OPN)
550 printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
551 else if(result & TDR_ET_SRT)
552 {
553 if (result & TDR_TIMEMASK)
554 printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
555 }
556 else
557 printk("%s: TDR: Unknown status %04x\n",dev->name,result);
558 }
559
560
561
562
563 p->scb->cmd = p->scb->status & STAT_MASK;
564 ni_attn586();
565
566
567
568
569 #if (NUM_XMIT_BUFFS == 1)
570 for(i=0;i<2;i++)
571 {
572 p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
573 p->nop_cmds[i]->cmd_cmd = CMD_NOP;
574 p->nop_cmds[i]->cmd_status = 0;
575 p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
576 ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
577 }
578 p->xmit_cmds[0] = (struct transmit_cmd_struct *)ptr;
579 ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
580 #else
581 for(i=0;i<NUM_XMIT_BUFFS;i++)
582 {
583 p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
584 p->nop_cmds[i]->cmd_cmd = CMD_NOP;
585 p->nop_cmds[i]->cmd_status = 0;
586 p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
587 ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
588 p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr;
589 ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
590 }
591 #endif
592
593 ptr = alloc_rfa(dev,(void *)ptr);
594
595
596
597
598
599 if(num_addrs > 0)
600 {
601 int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
602 if(len <= 0)
603 {
604 printk("%s: Ooooops, no memory for MC-Setup!\n",dev->name);
605 }
606 else
607 {
608 if(len < num_addrs)
609 {
610 num_addrs = len;
611 printk("%s: Sorry, can only apply %d MC-Address(es).\n",dev->name,num_addrs);
612 }
613 mc_cmd = (struct mcsetup_cmd_struct *) ptr;
614 mc_cmd->cmd_status = 0;
615 mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
616 mc_cmd->cmd_link = 0xffff;
617 mc_cmd->mc_cnt = num_addrs * 6;
618 for(i=0;i<num_addrs;i++)
619 memcpy((char *) mc_cmd->mc_list[i],((char (*)[6]) addrs)[i],6);
620 p->scb->cbl_offset = make16(mc_cmd);
621 p->scb->cmd = CUC_START;
622 ni_attn586();
623 s = jiffies;
624 while(!(mc_cmd->cmd_status & STAT_COMPL))
625 if(jiffies - s > 30)
626 break;
627 if(!(mc_cmd->cmd_status & STAT_COMPL))
628 printk("%s: Can't apply multicast-address-list.\n",dev->name);
629 }
630 }
631
632
633
634
635 for(i=0;i<NUM_XMIT_BUFFS;i++)
636 {
637 p->xmit_cbuffs[i] = (char *)ptr;
638 ptr = (char *) ptr + XMIT_BUFF_SIZE;
639 p->xmit_buffs[i] = (struct tbd_struct *)ptr;
640 ptr = (char *) ptr + sizeof(struct tbd_struct);
641 if((void *)ptr > (void *)p->iscp)
642 {
643 printk("%s: not enough shared-mem for your configuration!\n",dev->name);
644 return 1;
645 }
646 memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
647 memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
648 p->xmit_cmds[i]->cmd_status = STAT_COMPL;
649 p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
650 p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
651 p->xmit_buffs[i]->next = 0xffff;
652 p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
653 }
654
655 p->xmit_count = 0;
656 p->xmit_last = 0;
657 #ifndef NO_NOPCOMMANDS
658 p->nop_point = 0;
659 #endif
660
661
662
663
664 #ifndef NO_NOPCOMMANDS
665 p->scb->cbl_offset = make16(p->nop_cmds[0]);
666 p->scb->cmd = CUC_START;
667 ni_attn586();
668 WAIT_4_SCB_CMD();
669 #else
670 p->xmit_cmds[0]->cmd_link = 0xffff;
671 p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT;
672 #endif
673
674 return 0;
675 }
676
677
678
679
680
681
682 static void *alloc_rfa(struct device *dev,void *ptr)
683 {
684 volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
685 volatile struct rbd_struct *rbd;
686 int i;
687 struct priv *p = (struct priv *) dev->priv;
688
689 memset((char *) rfd,0,sizeof(struct rfd_struct)*p->num_recv_buffs);
690 p->rfd_first = rfd;
691
692 for(i = 0; i < p->num_recv_buffs; i++)
693 rfd[i].next = make16(rfd + (i+1) % p->num_recv_buffs);
694 rfd[p->num_recv_buffs-1].last = RFD_SUSP;
695
696 ptr = (void *) (rfd + p->num_recv_buffs);
697
698 rbd = (struct rbd_struct *) ptr;
699 ptr = (void *) (rbd + p->num_recv_buffs);
700
701
702 memset((char *) rbd,0,sizeof(struct rbd_struct)*p->num_recv_buffs);
703
704 for(i=0;i<p->num_recv_buffs;i++)
705 {
706 rbd[i].next = make16((rbd + (i+1) % p->num_recv_buffs));
707 rbd[i].size = RECV_BUFF_SIZE;
708 rbd[i].buffer = make24(ptr);
709 ptr = (char *) ptr + RECV_BUFF_SIZE;
710 }
711
712 p->rfd_top = p->rfd_first;
713 p->rfd_last = p->rfd_first + p->num_recv_buffs - 1;
714
715 p->scb->rfa_offset = make16(p->rfd_first);
716 p->rfd_first->rbd_offset = make16(rbd);
717
718 return ptr;
719 }
720
721
722
723
724
725
726 static void ni52_interrupt(int irq,struct pt_regs *reg_ptr)
727 {
728 struct device *dev = (struct device *) irq2dev_map[irq];
729 unsigned short stat;
730 struct priv *p;
731
732 if (dev == NULL) {
733 printk ("ni52-interrupt: irq %d for unknown device.\n",(int) -(((struct pt_regs *)reg_ptr)->orig_eax+2));
734 return;
735 }
736 p = (struct priv *) dev->priv;
737
738 dev->interrupt = 1;
739
740 while((stat=p->scb->status & STAT_MASK))
741 {
742 p->scb->cmd = stat;
743 ni_attn586();
744
745 if(stat & STAT_CX)
746 ni52_xmt_int(dev);
747
748 if(stat & STAT_FR)
749 ni52_rcv_int(dev);
750
751 #ifndef NO_NOPCOMMANDS
752 if(stat & STAT_CNA)
753 {
754 if(dev->start)
755 printk("%s: oops! CU has left active state. stat: %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
756 }
757 #endif
758
759 if(stat & STAT_RNR)
760 {
761 if(p->scb->status & RU_SUSPEND)
762 {
763 WAIT_4_SCB_CMD();
764 p->scb->cmd = RUC_RESUME;
765 ni_attn586();
766 }
767 else
768 {
769 printk("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
770 ni52_rnr_int(dev);
771 }
772 }
773 WAIT_4_SCB_CMD();
774 if(p->scb->cmd)
775 break;
776 }
777
778 dev->interrupt = 0;
779 }
780
781
782
783
784
785 static void ni52_rcv_int(struct device *dev)
786 {
787 int status;
788 unsigned short totlen;
789 struct sk_buff *skb;
790 struct rbd_struct *rbd;
791 struct priv *p = (struct priv *) dev->priv;
792
793 for(;(status = p->rfd_top->status) & STAT_COMPL;)
794 {
795 rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
796
797 if(status & STAT_OK)
798 {
799 if( (totlen = rbd->status) & RBD_LAST)
800 {
801 totlen &= RBD_MASK;
802 rbd->status = 0;
803 skb = (struct sk_buff *) dev_alloc_skb(totlen+2);
804 if(skb != NULL)
805 {
806 skb->dev = dev;
807 skb_reserve(skb,2);
808 memcpy(skb_put(skb,totlen),(char *) p->base+(unsigned long) rbd->buffer, totlen);
809 skb->protocol=eth_type_trans(skb,dev);
810 netif_rx(skb);
811 p->stats.rx_packets++;
812 }
813 else
814 p->stats.rx_dropped++;
815 }
816 else
817 {
818 printk("%s: received oversized frame.\n",dev->name);
819 p->stats.rx_dropped++;
820 }
821 }
822 else
823 {
824 printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);
825 p->stats.rx_errors++;
826 }
827 p->rfd_top->status = 0;
828 p->rfd_top->last = RFD_SUSP;
829 p->rfd_last->last = 0;
830 p->rfd_last = p->rfd_top;
831 p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next);
832 }
833 }
834
835
836
837
838
839 static void ni52_rnr_int(struct device *dev)
840 {
841 struct priv *p = (struct priv *) dev->priv;
842
843 p->stats.rx_errors++;
844
845 WAIT_4_SCB_CMD();
846 p->scb->cmd = RUC_ABORT;
847 ni_attn586();
848 WAIT_4_SCB_CMD();
849
850 alloc_rfa(dev,(char *)p->rfd_first);
851 startrecv586(dev);
852
853 printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->status);
854
855 }
856
857
858
859
860
861 static void ni52_xmt_int(struct device *dev)
862 {
863 int status;
864 struct priv *p = (struct priv *) dev->priv;
865
866 status = p->xmit_cmds[p->xmit_last]->cmd_status;
867 if(!(status & STAT_COMPL))
868 printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);
869
870 if(status & STAT_OK)
871 {
872 p->stats.tx_packets++;
873 p->stats.collisions += (status & TCMD_MAXCOLLMASK);
874 }
875 else
876 {
877 p->stats.tx_errors++;
878 if(status & TCMD_LATECOLL) {
879 printk("%s: late collision detected.\n",dev->name);
880 p->stats.collisions++;
881 }
882 else if(status & TCMD_NOCARRIER) {
883 p->stats.tx_carrier_errors++;
884 printk("%s: no carrier detected.\n",dev->name);
885 }
886 else if(status & TCMD_LOSTCTS)
887 printk("%s: loss of CTS detected.\n",dev->name);
888 else if(status & TCMD_UNDERRUN) {
889 p->stats.tx_fifo_errors++;
890 printk("%s: DMA underrun detected.\n",dev->name);
891 }
892 else if(status & TCMD_MAXCOLL) {
893 printk("%s: Max. collisions exceeded.\n",dev->name);
894 p->stats.collisions += 16;
895 }
896 }
897
898 #if (NUM_XMIT_BUFFS != 1)
899 if( (++p->xmit_last) == NUM_XMIT_BUFFS)
900 p->xmit_last = 0;
901 #endif
902
903 dev->tbusy = 0;
904 mark_bh(NET_BH);
905 }
906
907
908
909
910
911 static void startrecv586(struct device *dev)
912 {
913 struct priv *p = (struct priv *) dev->priv;
914
915 p->scb->rfa_offset = make16(p->rfd_first);
916 p->scb->cmd = RUC_START;
917 ni_attn586();
918 WAIT_4_SCB_CMD();
919 }
920
921
922
923
924
925 static int ni52_send_packet(struct sk_buff *skb, struct device *dev)
926 {
927 int len,i;
928 #ifndef NO_NOPCOMMANDS
929 int next_nop;
930 #endif
931 struct priv *p = (struct priv *) dev->priv;
932
933 if(dev->tbusy)
934 {
935 int tickssofar = jiffies - dev->trans_start;
936 if (tickssofar < 5)
937 return 1;
938
939 if(p->scb->status & CU_ACTIVE)
940 {
941 dev->tbusy = 0;
942 #ifdef DEBUG
943 printk("%s: strange ... timeout with CU active?!?\n",dev->name);
944 printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)p->xmit_cmds[0]->cmd_status,(int)p->nop_cmds[0]->cmd_status,(int)p->nop_cmds[1]->cmd_status,(int)p->nop_point);
945 #endif
946 p->scb->cmd = CUC_ABORT;
947 ni_attn586();
948 WAIT_4_SCB_CMD();
949 p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
950 p->scb->cmd = CUC_START;
951 ni_attn586();
952 WAIT_4_SCB_CMD();
953 dev->trans_start = jiffies;
954 return 0;
955 }
956 else
957 {
958 #ifdef DEBUG
959 printk("%s: xmitter timed out, try to restart! stat: %04x\n",dev->name,p->scb->status);
960 printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status);
961 #endif
962 ni52_close(dev);
963 ni52_open(dev);
964 }
965 dev->trans_start = jiffies;
966 return 0;
967 }
968
969 if(skb == NULL)
970 {
971 dev_tint(dev);
972 return 0;
973 }
974
975 if (skb->len <= 0)
976 return 0;
977 if(skb->len > XMIT_BUFF_SIZE)
978 {
979 printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %ld bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
980 return 0;
981 }
982
983 if (set_bit(0, (void*)&dev->tbusy) != 0)
984 printk("%s: Transmitter access conflict.\n", dev->name);
985 else
986 {
987 memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len);
988 len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
989
990 #if (NUM_XMIT_BUFFS == 1)
991 # ifdef NO_NOPCOMMANDS
992 p->xmit_buffs[0]->size = TBD_LAST | len;
993 for(i=0;i<16;i++)
994 {
995 p->scb->cbl_offset = make16(p->xmit_cmds[0]);
996 p->scb->cmd = CUC_START;
997 p->xmit_cmds[0]->cmd_status = 0;
998
999 ni_attn586();
1000 dev->trans_start = jiffies;
1001 if(!i)
1002 dev_kfree_skb(skb,FREE_WRITE);
1003 WAIT_4_SCB_CMD();
1004 if( (p->scb->status & CU_ACTIVE))
1005 break;
1006 if(p->xmit_cmds[0]->cmd_status)
1007 break;
1008 if(i==15)
1009 printk("%s: Can't start transmit-command.\n",dev->name);
1010 }
1011 # else
1012 next_nop = (p->nop_point + 1) & 0x1;
1013 p->xmit_buffs[0]->size = TBD_LAST | len;
1014
1015 p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link
1016 = make16((p->nop_cmds[next_nop]));
1017 p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
1018
1019 p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
1020 dev->trans_start = jiffies;
1021 p->nop_point = next_nop;
1022 dev_kfree_skb(skb,FREE_WRITE);
1023 # endif
1024 #else
1025 p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
1026 if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )
1027 next_nop = 0;
1028
1029 p->xmit_cmds[p->xmit_count]->cmd_status = 0;
1030 p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link
1031 = make16((p->nop_cmds[next_nop]));
1032 p->nop_cmds[next_nop]->cmd_status = 0;
1033
1034 p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
1035 dev->trans_start = jiffies;
1036 p->xmit_count = next_nop;
1037
1038 cli();
1039 if(p->xmit_count != p->xmit_last)
1040 dev->tbusy = 0;
1041 sti();
1042 dev_kfree_skb(skb,FREE_WRITE);
1043 #endif
1044 }
1045 return 0;
1046 }
1047
1048
1049
1050
1051
1052 static struct enet_statistics *ni52_get_stats(struct device *dev)
1053 {
1054 struct priv *p = (struct priv *) dev->priv;
1055 unsigned short crc,aln,rsc,ovrn;
1056
1057 crc = p->scb->crc_errs;
1058 p->scb->crc_errs -= crc;
1059 aln = p->scb->aln_errs;
1060 p->scb->aln_errs -= aln;
1061 rsc = p->scb->rsc_errs;
1062 p->scb->rsc_errs -= rsc;
1063 ovrn = p->scb->ovrn_errs;
1064 p->scb->ovrn_errs -= ovrn;
1065
1066 p->stats.rx_crc_errors += crc;
1067 p->stats.rx_fifo_errors += ovrn;
1068 p->stats.rx_frame_errors += aln;
1069 p->stats.rx_dropped += rsc;
1070
1071 return &p->stats;
1072 }
1073
1074
1075
1076
1077
1078 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
1079 {
1080 if(!dev->start && !num_addrs)
1081 {
1082 printk("%s: Can't apply promiscuous/multicastmode to a not running interface.\n",dev->name);
1083 return;
1084 }
1085
1086 dev->start = 0;
1087 alloc586(dev);
1088 init586(dev,num_addrs,addrs);
1089 startrecv586(dev);
1090 dev->start = 1;
1091 }
1092
1093
1094
1095