xref: /original-bsd/sys/netccitt/hd_timer.c (revision 23c6a147)
1 /* Copyright (c) University of British Columbia, 1984 */
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/mbuf.h"
6 #include "../h/domain.h"
7 #include "../h/socket.h"
8 #include "../h/protosw.h"
9 #include "../h/errno.h"
10 #include "../h/time.h"
11 #include "../h/kernel.h"
12 
13 #include "../net/if.h"
14 
15 #include "../netccitt/hdlc.h"
16 #include "../netccitt/hd_var.h"
17 #include "../netccitt/x25.h"
18 
19 /*
20  * these can be patched with adb if the
21  * default values are inappropriate
22  */
23 
24 int	hd_t1 = T1;
25 int	hd_t3 = T3;
26 int	hd_n2 = N2;
27 
28 /*
29  *  HDLC TIMER
30  *
31  *  This routine is called every 500ms by the kernel. Decrement timer by this
32  *  amount - if expired then process the event.
33  */
34 
35 hd_timer ()
36 {
37 	register struct hdcb *hdp;
38 	register int s = splimp ();
39 
40 	for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) {
41 		if (hdp->hd_rrtimer && (--hdp->hd_rrtimer == 0)) {
42 			if (hdp->hd_lasttxnr != hdp->hd_vr)
43 				hd_writeinternal (hdp, RR, POLLOFF);
44 		}
45 
46 		if (!(hdp->hd_timer && --hdp->hd_timer == 0))
47 			continue;
48 
49 		switch (hdp->hd_state) {
50 		case INIT:
51 		case DISC_SENT:
52 			hd_writeinternal (hdp, DISC, POLLON);
53 			break;
54 
55 		case ABM:
56 			if (hdp->hd_lastrxnr != hdp->hd_vs) {	/* XXX */
57 				hdp->hd_timeouts++;
58 				hd_resend_iframe (hdp);
59 			}
60 			break;
61 
62 		case WAIT_SABM:
63 			hd_writeinternal (hdp, FRMR, POLLOFF);
64 			if (++hdp->hd_retxcnt == hd_n2) {
65 				hdp->hd_retxcnt = 0;
66 				hd_writeinternal (hdp, SABM, POLLOFF);
67 				hdp->hd_state = WAIT_UA;
68 			}
69 			break;
70 
71 		case DM_SENT:
72 			if (++hdp->hd_retxcnt == hd_n2) {
73 				/* Notify the packet level. */
74 				(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_xcp);
75 				hdp->hd_retxcnt = 0;
76 				hdp->hd_state = SABM_SENT;
77 				hd_writeinternal (hdp, SABM, POLLOFF);
78 			} else
79 				hd_writeinternal (hdp, DM, POLLOFF);
80 			break;
81 
82 		case WAIT_UA:
83 			if (++hdp->hd_retxcnt == hd_n2) {
84 				hdp->hd_retxcnt = 0;
85 				hd_writeinternal (hdp, DM, POLLOFF);
86 				hdp->hd_state = DM_SENT;
87 			} else
88 				hd_writeinternal (hdp, SABM, POLLOFF);
89 			break;
90 
91 		case SABM_SENT:
92 			/* Do this indefinitely. */
93 			hd_writeinternal (hdp, SABM, POLLON);
94 			break;
95 
96 		case DISCONNECTED:
97 			/*
98 			 * Poll the interface driver flags waiting
99 			 * for the IFF_UP bit to come on.
100 			 */
101 			if (hdp->hd_ifp->if_flags & IFF_UP)
102 				hdp->hd_state = INIT;
103 
104 		}
105 		SET_TIMER (hdp);
106 	}
107 
108 	splx (s);
109 }
110