1*41705Ssklower /* 2*41705Ssklower * Copyright (c) University of British Columbia, 1984 3*41705Ssklower * Copyright (c) 1990 The Regents of the University of California. 4*41705Ssklower * All rights reserved. 5*41705Ssklower * 6*41705Ssklower * This code is derived from software contributed to Berkeley by 7*41705Ssklower * the Laboratory for Computation Vision and the Computer Science Department 8*41705Ssklower * of the University of British Columbia. 9*41705Ssklower * 10*41705Ssklower * %sccs.include.redist.c% 11*41705Ssklower * 12*41705Ssklower * @(#)hd_timer.c 7.2 (Berkeley) 05/11/90 13*41705Ssklower */ 1441588Ssklower 1541588Ssklower #include "../h/param.h" 1641588Ssklower #include "../h/systm.h" 1741588Ssklower #include "../h/mbuf.h" 1841588Ssklower #include "../h/domain.h" 1941588Ssklower #include "../h/socket.h" 2041588Ssklower #include "../h/protosw.h" 2141588Ssklower #include "../h/errno.h" 2241588Ssklower #include "../h/time.h" 2341588Ssklower #include "../h/kernel.h" 2441588Ssklower 2541588Ssklower #include "../net/if.h" 2641588Ssklower 2741588Ssklower #include "../netccitt/hdlc.h" 2841588Ssklower #include "../netccitt/hd_var.h" 2941588Ssklower #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 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. */ 8641588Ssklower (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_xcp); 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