|
|
1.1 root 1: /* (-lgl
2: * COHERENT Driver Kit Version 1.1.0
3: * Copyright (c) 1982, 1990 by Mark Williams Company.
4: * All rights reserved. May not be copied without permission.
5: -lgl) */
6: /*
7: * Tiac ARCNET PC-234 Device Driver
8: *
9: * True support for up to 4 network cards through minor devices 0-3.
10: * Up to 4 protocols now supported. Novell access is through normal
11: * minor device. Netbios access is through novell minor device + 16.
12: */
13:
14: #include <sys/coherent.h>
15: #include <sys/con.h>
16: #include <sys/devices.h>
17: #include <sys/sched.h>
18: #include <sys/seg.h>
19: #include <sys/stat.h>
20: #include <sys/tnioctl.h>
21: #include <errno.h>
22:
23: /*
24: * External functions.
25: */
26: extern int wakeup();
27: extern void pollwake();
28: extern void defer();
29:
30: /*
31: * Driver functions.
32: */
33: void tnopen();
34: void tnclose();
35: int tnread();
36: int tnwrite();
37: int tnioctl();
38: void tncycle();
39: void tnload();
40: void tnuload();
41: int tnpoll();
42: int nonedev();
43: int nulldev();
44: void tn0intr();
45: void tn1intr();
46: void tn2intr();
47: void tn3intr();
48: void tnintr();
49:
50: /*
51: * Driver Configuration.
52: */
53: CON
54: tncon = {
55: DFCHR|DFPOL, /* Flags */
56: TN_MAJOR, /* Major Index */
57: tnopen, /* Open */
58: tnclose, /* Close */
59: nonedev, /* Block */
60: tnread, /* Read */
61: tnwrite, /* Write */
62: tnioctl, /* Ioctl */
63: nulldev, /* Power fail */
64: tncycle, /* Timeout */
65: tnload, /* Load */
66: tnuload, /* Unload */
67: tnpoll /* Poll */
68: };
69:
70: /*
71: * Interrupt Entry Points.
72: */
73: void (*tnintf[4])() = {
74: tn0intr,
75: tn1intr,
76: tn2intr,
77: tn3intr
78: };
79:
80: #define BIT(n) (1 << (n))
81:
82: /*
83: * Bitmask, indexed by bit numbers 0..7.
84: */
85: static unsigned char bitm[8] = { BIT(0), BIT(1), BIT(2), BIT(3),
86: BIT(4), BIT(5), BIT(6), BIT(7) };
87:
88: /*
89: * Patchable parameters - Cards 0-3.
90: */
91: /* Card 0 1 2 3 */
92: int TNIRQ [4] = { 2, 7, 4, 0 };
93: saddr_t TNSEL [4] = { 0xD000, 0x0000, 0x0000, 0x0000 };
94: int TNPORT[4] = { 0x2E0, 0x220, 0x240, 0x000 };
95:
96: /*
97: * Patchable parameters - Prefix Byte.
98: * Indexed by high nibble of minor device.
99: */
100: int TNPREFIX[4] = { 0x00, 0xF3, 0x00, 0x00 };
101:
102: /*
103: * Patchable variables.
104: * TNTIME = Transmit watchdog timer in seconds.
105: */
106: int TNTIME = 5;
107:
108: /*
109: * Register addresses.
110: */
111: #define NIR (tp->tnport) /* Network Interrupt Mask Reg (w) */
112: #define NSR (tp->tnport) /* Network Status Register (r) */
113: #define NCR (tp->tnport+1) /* Network Command Register (w) */
114: #define NZR (tp->tnport+8) /* Network Zap (reset) Reg (w) */
115:
116: /*
117: * Network Interrupt Register (NIR).
118: */
119: #define NI_Tx BIT(0) /* Enable Transmitter Avail Intr */
120: #define NI_RECON BIT(2) /* Enable Reconfiguration Intr */
121: #define NI_Rx BIT(7) /* Enable Receiver Full Intr */
122:
123: /*
124: * Network Status Register (NSR).
125: */
126: #define NS_TxRDY BIT(0) /* Transmitter Available */
127: #define NS_TxACK BIT(1) /* Transmit Message Acknowledged */
128: #define NS_RECON BIT(2) /* Network Reconfiguration */
129: #define NS_TEST BIT(3) /* Test */
130: #define NS_POR BIT(4) /* Power on Reset */
131: #define NS_ETS1 BIT(5) /* Extended Timeout Status 1 */
132: #define NS_ETS2 BIT(6) /* Extended Timeout Status 2 */
133: #define NS_RxRDY BIT(7) /* Packet Received - Receiver Off */
134:
135: /*
136: * Network Command Register (NCR).
137: */
138: #define NC_TxDIS (((0)<<3) + 1) /* Disable Transmitter */
139: #define NC_RxDIS (((0)<<3) + 2) /* Disable Receiver */
140: #define NC_TxENA(n) (((n)<<3) + 3) /* Enable Transmitter on Page n */
141: #define NC_RxENA(n) (((n)<<3)+0x84) /* Enable Receiver on Page n */
142: #define NC_DFC (((1)<<3) + 5) /* Define Configuration (2k buf) */
143: #define NC_POR (((1)<<3) + 6) /* Clear NS_POR flag */
144: #define NC_RECON (((2)<<3) + 6) /* Clear NS_RECON flag */
145:
146: /*
147: * Packet Control.
148: */
149: struct tnet_s {
150:
151: /*
152: * Four buffers per card - 2 receive, 2 transmit.
153: */
154: struct tnbuf_s { /* tnget*,tnput* use tn_sel:tn_off */
155: unsigned tn_off; /* tn_sel:tn_off = current byte */
156: saddr_t tn_sel; /* network buffer selector */
157: struct tnbuf_s *tn_next;/* pointer to next pkt in queue */
158: unsigned tn_ena; /* Command to enable packet */
159: unsigned tn_base;/* tn_sel:tn_base = pkt address */
160: unsigned tn_xnid;/* Transmit node id */
161: unsigned tn_xlen;/* Transmit length */
162: } tnbuf [4];
163:
164: struct tnbuf_s * RxBusy[4];/* Queues of full receive packets*/
165: struct tnbuf_s * RxIdle; /* Queue of empty receive packets */
166:
167: struct tnbuf_s * TxBusy; /* Queue of full transmit packets */
168: struct tnbuf_s * TxIdle; /* Queue of empty transmit packets */
169:
170: event_t RxPoll[4];/* Polls for input packets */
171: event_t TxPoll; /* Polls for empty output packets */
172:
173: char RxReq[4];/* 1 = Proc waiting for recv buf */
174: char TxReq; /* 1 = Proc waiting for xmit buf */
175: char refc[4];/* # opens, indexed by prefix code */
176:
177: unsigned tnmask; /* Interrupt enable mask */
178: unsigned tnport; /* Base I/O port */
179: char tnaddr[8];/* ARC-NET Node ID, low byte 1st */
180:
181: unsigned tntime; /* transmit watchdog timer */
182: unsigned recon; /* number of long reconfigurations */
183: unsigned pri; /* priority event occurred */
184: long rbolt; /* lbolt at last reconfiguration */
185: unsigned char bad[32];/* bit mask of bad nodes */
186: unsigned char mod[32];/* bit mask of changed nodes */
187: long recons; /* reconfiguration statistic */
188: SEG * statseg;/* Segment containing stats */
189:
190: } tnet [4];
191:
192: /*
193: * Load Routine.
194: */
195: void
196: tnload()
197: {
198: register struct tnet_s * tp;
199: register struct tnbuf_s * np;
200: faddr_t faddr;
201: paddr_t paddr;
202: int i;
203: int nid;
204: long delay;
205:
206: for ( tp = &tnet[0], i = 0; i < 4; i++, tp++ ) {
207:
208: /*
209: * Validate patchable parameters.
210: */
211: if ( (TNSEL[i] == 0) || (TNPORT[i] == 0) || (TNIRQ[i] == 0) ) {
212: TNPORT[i] = 0;
213: TNSEL[i] = 0;
214: TNIRQ[i] = 0;
215: continue;
216: }
217:
218: tp->tnport = TNPORT[i];
219:
220: /*
221: * Clear Power-On-Reset Flag.
222: */
223: outb( NCR, NC_POR );
224:
225: /*
226: * Validate card presence.
227: * NOTE: tp->tnport must be programmed before using NIR macro.
228: */
229: if ( inb(NSR) & (NS_TEST|NS_POR) ) {
230: tp->tnport = 0;
231: continue;
232: }
233:
234: /*
235: * Convert physical address into virtual address.
236: */
237: paddr = TNSEL[i] << 4L;
238: faddr = ptov( paddr, (fsize_t) 2048 );
239:
240: /*
241: * Verify dual-port memory existence.
242: * NOTE: Do not overwrite first two bytes [0xD1,nid].
243: */
244: sfword( faddr+8, 0x1234 );
245: if ( ffword( faddr+8 ) != 0x1234 ) {
246: vrelse( faddr );
247: tp->tnport = 0;
248: continue;
249: }
250:
251: /*
252: * Allocate statistics segment.
253: */
254: tp->statseg = salloc( (fsize_t) (256*NTNST*4), SFSYST|SFHIGH );
255:
256: /*
257: * Out of memory.
258: */
259: if ( ! tp->statseg ) {
260: printf( "tn%d: out of memory\n", i );
261: vrelse( faddr );
262: tp->tnport = 0;
263: continue;
264: }
265:
266: tp->tnbuf[0].tn_sel =
267: tp->tnbuf[1].tn_sel =
268: tp->tnbuf[2].tn_sel =
269: tp->tnbuf[3].tn_sel = FP_SEL(faddr);
270:
271: tp->tnbuf[0].tn_ena = NC_TxENA(0);
272: tp->tnbuf[1].tn_ena = NC_TxENA(1);
273: tp->tnbuf[2].tn_ena = NC_RxENA(2);
274: tp->tnbuf[3].tn_ena = NC_RxENA(3);
275:
276: tp->tnbuf[0].tn_base = 0 * 512;
277: tp->tnbuf[1].tn_base = 1 * 512;
278: tp->tnbuf[2].tn_base = 2 * 512;
279: tp->tnbuf[3].tn_base = 3 * 512;
280:
281: /*
282: * Initialize transmit idle queue.
283: */
284: tp->TxIdle = &tp->tnbuf[0];
285: tp->tnbuf[0].tn_next = &tp->tnbuf[1];
286:
287: /*
288: * Initialize receive idle queue.
289: */
290: tp->RxIdle = &tp->tnbuf[2];
291: tp->tnbuf[2].tn_next = &tp->tnbuf[3];
292:
293: /*
294: * Validate Node Id.
295: */
296: np = &tp->tnbuf[0];
297: np->tn_off = 0;
298: if ( tngetc(np) != 0xD1 ) {
299:
300: /*
301: * Initiate Power On Reset.
302: */
303: outb( NZR, 1 );
304:
305: /*
306: * Wait minimimum of 180 [suggest 250] milli-seconds.
307: * Should function properly up to at least 16 Mhz clock.
308: */
309: for ( delay = 250000L; --delay != 0; )
310: ;
311: }
312:
313: /*
314: * Validate and Remember Node Id.
315: */
316: np->tn_off = 0;
317: if ( tngetc(np) == 0xD1 )
318: tp->tnaddr[0] = tngetc( np );
319:
320: /*
321: * Record starting time of statistics collection.
322: */
323: faddr = tp->statseg->s_faddr + TnELAPSED*4;
324: for ( nid = 0; nid < 256; nid++, faddr += NTNST*4 )
325: kfcopy( &lbolt, faddr, sizeof(lbolt) );
326:
327: memset( tp->bad, -1, 32 ); /* Assume LAN is down */
328: memset( tp->mod, 0, 32 ); /* Assume no node changes */
329: tp->tnmask = NI_Rx | NI_RECON; /* Interrupts to enable */
330: outb( NIR, 0 ); /* Disable Interrupts */
331: outb( NCR, NC_POR ); /* Clear POR Flag */
332: outb( NCR, NC_DFC ); /* Define 2K buf config */
333: outb( NCR, NC_TxDIS ); /* Disable Transmitter */
334: outb( NCR, tp->RxIdle->tn_ena); /* Enable receiver */
335: setivec( TNIRQ[i], tnintf[i] ); /* Seize Interrupt Vector */
336: outb( NIR, tp->tnmask ); /* Enable Interrupts */
337: }
338:
339: /*
340: * Enable watchdog timer
341: */
342: drvl[TN_MAJOR].d_time = 1;
343: }
344:
345: /*
346: * Unload Routine.
347: */
348: void
349: tnuload( dev )
350: dev_t dev;
351: {
352: register struct tnet_s * tp;
353: register int i;
354: faddr_t faddr;
355:
356: /*
357: * Disable watchdog timer.
358: */
359: drvl[TN_MAJOR].d_time = 0;
360:
361: /*
362: * Scan network adaptors.
363: */
364: for ( tp = &tnet[0], i = 0; i < 4; i++, tp++ ) {
365:
366: if ( tp->tnport == 0 )
367: continue;
368:
369: /*
370: * Disable Interrupts
371: */
372: outb( NIR, 0 );
373:
374: /*
375: * Release interrupt vector.
376: */
377: clrivec( TNIRQ[i] );
378:
379: /*
380: * Release virtual address AFTER disabling interrupts.
381: */
382: if ( FP_SEL(faddr) = tp->tnbuf[0].tn_sel )
383: vrelse( faddr );
384:
385: /*
386: * Release stats segment.
387: */
388: if ( tp->statseg != NULL )
389: sfree( tp->statseg );
390: }
391: }
392:
393: /*
394: * Open Routine.
395: *
396: * Low nibble of minor device is card identifier 0 to 3.
397: * High nibble of minor device is code identifier 0 to 3.
398: */
399: void
400: tnopen( dev, mode )
401: dev_t dev;
402: {
403: register struct tnet_s * tp;
404: int card = (dev & 0x0F);
405: int code = (dev & 0xF0) >> 4;
406:
407: /*
408: * Validate minor device and card existence.
409: */
410: if ( (card > 3) || (code > 3) || (tnet[card].tnport == 0)) {
411: u.u_error = ENXIO;
412: return;
413: }
414:
415: /*
416: * Code identifiers 1 to 3 are only valid if a prefix code is known.
417: */
418: if ( (code > 0) && (TNPREFIX[code] == 0) ) {
419: u.u_error = ENXIO;
420: return;
421: }
422:
423: /*
424: * Access network information.
425: */
426: tp = &tnet[card];
427:
428: /*
429: * Increment reference count (# opens).
430: */
431: tp->refc[code]++;
432: }
433:
434: /*
435: * Close Routine.
436: */
437: void
438: tnclose( dev )
439: dev_t dev;
440: {
441: register struct tnet_s * tp =tp = &tnet[ dev & 3];
442: register struct tnbuf_s * np;
443: int code = (dev & 0x30) >> 4;
444: int s;
445:
446: /*
447: * Decrement reference count.
448: */
449: if ( --tp->refc[code] != 0 )
450: return;
451:
452: /*
453: * Last close.
454: * Release all queued packets.
455: */
456: while ( np = tp->RxBusy[code] ) {
457: s = sphi( );
458: tp->RxBusy[code] = np->tn_next;
459: tn_rxena( tp, np );
460: spl( s );
461: }
462: }
463:
464: /*
465: * Watchdog Timing Routine
466: *
467: * If transmit has been enabled for 1-2 seconds:
468: * Abort transmission of packet, forcing interrupt.
469: */
470: void
471: tncycle( )
472: {
473: register struct tnet_s * tp;
474: register int code;
475: int s;
476:
477: /*
478: * Scan all network cards.
479: */
480: for ( tp = &tnet[0]; tp <= &tnet[3]; tp++ ) {
481:
482: if ( ! tp->tnport )
483: continue;
484:
485: /*
486: * Disable interrupts.
487: */
488: s = sphi();
489:
490: /*
491: * Enable broadcasts after 5 seconds without reconfiguration.
492: */
493: if ( (tp->recon > 0) && ((lbolt - tp->rbolt) > (5*HZ)) ) {
494: /*
495: * LAN was previously down.
496: */
497: if ( tp->bad[0] & 1 ) {
498: faddr_t fp = tp->statseg->s_faddr;
499: aflong( fp+TnSTATMOD*4, 1 );
500: tp->mod[0] |= 1;
501: tp->pri = 1;
502: }
503: tp->bad[0] &= ~1;
504: tp->recon = 0;
505: }
506:
507: /*
508: * Discard bad packet on transmit watchdog timeout.
509: */
510: if ( (tp->tntime > 0) && (--(tp->tntime) == 0) )
511: outb( NCR, NC_TxDIS );
512:
513: /*
514: * Enable interrupts.
515: */
516: spl( s );
517:
518: /*
519: * LAN/DEVICE UP/DOWN event has occurred.
520: */
521: if ( tp->pri == 1 ) {
522:
523: tp->pri = 2;
524:
525: for ( code = 0; code < 4; code++ )
526: if ( tp->RxPoll[code].e_procp )
527: pollwake( &tp->RxPoll[code] );
528: }
529: }
530: }
531:
532: static
533: tnioctl( dev, com, arg )
534: dev_t dev;
535: int com;
536: register tnattr_t * arg;
537: {
538: register struct tnet_s * tp = &tnet[dev & 3];
539: faddr_t fp;
540: int nid;
541: long t;
542: tnattr_t local; /* to avoid fucopy() problems */
543:
544: switch ( com ) {
545:
546: case TNGETA:
547: case TNGETAF:
548: /*
549: * Access node statistics.
550: */
551: nid = getubd( &arg->host[5] );
552: fp = tp->statseg->s_faddr + nid * (NTNST*4);
553:
554: /*
555: * Disable interrupts to avoid race condition with tnintr().
556: */
557: sphi();
558:
559: /*
560: * Copy node status.
561: */
562: if ( tp->bad[nid/8] & bitm[nid%8] )
563: putubd( &arg->bad, 1 );
564: else
565: putubd( &arg->bad, 0 );
566:
567: /*
568: * Copy network reconfigurations to user space.
569: * NOTE: This is not a node statistic, but a network stat.
570: */
571: kucopy( &tp->recons, &arg->recons, sizeof(tp->recons) );
572:
573: /*
574: * Copy node statistics to user space.
575: */
576: fkcopy( fp, &local.stats[0], sizeof(local.stats) );
577: kucopy( &local.stats[0], &arg->stats[0], sizeof(arg->stats) );
578:
579: /*
580: * Copy true elapsed time of statistics collection.
581: */
582: fkcopy( fp+TnELAPSED*4, &t, sizeof(t) );
583: t = lbolt - t;
584: kucopy( &t, &arg->stats[TnELAPSED], sizeof(arg->stats[0]) );
585:
586: /*
587: * Clear node statistics.
588: * NOTE: Elapsed time statistic is time of last clear.
589: */
590: if ( com == TNGETAF ) {
591: fclear( fp, NTNST * 4 );
592: kfcopy( &lbolt, fp+TnELAPSED*4, sizeof(lbolt) );
593: if ( nid == 0 )
594: tp->recons = 0;
595: }
596:
597: /*
598: * Enable interrupts.
599: */
600: splo();
601:
602: return( 0 );
603:
604: default:
605: u.u_error = EINVAL;
606: }
607: }
608:
609: /*
610: * Polling Routine.
611: *
612: * Note: Double-looks are performed to prevent critical race with
613: * interrupt handlers, without having to disable interrupts.
614: */
615: static
616: tnpoll( dev, ev, msec )
617: dev_t dev;
618: int ev;
619: int msec;
620: {
621: register struct tnet_s * tp = &tnet[dev & 3];
622: int code = (dev & 0x30) >> 4;
623: int rev = 0;
624:
625: /*
626: * Fast check for priority, input, and output polls.
627: * Priority poll checks for LAN UP/DOWN transition.
628: * Input poll checks for a full receive buffer.
629: * Output poll checks for an empty transmit buffer, or LAN down.
630: */
631: if ( (ev & POLLPRI) && (tp->pri != 0) )
632: rev |= POLLPRI;
633: if ( (ev & POLLIN) && (tp->RxBusy[code] != NULL) )
634: rev |= POLLIN;
635: if ( (ev & POLLOUT) && ((tp->TxIdle != 0) || (tp->bad[0] & 1)) )
636: rev |= POLLOUT;
637:
638: /*
639: * Fast check found an event, or this is a non-blocking poll.
640: */
641: if ( (rev != 0) || (msec == 0) )
642: return( rev );
643:
644: /*
645: * Blocking Input poll.
646: */
647: if ( ev & POLLIN ) {
648:
649: pollopen( &tp->RxPoll[code] );
650:
651: /*
652: * Second look to avoid interrupt race.
653: */
654: if ( tp->RxBusy[code] )
655: return( POLLIN );
656: }
657:
658: /*
659: * Blocking Output poll.
660: */
661: if ( ev & POLLOUT ) {
662:
663: pollopen( &tp->TxPoll );
664:
665: /*
666: * Second look to avoid interrupt race.
667: * NOTE: When the LAN is down broadcasts [nid 0] are disabled.
668: */
669: if ( (tp->TxIdle != 0) || (tp->bad[0] & 1) )
670: return( POLLOUT );
671: }
672:
673: return( rev );
674: }
675:
676: /*
677: * Interrupt Entry Point - Card 0.
678: */
679: void
680: tn0intr()
681: {
682: tnintr( &tnet[0] );
683: }
684:
685: /*
686: * Interrupt Entry Point - Card 1.
687: */
688: void
689: tn1intr()
690: {
691: tnintr( &tnet[1] );
692: }
693:
694: /*
695: * Interrupt Entry Point - Card 2.
696: */
697: void
698: tn2intr()
699: {
700: tnintr( &tnet[2] );
701: }
702:
703: /*
704: * Interrupt Entry Point - Card 3.
705: */
706: void
707: tn3intr()
708: {
709: tnintr( &tnet[3] );
710: }
711:
712: /*
713: * Interrupt Handler.
714: *
715: * Process transmit/receive interrupts.
716: */
717: void
718: tnintr( tp )
719: register struct tnet_s * tp;
720: {
721: register struct tnbuf_s * np;
722: register int csr;
723: int nid;
724: int n;
725: int bit;
726:
727: /*
728: * Read interrupt status.
729: * Disable interrupts to ensure edge occurs later.
730: */
731: csr = inb( NSR );
732: tp->tnmask = NI_RECON;
733: outb( NIR, 0 );
734:
735: /*
736: * Reconfigurations with a period of 840 msec [600-1100]
737: * increment tp->recon. Other periods clear tp->recon.
738: * After 5 reconfigurations at 840 msecs, the network is down.
739: * After 1 reconfiguration at another interval, the network is up.
740: * Network also comes up in tncycle() 5 seconds after last reconfig.
741: */
742: if ( csr & NS_RECON ) {
743:
744: outb( NCR, NC_RECON );
745: nid = (unsigned) (lbolt - tp->rbolt) * (1000/HZ);
746: tp->rbolt = lbolt;
747: tp->recons++;
748:
749: /*
750: * Not a chained reconfiguration.
751: * Assume the network is up.
752: * NOTE: Expect 840 msecs, but allow interrupt latency slip.
753: */
754: if ( (nid < 700) || (nid > 1000) ) {
755: if ( tp->bad[0] & 1 ) {
756: tp->mod[0] |= 1;
757: tp->bad[0] &= ~1;
758: tp->pri = 1;
759: }
760: tp->recon = 0;
761: }
762:
763: /*
764: * Chained reconfiguration - threshold exceeded.
765: */
766: else if ( (++(tp->recon) == 5) && ((tp->bad[0] & 1) == 0) ) {
767: faddr_t fp = tp->statseg->s_faddr;
768: aflong( fp+TnSTATMOD*4, 1 );
769: memset( tp->bad, -1, sizeof(tp->bad) );
770: tp->mod[0] |= 1;
771: tp->pri = 1;
772: }
773: }
774:
775: /*
776: * Service Power on Resets.
777: */
778: if ( csr & NS_POR ) {
779:
780: csr &= ~(NS_RxRDY|NS_TxRDY); /* Ignore receive/transmit */
781: outb( NCR, NC_DFC ); /* Define 2K buf config */
782: outb( NCR, NC_POR ); /* Clear POR flag */
783:
784: /*
785: * Enable receiver
786: */
787: if ( np = tp->RxIdle )
788: outb( NCR, np->tn_ena );
789:
790: /*
791: * Enable transmitter
792: */
793: if ( np = tp->TxBusy )
794: outb( NCR, np->tn_ena );
795: }
796:
797: /*
798: * Service transmit interupts if transmit is pending.
799: */
800: if ( np = tp->TxBusy ) {
801:
802: tp->tnmask |= NI_Tx;
803:
804: /*
805: * Check for transmission completed.
806: */
807: if ( csr & NS_TxRDY ) {
808:
809: /*
810: * Destination Node Id is in 2nd byte of packet.
811: */
812: np->tn_off = np->tn_base + 1;
813: nid = tngetc( np );
814:
815: /*
816: * Get length of short/long packets.
817: */
818: n = 256 - tngetc(np);
819: if ( n == 256 )
820: n = 512 - tngetc(np);
821:
822: /*
823: * Transmitted packet was acknowledged.
824: */
825: if ( csr & NS_TxACK ) {
826: /*
827: * Adjust global and node statistics.
828: */
829: faddr_t fp = tp->statseg->s_faddr;
830: aflong( fp+TnTxPACKS*4, 1 );
831: aflong( fp+TnTxBYTES*4, n );
832: fp += nid * (NTNST * 4);
833: aflong( fp+TnTxPACKS*4, 1 );
834: aflong( fp+TnTxBYTES*4, n );
835: }
836:
837: /*
838: * Transmitted packet was discarded.
839: * NOTE: Do not flag broadcast [nid 0] as bad.
840: */
841: else if ( nid != 0 ) {
842: /*
843: * Adjust global and node statistics.
844: */
845: faddr_t fp = tp->statseg->s_faddr;
846: aflong( fp+TnDISCARD*4, 1 );
847: fp += nid * (NTNST * 4);
848: aflong( fp+TnDISCARD*4, 1 );
849: aflong( fp+TnSTATMOD*4, 1 );
850:
851: /*
852: * Flag node as being bad.
853: */
854: bit = bitm[ nid % 8 ];
855: tp->bad[ nid / 8 ] |= bit;
856: tp->mod[ nid / 8 ] |= bit;
857: tp->pri = 1;
858: }
859:
860: /*
861: * Move packet buffer to idle transmit queue.
862: */
863: tp->TxBusy = np->tn_next;
864: np->tn_next = tp->TxIdle;
865: tp->TxIdle = np;
866:
867: /*
868: * Check for another packet to transmit.
869: */
870: if ( np = tp->TxBusy ) {
871:
872: /*
873: * Enable transmitter, start watchdog timer.
874: */
875: outb( NCR, np->tn_ena );
876: tp->tntime = TNTIME;
877: }
878:
879: /*
880: * Disable Transmit Interrupt, clear watchdog timer.
881: */
882: else {
883: tp->tnmask &= ~NI_Tx;
884: tp->tntime = 0;
885: }
886:
887: /*
888: * Wake processes waiting to transmit.
889: */
890: if ( tp->TxReq ) {
891: tp->TxReq = 0;
892: defer( wakeup, &tp->TxReq );
893: }
894:
895: if ( tp->TxPoll.e_procp )
896: defer( pollwake, &tp->TxPoll );
897: }
898: }
899:
900: /*
901: * Check for receive request.
902: */
903: if ( np = tp->RxIdle ) {
904:
905: tp->tnmask |= NI_Rx;
906:
907: /*
908: * Check for packet received.
909: */
910: if ( csr & NS_RxRDY ) {
911:
912: /*
913: * Remove first packet from receive ready queue.
914: * Re-enable receiver or disable receive interrupts.
915: */
916: if ( tp->RxIdle = np->tn_next ) {
917: outb( NCR, np->tn_next->tn_ena );
918: np->tn_next = 0;
919: }
920: else
921: tp->tnmask &= ~NI_Rx;
922:
923: /*
924: * Source Node Id is in 1st byte of packet.
925: */
926: np->tn_off = np->tn_base;
927: nid = tngetc( np );
928:
929: /*
930: * Try to establish our Node Id if not already set.
931: * Destination Node Id (our station)
932: * is in 2nd byte of the received packet.
933: * NOTE: Always read node id byte.
934: * This ensures offset bytes can be read.
935: */
936: if ( (n = tngetc(np)) && (tp->tnaddr[0] == 0) )
937: tp->tnaddr[0] = n;
938:
939: /*
940: * Get offset to first data byte in short/long packet.
941: * Short packet offset is in 3rd byte of packet.
942: * Long packet offset is in 4th byte of packet.
943: */
944: if ( n = tngetc(np) )
945: np->tn_off = np->tn_base + n;
946: else
947: np->tn_off = np->tn_base + tngetc(np);
948:
949: /*
950: * LAN has come up.
951: * Clear bad flag for the broadcast node.
952: */
953: if ( tp->bad[0] & 1 ) {
954: tp->bad[ 0 ] &= ~1;
955: tp->mod[ 0 ] |= 1;
956: tp->pri = 1;
957: }
958:
959: /*
960: * Node has come up.
961: * Clear bad flag for the Source Node.
962: */
963: bit = bitm[ nid % 8 ];
964: if ( tp->bad[ nid / 8 ] & bit ) {
965: faddr_t fp = tp->statseg->s_faddr;
966: aflong( fp+TnSTATMOD*4, 1 );
967: fp += nid * (NTNST * 4);
968: aflong( fp+TnSTATMOD*4, 1 );
969: tp->bad[ nid / 8 ] &= ~bit;
970: tp->mod[ nid / 8 ] |= bit;
971: tp->pri = 1;
972: }
973:
974: /*
975: * Get first data byte from packet.
976: */
977: bit = tngetc( np );
978:
979: /*
980: * Determine prefix code associated with packet.
981: */
982: for ( n = 3; n > 0; n-- ) {
983: if ( TNPREFIX[n] == bit )
984: break;
985: }
986:
987: /*
988: * Interface is open.
989: */
990: if ( tp->refc[n] ) {
991:
992: /*
993: * Append received packet to received queue.
994: * NOTE: At most 2 packets in any queue.
995: */
996: if ( tp->RxBusy[n] )
997: tp->RxBusy[n]->tn_next = np;
998: else
999: tp->RxBusy[n] = np;
1000:
1001: /*
1002: * Wake processes waiting to read.
1003: */
1004: if ( tp->RxReq[n] ) {
1005: tp->RxReq[n] = 0;
1006: defer( wakeup, &tp->RxReq[n] );
1007: }
1008:
1009: if ( tp->RxPoll[n].e_procp )
1010: defer( pollwake, &tp->RxPoll[n] );
1011: }
1012:
1013: /*
1014: * Interface is closed.
1015: * Return packet to end of receive idle queue.
1016: */
1017: else
1018: tn_rxena( tp, np );
1019: }
1020: }
1021:
1022: /*
1023: * Restore interrupt mask.
1024: */
1025: outb( NIR, tp->tnmask );
1026: }
1027:
1028: /*
1029: * Read Routine.
1030: *
1031: * Wait for a packet to be received.
1032: * Transform packet header and copy packet body.
1033: * Place packet buffer on receive idle queue.
1034: * If receiver was inhibited, enable receiver.
1035: */
1036:
1037:
1038: tnread ( dev, iop )
1039:
1040: dev_t dev;
1041: register IO * iop;
1042:
1043: {
1044: register struct tnet_s * tp = &tnet[ dev & 3 ];
1045: register struct tnbuf_s * np;
1046: int code = (dev & 0x30) >> 4;
1047: unsigned len;
1048: unsigned cnt;
1049: unsigned srcid;
1050: int s;
1051:
1052: /*
1053: * Driver information requested.
1054: */
1055: if ( iop->io_ioc <= 2 + sizeof(tp->bad) + sizeof(tp->mod) ) {
1056:
1057: /*
1058: * Supply null byte, then our node id.
1059: */
1060: ioputc( 0, iop );
1061: ioputc( tp->tnaddr[0], iop );
1062:
1063: /*
1064: * Bad and modified node bit masks requested.
1065: * Disable interrupts during transfer to prevent
1066: * critical race with tnintr().
1067: */
1068: if ( iop->io_ioc == sizeof(tp->bad) + sizeof(tp->mod) ) {
1069: sphi();
1070: iowrite( iop, tp->bad, sizeof(tp->bad) );
1071: iowrite( iop, tp->mod, sizeof(tp->mod) );
1072: kclear( tp->mod, sizeof(tp->mod) );
1073: tp->pri = 0;
1074: splo();
1075: }
1076:
1077: /*
1078: * Bad node bit mask requested.
1079: */
1080: else if ( iop->io_ioc == sizeof(tp->bad) )
1081: iowrite( iop, tp->bad, sizeof(tp->bad) );
1082:
1083: return;
1084: }
1085:
1086: /*
1087: * Wait for packet reception.
1088: */
1089: for ( ; ; ) {
1090:
1091: s = sphi( );
1092:
1093: /*
1094: * Check for received packet.
1095: */
1096: if ( np = tp->RxBusy[code] ) {
1097: tp->RxBusy[code] = np->tn_next;
1098: np->tn_next = 0;
1099: spl( s );
1100: break;
1101: }
1102:
1103: /*
1104: * Non-blocking reads.
1105: */
1106: if ( iop->io_flag & IONDLY ) {
1107: u.u_error = EAGAIN;
1108: spl( s );
1109: return;
1110: }
1111:
1112: tp->RxReq[code] = 1;
1113:
1114: sleep( &tp->RxReq[code], CVTTIN, IVTTIN, SVTTIN );
1115: spl( s );
1116:
1117: /*
1118: * Check for pending signal.
1119: */
1120: if ( nondsig() ) {
1121: u.u_error = EINTR;
1122: return;
1123: }
1124: }
1125:
1126: /*
1127: * Copy source and destination node ids
1128: */
1129: np->tn_off = np->tn_base;
1130: ioputc( srcid = tngetc(np), iop );
1131: ioputc( tngetc(np), iop );
1132:
1133: /*
1134: * Check for short packet.
1135: */
1136: if ( cnt = tngetc(np) ) {
1137:
1138: np->tn_off = np->tn_base + cnt;
1139: len = 256 - cnt;
1140: }
1141:
1142: /*
1143: * Check for long packet.
1144: */
1145: else if ( cnt = tngetc(np) ) {
1146:
1147: np->tn_off = np->tn_base + cnt;
1148: len = 512 - cnt;
1149: }
1150:
1151: /*
1152: * Check for non-empty packet.
1153: */
1154: if ( cnt != 0 ) {
1155:
1156: /*
1157: * Truncate packet if necessary.
1158: */
1159: if ( iop->io_ioc < len )
1160: len = iop->io_ioc;
1161:
1162: /*
1163: * Copy packet body.
1164: */
1165: tucopy( np, iop->io_base, len );
1166: iop->io_ioc -= len;
1167: iop->io_base += len;
1168: }
1169:
1170: /*
1171: * Adjust received data statistics.
1172: */
1173: if ( tp->statseg != NULL ) {
1174: faddr_t fp = tp->statseg->s_faddr;
1175: aflong( fp+TnRxPACKS*4, 1 );
1176: aflong( fp+TnRxBYTES*4, len );
1177: fp += srcid * (NTNST * 4);
1178: aflong( fp+TnRxPACKS*4, 1 );
1179: aflong( fp+TnRxBYTES*4, len );
1180: }
1181:
1182: /*
1183: * Enable packet reception with buffer.
1184: */
1185: tn_rxena( tp, np );
1186: }
1187:
1188:
1189: /*
1190: * Write Routine.
1191: *
1192: * Wait for a empty transmit buffer to become available.
1193: * Format the buffer and place on transmit queue.
1194: * If transmit queue was empty, start transmitter.
1195: */
1196:
1197: tnwrite ( dev, iop )
1198:
1199: dev_t dev;
1200: register IO * iop;
1201:
1202: {
1203: register struct tnet_s * tp = &tnet[ dev & 3 ];
1204: register struct tnbuf_s * np;
1205: unsigned len, cnt;
1206: int dstid;
1207: int s;
1208:
1209: /*
1210: * Validate size of write.
1211: */
1212: if ( ( iop->io_ioc < 3 ) || ( iop->io_ioc > 510 ) ) {
1213: u.u_error = EINVAL;
1214: return;
1215: }
1216:
1217: /*
1218: * Destination Node Id is 2nd byte of write.
1219: */
1220: iogetc( iop );
1221: dstid = iogetc( iop );
1222:
1223: /*
1224: * Wait for empty transmit buffer.
1225: */
1226: for ( ; ; ) {
1227:
1228: /*
1229: * If Destination Node appears bad, set errno to EDATTN.
1230: */
1231: if ( tp->bad[ dstid / 8 ] & (1 << (dstid % 8)) ) {
1232: u.u_error = EDATTN;
1233: return;
1234: }
1235:
1236: s = sphi( );
1237:
1238: /*
1239: * Check for empty transmit buffer.
1240: */
1241: if ( np = tp->TxIdle ) {
1242:
1243: tp->TxIdle = np->tn_next;
1244: np->tn_next = 0;
1245: spl( s );
1246: break;
1247: }
1248:
1249: /*
1250: * Non-blocking writes.
1251: */
1252: if ( iop->io_flag & IONDLY ) {
1253: /*
1254: * Adjust delayed write stats.
1255: */
1256: faddr_t fp = tp->statseg->s_faddr;
1257: aflong( fp+TnWRTDLYS*4, 1 );
1258: fp += dstid * (NTNST * 4);
1259: aflong( fp+TnWRTDLYS*4, 1 );
1260:
1261: u.u_error = EAGAIN;
1262: spl( s );
1263: return;
1264: }
1265:
1266: tp->TxReq = 1;
1267: sleep( &tp->TxReq, CVTTOUT, IVTTOUT, SVTTOUT );
1268: spl( s );
1269:
1270: /*
1271: * Check for pending signal.
1272: */
1273: if ( nondsig() ) {
1274: u.u_error = EINTR;
1275: return;
1276: }
1277: }
1278:
1279: /*
1280: * Copy source and destination node ids
1281: * NOTE: Hardware inserts source node id automatically.
1282: */
1283: np->tn_off = np->tn_base;
1284: tnputc( np, 0 );
1285: tnputc( np, dstid );
1286:
1287: len = iop->io_ioc;
1288:
1289: /*
1290: * Check for long packet.
1291: */
1292: if ( len > 253 ) {
1293: tnputc( np, 0 );
1294: tnputc( np, cnt = 512 - len );
1295: np->tn_off = np->tn_base + cnt;
1296: }
1297:
1298: /*
1299: * Short packet.
1300: */
1301: else {
1302: tnputc( np, cnt = 256 - len );
1303: np->tn_off = np->tn_base + cnt;
1304: }
1305:
1306: /*
1307: * Copy packet body.
1308: */
1309: utcopy( iop->io_base, np, len );
1310: iop->io_base += len;
1311: iop->io_ioc -= len;
1312:
1313: /*
1314: * Record length in header structure.
1315: */
1316: np->tn_xlen = iop->io_ioc;
1317:
1318: sphi();
1319:
1320: /*
1321: * Put packet on transmit ready queue, prime transmitter if necessary.
1322: */
1323: if ( ! tp->TxBusy ) {
1324: tp->TxBusy = np;
1325: outb( NCR, np->tn_ena ); /* enable transmitter */
1326: outb( NIR, tp->tnmask |= NI_Tx); /* enable xmit intr */
1327: tp->tntime = TNTIME; /* restart watchdog */
1328: }
1329: else
1330: tp->TxBusy->tn_next = np;
1331:
1332: spl(s);
1333: }
1334:
1335: /*
1336: * Enable packet reception with buffer.
1337: */
1338: tn_rxena( tp, np )
1339: register struct tnet_s * tp;
1340: register struct tnbuf_s * np;
1341: {
1342: int s;
1343:
1344: s = sphi( );
1345:
1346: /*
1347: * Put packet on receive ready queue, prime receiver if necessary.
1348: */
1349: if ( tp->RxIdle == NULL ) {
1350: tp->RxIdle = np;
1351: outb( NCR, np->tn_ena );
1352: outb( NIR, tp->tnmask |= NI_Rx );
1353: }
1354: else
1355: tp->RxIdle->tn_next = np;
1356:
1357: np->tn_next = 0;
1358: spl( s );
1359: }
1360:
1361: /*
1362: * Adjust far long.
1363: */
1364: static
1365: aflong( fp, i )
1366: faddr_t fp;
1367: int i;
1368: {
1369: long lw;
1370:
1371: fkcopy( fp, &lw, sizeof(lw) );
1372: lw += i;
1373: kfcopy( &lw, fp, sizeof(lw) );
1374: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.