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