xref: /csrg-svn/sys/netccitt/hd_timer.c (revision 63216)
141705Ssklower /*
241705Ssklower  * Copyright (c) University of British Columbia, 1984
3*63216Sbostic  * Copyright (c) 1990, 1993
4*63216Sbostic  *	The Regents of the University of California.  All rights reserved.
541705Ssklower  *
641705Ssklower  * This code is derived from software contributed to Berkeley by
741705Ssklower  * the Laboratory for Computation Vision and the Computer Science Department
841705Ssklower  * of the University of British Columbia.
941705Ssklower  *
1041705Ssklower  * %sccs.include.redist.c%
1141705Ssklower  *
12*63216Sbostic  *	@(#)hd_timer.c	8.1 (Berkeley) 06/10/93
1341705Ssklower  */
1441588Ssklower 
1556530Sbostic #include <sys/param.h>
1656530Sbostic #include <sys/systm.h>
1756530Sbostic #include <sys/mbuf.h>
1856530Sbostic #include <sys/domain.h>
1956530Sbostic #include <sys/socket.h>
2056530Sbostic #include <sys/protosw.h>
2156530Sbostic #include <sys/errno.h>
2256530Sbostic #include <sys/time.h>
2356530Sbostic #include <sys/kernel.h>
2441588Ssklower 
2556530Sbostic #include <net/if.h>
2641588Ssklower 
2756530Sbostic #include <netccitt/hdlc.h>
2856530Sbostic #include <netccitt/hd_var.h>
2956530Sbostic #include <netccitt/x25.h>
3041588Ssklower 
3141588Ssklower /*
3241588Ssklower  * these can be patched with adb if the
3341588Ssklower  * default values are inappropriate
3441588Ssklower  */
3541588Ssklower 
3641588Ssklower int	hd_t1 = T1;
3741588Ssklower int	hd_t3 = T3;
3841588Ssklower int	hd_n2 = N2;
3941588Ssklower 
4041588Ssklower /*
4141588Ssklower  *  HDLC TIMER
4241588Ssklower  *
4341588Ssklower  *  This routine is called every 500ms by the kernel. Decrement timer by this
4441588Ssklower  *  amount - if expired then process the event.
4541588Ssklower  */
4641588Ssklower 
hd_timer()4741588Ssklower hd_timer ()
4841588Ssklower {
4941588Ssklower 	register struct hdcb *hdp;
5041588Ssklower 	register int s = splimp ();
5141588Ssklower 
5241588Ssklower 	for (hdp = hdcbhead; hdp; hdp = hdp->hd_next) {
5341588Ssklower 		if (hdp->hd_rrtimer && (--hdp->hd_rrtimer == 0)) {
5441588Ssklower 			if (hdp->hd_lasttxnr != hdp->hd_vr)
5541588Ssklower 				hd_writeinternal (hdp, RR, POLLOFF);
5641588Ssklower 		}
5741588Ssklower 
5841588Ssklower 		if (!(hdp->hd_timer && --hdp->hd_timer == 0))
5941588Ssklower 			continue;
6041588Ssklower 
6141588Ssklower 		switch (hdp->hd_state) {
6241588Ssklower 		case INIT:
6341588Ssklower 		case DISC_SENT:
6441588Ssklower 			hd_writeinternal (hdp, DISC, POLLON);
6541588Ssklower 			break;
6641588Ssklower 
6741588Ssklower 		case ABM:
6841588Ssklower 			if (hdp->hd_lastrxnr != hdp->hd_vs) {	/* XXX */
6941588Ssklower 				hdp->hd_timeouts++;
7041588Ssklower 				hd_resend_iframe (hdp);
7141588Ssklower 			}
7241588Ssklower 			break;
7341588Ssklower 
7441588Ssklower 		case WAIT_SABM:
7541588Ssklower 			hd_writeinternal (hdp, FRMR, POLLOFF);
7641588Ssklower 			if (++hdp->hd_retxcnt == hd_n2) {
7741588Ssklower 				hdp->hd_retxcnt = 0;
7841588Ssklower 				hd_writeinternal (hdp, SABM, POLLOFF);
7941588Ssklower 				hdp->hd_state = WAIT_UA;
8041588Ssklower 			}
8141588Ssklower 			break;
8241588Ssklower 
8341588Ssklower 		case DM_SENT:
8441588Ssklower 			if (++hdp->hd_retxcnt == hd_n2) {
8541588Ssklower 				/* Notify the packet level. */
8649927Ssklower 				(void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
8741588Ssklower 				hdp->hd_retxcnt = 0;
8841588Ssklower 				hdp->hd_state = SABM_SENT;
8941588Ssklower 				hd_writeinternal (hdp, SABM, POLLOFF);
9041588Ssklower 			} else
9141588Ssklower 				hd_writeinternal (hdp, DM, POLLOFF);
9241588Ssklower 			break;
9341588Ssklower 
9441588Ssklower 		case WAIT_UA:
9541588Ssklower 			if (++hdp->hd_retxcnt == hd_n2) {
9641588Ssklower 				hdp->hd_retxcnt = 0;
9741588Ssklower 				hd_writeinternal (hdp, DM, POLLOFF);
9841588Ssklower 				hdp->hd_state = DM_SENT;
9941588Ssklower 			} else
10041588Ssklower 				hd_writeinternal (hdp, SABM, POLLOFF);
10141588Ssklower 			break;
10241588Ssklower 
10341588Ssklower 		case SABM_SENT:
10441588Ssklower 			/* Do this indefinitely. */
10541588Ssklower 			hd_writeinternal (hdp, SABM, POLLON);
10641588Ssklower 			break;
10741588Ssklower 
10841588Ssklower 		case DISCONNECTED:
10941588Ssklower 			/*
11041588Ssklower 			 * Poll the interface driver flags waiting
11141588Ssklower 			 * for the IFF_UP bit to come on.
11241588Ssklower 			 */
11341588Ssklower 			if (hdp->hd_ifp->if_flags & IFF_UP)
11441588Ssklower 				hdp->hd_state = INIT;
11541588Ssklower 
11641588Ssklower 		}
11741588Ssklower 		SET_TIMER (hdp);
11841588Ssklower 	}
11941588Ssklower 
12041588Ssklower 	splx (s);
12141588Ssklower }
122