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