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