1 /* 2 * Copyright (c) University of British Columbia, 1984 3 * Copyright (c) 1990 The Regents of the University of California. 4 * 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 7.2 (Berkeley) 05/11/90 13 */ 14 15 #include "../h/param.h" 16 #include "../h/systm.h" 17 #include "../h/mbuf.h" 18 #include "../h/domain.h" 19 #include "../h/socket.h" 20 #include "../h/protosw.h" 21 #include "../h/errno.h" 22 #include "../h/time.h" 23 #include "../h/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_xcp); 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