Commit | Line | Data |
---|---|---|
c462de67 KS |
1 | /* |
2 | * Copyright (C) Dirk Husemann, Computer Science Department IV, | |
3 | * University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992 | |
e7a3707f KB |
4 | * Copyright (c) 1992, 1993 |
5 | * The Regents of the University of California. All rights reserved. | |
c462de67 KS |
6 | * |
7 | * This code is derived from software contributed to Berkeley by | |
8 | * Dirk Husemann and the Computer Science Department (IV) of | |
9 | * the University of Erlangen-Nuremberg, Germany. | |
10 | * | |
11 | * %sccs.include.redist.c% | |
12 | * | |
e7a3707f | 13 | * @(#)llc_timer.c 8.1 (Berkeley) %G% |
c462de67 KS |
14 | */ |
15 | ||
16 | #include <sys/param.h> | |
17 | #include <sys/systm.h> | |
18 | #include <sys/mbuf.h> | |
19 | #include <sys/domain.h> | |
20 | #include <sys/socket.h> | |
21 | #include <sys/protosw.h> | |
22 | #include <sys/errno.h> | |
23 | #include <sys/time.h> | |
24 | #include <sys/kernel.h> | |
25 | ||
26 | #include <net/if.h> | |
27 | #include <net/if_dl.h> | |
28 | #include <net/if_llc.h> | |
29 | ||
30 | #include <netccitt/dll.h> | |
31 | #include <netccitt/llc_var.h> | |
32 | ||
33 | ||
34 | /* | |
35 | * Various timer values. They can be adjusted | |
36 | * by patching the binary with adb if necessary. | |
37 | */ | |
38 | /* ISO 8802-2 timers */ | |
39 | int llc_n2 = LLC_N2_VALUE; | |
40 | int llc_ACK_timer = LLC_ACK_TIMER; | |
41 | int llc_P_timer = LLC_P_TIMER; | |
42 | int llc_BUSY_timer = LLC_BUSY_TIMER; | |
43 | int llc_REJ_timer = LLC_REJ_TIMER; | |
44 | /* Implementation specific timers */ | |
45 | int llc_AGE_timer = LLC_AGE_TIMER; | |
46 | int llc_DACTION_timer = LLC_DACTION_TIMER; | |
47 | ||
48 | /* | |
49 | * The timer routine. We are called every 500ms by the kernel. | |
50 | * Handle the various virtual timers. | |
51 | */ | |
52 | ||
53 | void | |
54 | llc_timer() | |
55 | { | |
56 | register struct llc_linkcb *linkp; | |
57 | register struct llc_linkcb *nlinkp; | |
58 | register int timer; | |
59 | register int action; | |
60 | register int s = splimp(); | |
61 | ||
62 | /* | |
63 | * All links are accessible over the doubly linked list llccb_q | |
64 | */ | |
65 | if (!LQEMPTY) { | |
66 | /* | |
67 | * A for-loop is not that great an idea as the linkp | |
68 | * might get deleted if the age timer has expired ... | |
69 | */ | |
70 | linkp = LQFIRST; | |
71 | while (LQVALID(linkp)) { | |
72 | nlinkp = LQNEXT(linkp); | |
73 | /* | |
74 | * Check implementation specific timers first | |
75 | */ | |
76 | /* The delayed action/acknowledge idle timer */ | |
77 | switch (LLC_TIMERXPIRED(linkp, DACTION)) { | |
78 | case LLC_TIMER_RUNNING: | |
79 | LLC_AGETIMER(linkp, DACTION); | |
80 | break; | |
81 | case LLC_TIMER_EXPIRED: { | |
82 | register int cmdrsp; | |
83 | register int pollfinal; | |
84 | ||
85 | switch (LLC_GETFLAG(linkp, DACTION)) { | |
86 | case LLC_DACKCMD: | |
87 | cmdrsp = LLC_CMD, pollfinal = 0; | |
88 | break; | |
89 | case LLC_DACKCMDPOLL: | |
90 | cmdrsp = LLC_CMD, pollfinal = 1; | |
91 | break; | |
92 | case LLC_DACKRSP: | |
93 | cmdrsp = LLC_RSP, pollfinal = 0; | |
94 | break; | |
95 | case LLC_DACKRSPFINAL: | |
96 | cmdrsp = LLC_RSP, pollfinal = 1; | |
97 | break; | |
98 | } | |
99 | llc_send(linkp, LLCFT_RR, cmdrsp, pollfinal); | |
100 | LLC_STOPTIMER(linkp, DACTION); | |
101 | break; | |
102 | } | |
103 | } | |
104 | /* The link idle timer */ | |
105 | switch (LLC_TIMERXPIRED(linkp, AGE)) { | |
106 | case LLC_TIMER_RUNNING: | |
107 | LLC_AGETIMER(linkp, AGE); | |
108 | break; | |
109 | case LLC_TIMER_EXPIRED: | |
110 | /* | |
111 | * Only crunch the link when really no | |
112 | * timers are running any more. | |
113 | */ | |
114 | if (llc_anytimersup(linkp) == 0) { | |
115 | llc_dellink(linkp); | |
116 | LLC_STOPTIMER(linkp, AGE); | |
117 | goto gone; | |
118 | } else { | |
119 | LLC_STARTTIMER(linkp, AGE); | |
120 | } | |
121 | break; | |
122 | } | |
123 | /* | |
124 | * Now, check all the ISO 8802-2 timers | |
125 | */ | |
126 | FOR_ALL_LLC_TIMERS(timer) { | |
127 | action = 0; | |
128 | if ((linkp->llcl_timerflags & (1<<timer)) && | |
129 | (linkp->llcl_timers[timer] == 0)) { | |
130 | switch (timer) { | |
131 | case LLC_ACK_SHIFT: | |
132 | action = LLC_ACK_TIMER_EXPIRED; | |
133 | break; | |
134 | case LLC_P_SHIFT: | |
135 | action = LLC_P_TIMER_EXPIRED; | |
136 | break; | |
137 | case LLC_BUSY_SHIFT: | |
138 | action = LLC_BUSY_TIMER_EXPIRED; | |
139 | break; | |
140 | case LLC_REJ_SHIFT: | |
141 | action = LLC_REJ_TIMER_EXPIRED; | |
142 | break; | |
143 | } | |
144 | linkp->llcl_timerflags &= ~(1<<timer); | |
145 | (void)llc_statehandler(linkp, (struct llc *)0, action, 0, 1); | |
146 | } else if (linkp->llcl_timers[timer] > 0) | |
147 | linkp->llcl_timers[timer]--; | |
148 | } | |
149 | ||
150 | gone: linkp = nlinkp; | |
151 | } | |
152 | } | |
153 | splx (s); | |
154 | } |