Commit | Line | Data |
---|---|---|
c462de67 KS |
1 | /* |
2 | * Copyright (C) Dirk Husemann, Computer Science Department IV, | |
3 | * University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992 | |
4 | * Copyright (c) 1992 Regents of the University of California. | |
5 | * All rights reserved. | |
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 | * | |
1e4f18be | 13 | * @(#)llc_var.h 7.2 (Berkeley) %G% |
c462de67 KS |
14 | */ |
15 | ||
16 | #ifdef __STDC__ | |
17 | /* | |
18 | * Forward structure declarations for function prototypes [sic]. | |
19 | */ | |
20 | struct llc; | |
21 | #endif | |
22 | ||
23 | #define NPAIDB_LINK 0 | |
24 | ||
25 | struct npaidbentry { | |
26 | union { | |
27 | /* MAC,DLSAP -> CONS */ | |
28 | struct { | |
29 | struct llc_linkcb *NE_link; | |
30 | struct rtentry *NE_rt; | |
31 | } NE; | |
32 | /* SAP info for unconfigured incoming calls */ | |
33 | struct { | |
34 | u_short SI_class; | |
35 | #define LLC_CLASS_I 0x1 | |
36 | #define LLC_CLASS_II 0x3 | |
37 | #define LLC_CLASS_III 0x4 /* Future */ | |
38 | #define LLC_CLASS_IV 0x7 /* Future */ | |
39 | u_short SI_window; | |
40 | u_short SI_trace; | |
41 | u_short SI_xchxid; | |
42 | int (*SI_input) | |
43 | __P((struct mbuf *)); | |
44 | caddr_t (*SI_ctlinput) | |
45 | __P((int, struct sockaddr *, caddr_t)); | |
46 | } SI; | |
47 | } NESIun; | |
48 | }; | |
49 | #define np_link NESIun.NE.NE_link | |
50 | #define np_rt NESIun.NE.NE_rt | |
51 | #define si_class NESIun.SI.SI_class | |
52 | #define si_window NESIun.SI.SI_window | |
53 | #define si_trace NESIun.SI.SI_trace | |
54 | #define si_xchxid NESIun.SI.SI_xchxid | |
55 | #define si_input NESIun.SI.SI_input | |
56 | #define si_ctlinput NESIun.SI.SI_ctlinput | |
57 | ||
58 | #define NPDL_SAPNETMASK 0x7e | |
59 | ||
60 | /* | |
61 | * Definitions for accessing bitfields/bitslices inside | |
62 | * LLC2 headers | |
63 | */ | |
64 | struct bitslice { | |
65 | unsigned int bs_mask; | |
66 | unsigned int bs_shift; | |
67 | }; | |
68 | ||
69 | ||
70 | #define i_z 0 | |
71 | #define i_ns 1 | |
72 | #define i_pf 0 | |
73 | #define i_nr 1 | |
74 | #define s_oz 2 | |
75 | #define s_selector 3 | |
76 | #define s_pf 0 | |
77 | #define s_nr 1 | |
78 | #define u_bb 2 | |
79 | #define u_select_other 3 | |
80 | #define u_pf 4 | |
81 | #define u_select 5 | |
82 | #define f_vs 1 | |
83 | #define f_cr 0 | |
84 | #define f_vr 1 | |
85 | #define f_wxyzv 6 | |
86 | ||
87 | #define LLCGBITS(Arg, Index) (((Arg) & llc_bitslice[(Index)].bs_mask) >> llc_bitslice[(Index)].bs_shift) | |
88 | #define LLCSBITS(Arg, Index, Val) (Arg) |= (((Val) << llc_bitslice[(Index)].bs_shift) & llc_bitslice[(Index)].bs_mask) | |
89 | #define LLCCSBITS(Arg, Index, Val) (Arg) = (((Val) << llc_bitslice[(Index)].bs_shift) & llc_bitslice[(Index)].bs_mask) | |
90 | ||
91 | extern struct bitslice llc_bitslice[]; | |
92 | ||
93 | #define LLC_CMD 0 | |
94 | #define LLC_RSP 1 | |
95 | #define LLC_MAXCMDRSP 2 | |
96 | ||
97 | /* | |
98 | * LLC events --- These events may either be frames received from the | |
99 | * remote LLC DSAP, request from the network layer user, | |
100 | * timer events from llc_timer(), or diagnostic events from | |
101 | * llc_input(). | |
102 | */ | |
103 | ||
104 | /* LLC frame types */ | |
105 | #define LLCFT_INFO 0 * LLC_MAXCMDRSP | |
106 | #define LLCFT_RR 1 * LLC_MAXCMDRSP | |
107 | #define LLCFT_RNR 2 * LLC_MAXCMDRSP | |
108 | #define LLCFT_REJ 3 * LLC_MAXCMDRSP | |
109 | #define LLCFT_DM 4 * LLC_MAXCMDRSP | |
110 | #define LLCFT_SABME 5 * LLC_MAXCMDRSP | |
111 | #define LLCFT_DISC 6 * LLC_MAXCMDRSP | |
112 | #define LLCFT_UA 7 * LLC_MAXCMDRSP | |
113 | #define LLCFT_FRMR 8 * LLC_MAXCMDRSP | |
114 | #define LLCFT_UI 9 * LLC_MAXCMDRSP | |
115 | #define LLCFT_XID 10 * LLC_MAXCMDRSP | |
116 | #define LLCFT_TEST 11 * LLC_MAXCMDRSP | |
117 | ||
118 | /* LLC2 timer events */ | |
119 | #define LLC_ACK_TIMER_EXPIRED 12 * LLC_MAXCMDRSP | |
120 | #define LLC_P_TIMER_EXPIRED 13 * LLC_MAXCMDRSP | |
121 | #define LLC_REJ_TIMER_EXPIRED 14 * LLC_MAXCMDRSP | |
122 | #define LLC_BUSY_TIMER_EXPIRED 15 * LLC_MAXCMDRSP | |
123 | ||
124 | /* LLC2 diagnostic events */ | |
125 | #define LLC_INVALID_NR 16 * LLC_MAXCMDRSP | |
126 | #define LLC_INVALID_NS 17 * LLC_MAXCMDRSP | |
127 | #define LLC_BAD_PDU 18 * LLC_MAXCMDRSP | |
128 | #define LLC_LOCAL_BUSY_DETECTED 19 * LLC_MAXCMDRSP | |
129 | #define LLC_LOCAL_BUSY_CLEARED 20 * LLC_MAXCMDRSP | |
130 | ||
131 | /* Network layer user requests */ | |
132 | /* | |
133 | * NL_CONNECT_REQUEST --- The user has requested that a data link connection | |
134 | * be established with a remote LLC DSAP. | |
135 | */ | |
136 | #define NL_CONNECT_REQUEST 21 * LLC_MAXCMDRSP | |
137 | /* | |
138 | * NL_CONNECT_RESPONSE --- The user has accepted the data link connection. | |
139 | */ | |
140 | #define NL_CONNECT_RESPONSE 22 * LLC_MAXCMDRSP | |
141 | /* | |
142 | * NL_RESET_REQUEST --- The user has requested that the data link with the | |
143 | * remote LLC DSAP be reset. | |
144 | */ | |
145 | #define NL_RESET_REQUEST 23 * LLC_MAXCMDRSP | |
146 | /* | |
147 | * NL_RESET_RESPONSE --- The user has accepted the reset of the data link | |
148 | * connection. | |
149 | */ | |
150 | #define NL_RESET_RESPONSE 24 * LLC_MAXCMDRSP | |
151 | /* | |
152 | * NL_DISCONNECT_REQUEST --- The user has requested that the data link | |
153 | * connection with remote LLC DSAP be terminated. | |
154 | */ | |
155 | #define NL_DISCONNECT_REQUEST 25 * LLC_MAXCMDRSP | |
156 | /* | |
157 | * NL_DATA_REQUEST --- The user has requested that a data unit be sent ot the | |
158 | * remote LLC DSAP. | |
159 | */ | |
160 | #define NL_DATA_REQUEST 26 * LLC_MAXCMDRSP | |
161 | /* | |
162 | * NL_INITIATE_PF_CYCLE --- The local LLC wants to initiate a P/F cycle. | |
163 | */ | |
164 | #define NL_INITIATE_PF_CYCLE 27 * LLC_MAXCMDRSP | |
165 | /* | |
166 | * NL_LOCAL_BUSY_DETECTED --- The local entity has encountered a busy condition | |
167 | */ | |
168 | #define NL_LOCAL_BUSY_DETECTED 28 * LLC_MAXCMDRSP | |
169 | ||
170 | #define LLCFT_NONE 255 | |
171 | ||
172 | /* return message from state handlers */ | |
173 | ||
174 | /* | |
175 | * LLC_CONNECT_INDICATION --- Inform the user that a connection has been | |
176 | * requested by a remote LLC SSAP. | |
177 | */ | |
178 | #define LLC_CONNECT_INDICATION 1 | |
179 | /* | |
180 | * LLC_CONNECT_CONFIRM --- The connection service component indicates that the | |
181 | * remote network entity has accepted the connection. | |
182 | */ | |
183 | #define LLC_CONNECT_CONFIRM 2 | |
184 | /* | |
185 | * LLC_DISCONNECT_INDICATION --- Inform the user that the remote network | |
186 | * entity has intiated disconnection of the data | |
187 | * link connection. | |
188 | */ | |
189 | #define LLC_DISCONNECT_INDICATION 3 | |
190 | /* | |
191 | * LLC_RESET_CONFIRM --- The connection service component indicates that the | |
192 | * remote network entity has accepted the reset. | |
193 | */ | |
194 | #define LLC_RESET_CONFIRM 4 | |
195 | /* | |
196 | * LLC_RESET_INDICATION_REMOTE --- The remote network entity or remote peer | |
197 | * has initiated a reset of the data link | |
198 | * connection. | |
199 | */ | |
200 | #define LLC_RESET_INDICATION_REMOTE 5 | |
201 | /* | |
202 | * LLC_RESET_INDICATION_LOCAL --- The local LLC has determined that the data | |
203 | * link connection is in need of | |
204 | * reinitialization. | |
205 | */ | |
206 | #define LLC_RESET_INDICATION_LOCAL 6 | |
207 | /* | |
208 | * LLC_FRMR_RECEIVED --- The local connection service component has received a | |
209 | * FRMR response PDU. | |
210 | */ | |
211 | #define LLC_FRMR_RECEIVED 7 | |
212 | /* | |
213 | * LLC_FRMR_SENT --- The local connection component has received an ivalid | |
214 | * PDU, and has sent a FRMR response PDU. | |
215 | */ | |
216 | #define LLC_FRMR_SENT 8 | |
217 | /* | |
218 | * LLC_DATA_INDICATION --- The connection service component passes the data | |
219 | * unit from the received I PDU to the user. | |
220 | */ | |
221 | #define LLC_DATA_INDICATION 9 | |
222 | /* | |
223 | * LLC_REMOTE_NOT_BUSY --- The remote LLC DSAP is no longer busy. The local | |
224 | * connection service component will now accept a | |
225 | * DATA_REQUEST. | |
226 | */ | |
227 | #define LLC_REMOTE_NOT_BUSY 10 | |
228 | /* | |
229 | * LLC_REMOTE_BUSY --- The remote LLC DSAP is busy. The local connection | |
230 | * service component will not accept a DATA_REQUEST. | |
231 | */ | |
232 | #define LLC_REMOTE_BUSY 11 | |
233 | ||
234 | /* Internal return code */ | |
235 | #define LLC_PASSITON 255 | |
236 | ||
237 | #define INFORMATION_CONTROL 0x00 | |
238 | #define SUPERVISORY_CONTROL 0x02 | |
239 | #define UNUMBERED_CONTROL 0x03 | |
240 | ||
241 | /* | |
242 | * Other necessary definitions | |
243 | */ | |
244 | ||
245 | #define LLC_MAX_SEQUENCE 128 | |
246 | #define LLC_MAX_WINDOW 127 | |
247 | #define LLC_WINDOW_SIZE 7 | |
248 | ||
249 | /* | |
250 | * Don't we love this one? CCITT likes to suck on bits 8=) | |
251 | */ | |
252 | #define NLHDRSIZEGUESS 3 | |
253 | ||
254 | /* | |
255 | * LLC control block | |
256 | */ | |
257 | ||
258 | struct llc_linkcb { | |
259 | struct llccb_q { | |
260 | struct llccb_q *q_forw; /* admin chain */ | |
261 | struct llccb_q *q_backw; | |
262 | } llcl_q; | |
263 | struct npaidbentry *llcl_sapinfo; /* SAP information */ | |
264 | struct sockaddr_dl llcl_addr; /* link snpa address */ | |
265 | struct rtentry *llcl_nlrt; /* layer 3 -> LLC */ | |
266 | struct rtentry *llcl_llrt; /* LLC -> layer 3 */ | |
267 | struct ifnet *llcl_if; /* our interface */ | |
268 | caddr_t llcl_nlnext; /* cb for network layer */ | |
269 | struct mbuf *llcl_writeqh; /* Write queue head */ | |
270 | struct mbuf *llcl_writeqt; /* Write queue tail */ | |
271 | struct mbuf **llcl_output_buffers; | |
272 | short llcl_timers[6]; /* timer array */ | |
273 | long llcl_timerflags; /* flags signalling running timers */ | |
274 | int (*llcl_statehandler) | |
275 | __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
276 | int llcl_P_flag; | |
277 | int llcl_F_flag; | |
278 | int llcl_S_flag; | |
279 | int llcl_DATA_flag; | |
280 | int llcl_REMOTE_BUSY_flag; | |
281 | int llcl_DACTION_flag; /* delayed action */ | |
282 | int llcl_retry; | |
283 | /* | |
284 | * The following components deal --- in one way or the other --- | |
285 | * with the LLC2 window. Indicated by either [L] or [W] is the | |
286 | * domain of the specific component: | |
287 | * | |
288 | * [L] The domain is 0--LLC_MAX_WINDOW | |
289 | * [W] The domain is 0--llcl_window | |
290 | */ | |
291 | short llcl_vr; /* next to receive [L] */ | |
292 | short llcl_vs; /* next to send [L] */ | |
293 | short llcl_nr_received; /* next frame to b ack'd [L] */ | |
294 | short llcl_freeslot; /* next free slot [W] */ | |
295 | short llcl_projvs; /* V(S) associated with freeslot */ | |
296 | short llcl_slotsfree; /* free slots [W] */ | |
297 | short llcl_window; /* window size */ | |
298 | /* | |
299 | * In llcl_frmrinfo we jot down the last frmr info field, which we | |
300 | * need to do as we need to be able to resend it in the ERROR state. | |
301 | */ | |
302 | struct frmrinfo llcl_frmrinfo; /* last FRMR info field */ | |
303 | }; | |
304 | #define llcl_frmr_pdu0 llcl_frmrinfo.rej_pdu_0 | |
305 | #define llcl_frmr_pdu1 llcl_frmrinfo.rej_pdu_1 | |
306 | #define llcl_frmr_control llcl_frmrinfo.frmr_control | |
307 | #define llcl_frmr_control_ext llcl_frmrinfo.frmr_control_ext | |
308 | #define llcl_frmr_cause llcl_frmrinfo.frmr_cause | |
309 | ||
310 | #define LQNEXT(l) (struct llc_linkcb *)((l)->llcl_q.q_forw) | |
311 | #define LQEMPTY (llccb_q.q_forw == &llccb_q) | |
312 | #define LQFIRST (struct llc_linkcb *)(llccb_q.q_forw) | |
313 | #define LQVALID(l) (!((struct llccb_q *)(l) == &llccb_q)) | |
314 | ||
315 | #define LLC_ENQUEUE(l, m) if ((l)->llcl_writeqh == NULL) { \ | |
316 | (l)->llcl_writeqh = (m); \ | |
317 | (l)->llcl_writeqt = (m); \ | |
318 | } else { \ | |
319 | (l)->llcl_writeqt->m_nextpkt = (m); \ | |
320 | (l)->llcl_writeqt = (m); \ | |
321 | } | |
322 | ||
323 | #define LLC_DEQUEUE(l, m) if ((l)->llcl_writeqh == NULL) \ | |
324 | (m) = NULL; \ | |
325 | else { \ | |
326 | (m) = (l)->llcl_writeqh; \ | |
327 | (l)->llcl_writeqh = (l)->llcl_writeqh->m_nextpkt; \ | |
328 | } | |
329 | ||
330 | #define LLC_SETFRAME(l, m) { \ | |
331 | if ((l)->llcl_slotsfree > 0) { \ | |
332 | (l)->llcl_slotsfree--; \ | |
333 | (l)->llcl_output_buffers[(l)->llcl_freeslot] = (m); \ | |
334 | (l)->llcl_freeslot = ((l)->llcl_freeslot+1) % (l)->llcl_window; \ | |
335 | LLC_INC((l)->llcl_projvs); \ | |
336 | } \ | |
337 | } | |
338 | ||
339 | /* | |
340 | * handling of sockaddr_dl's | |
341 | */ | |
342 | ||
343 | #define LLADDRLEN(s) ((s)->sdl_alen + (s)->sdl_nlen) | |
344 | #define LLSAPADDR(s) ((s)->sdl_data[LLADDRLEN(s)-1] & 0xff) | |
345 | #define LLSAPLOC(s, if) ((s)->sdl_nlen + (if)->if_addrlen) | |
346 | ||
347 | struct sdl_hdr { | |
348 | struct sockaddr_dl sdlhdr_dst; | |
349 | struct sockaddr_dl sdlhdr_src; | |
350 | long sdlhdr_len; | |
351 | }; | |
352 | ||
353 | #define LLC_GETHDR(f,m) { \ | |
354 | struct mbuf *_m = (struct mbuf *) (m); \ | |
355 | if (_m) { \ | |
356 | M_PREPEND(_m, LLC_ISFRAMELEN, M_DONTWAIT); \ | |
357 | bzero(mtod(_m, caddr_t), LLC_ISFRAMELEN); \ | |
358 | } else { \ | |
359 | MGETHDR (_m, M_DONTWAIT, MT_HEADER); \ | |
360 | if (_m != NULL) { \ | |
361 | _m->m_pkthdr.len = _m->m_len = LLC_UFRAMELEN; \ | |
362 | _m->m_next = _m->m_act = NULL; \ | |
363 | bzero(mtod(_m, caddr_t), LLC_UFRAMELEN); \ | |
364 | } else return; \ | |
365 | } \ | |
366 | (m) = _m; \ | |
367 | (f) = mtod(m, struct llc *); \ | |
368 | } | |
369 | ||
370 | #define LLC_NEWSTATE(l, LLCstate) (l)->llcl_statehandler = llc_state_##LLCstate | |
371 | #define LLC_STATEEQ(l, LLCstate) ((l)->llcl_statehandler == llc_state_##LLCstate ? 1 : 0) | |
372 | ||
373 | #define LLC_ACK_SHIFT 0 | |
374 | #define LLC_P_SHIFT 1 | |
375 | #define LLC_BUSY_SHIFT 2 | |
376 | #define LLC_REJ_SHIFT 3 | |
377 | #define LLC_AGE_SHIFT 4 | |
378 | #define LLC_DACTION_SHIFT 5 | |
379 | ||
380 | #define LLC_TIMER_NOTRUNNING 0 | |
381 | #define LLC_TIMER_RUNNING 1 | |
382 | #define LLC_TIMER_EXPIRED 2 | |
383 | ||
384 | #define LLC_STARTTIMER(l, LLCtimer) { \ | |
385 | (l)->llcl_timers[LLC_##LLCtimer##_SHIFT] = llc_##LLCtimer##_timer; \ | |
386 | (l)->llcl_timerflags |= (1<<LLC_##LLCtimer##_SHIFT); \ | |
387 | } | |
388 | #define LLC_STOPTIMER(l, LLCtimer) { \ | |
389 | (l)->llcl_timers[LLC_##LLCtimer##_SHIFT] = 0; \ | |
390 | (l)->llcl_timerflags &= ~(1<<LLC_##LLCtimer##_SHIFT); \ | |
391 | } | |
392 | #define LLC_AGETIMER(l, LLCtimer) if ((l)->llcl_timers[LLC_##LLCtimer##_SHIFT] > 0) \ | |
393 | (l)->llcl_timers[LLC_##LLCtimer##_SHIFT]--; | |
394 | ||
395 | #define LLC_TIMERXPIRED(l, LLCtimer) \ | |
396 | (((l)->llcl_timerflags & (1<<LLC_##LLCtimer##_SHIFT)) ? \ | |
397 | (((l)->llcl_timers[LLC_##LLCtimer##_SHIFT] == 0 ) ? \ | |
398 | LLC_TIMER_EXPIRED : LLC_TIMER_RUNNING) : LLC_TIMER_NOTRUNNING) | |
399 | ||
400 | #define FOR_ALL_LLC_TIMERS(t) for ((t) = LLC_ACK_SHIFT; (t) < LLC_AGE_SHIFT; (t)++) | |
401 | ||
402 | #define LLC_SETFLAG(l, LLCflag, v) (l)->llcl_##LLCflag##_flag = (v) | |
403 | #define LLC_GETFLAG(l, LLCflag) (l)->llcl_##LLCflag##_flag | |
404 | ||
405 | #define LLC_RESETCOUNTER(l) { \ | |
406 | (l)->llcl_vs = (l)->llcl_vr = (l)->llcl_retry = 0; \ | |
407 | llc_resetwindow((l)); \ | |
408 | } | |
409 | ||
410 | /* | |
411 | * LLC2 macro definitions | |
412 | */ | |
413 | ||
414 | ||
415 | #define LLC_START_ACK_TIMER(l) LLC_STARTTIMER((l), ACK) | |
416 | #define LLC_STOP_ACK_TIMER(l) LLC_STOPTIMER((l), ACK) | |
417 | #define LLC_START_REJ_TIMER(l) LLC_STARTTIMER((l), REJ) | |
418 | #define LLC_STOP_REJ_TIMER(l) LLC_STOPTIMER((l), REJ) | |
419 | #define LLC_START_P_TIMER(l) { \ | |
420 | LLC_STARTTIMER((l), P); \ | |
421 | if (LLC_GETFLAG((l), P) == 0) \ | |
422 | (l)->llcl_retry = 0; \ | |
423 | LLC_SETFLAG((l), P, 1); \ | |
424 | } | |
425 | #define LLC_STOP_P_TIMER(l) { \ | |
426 | LLC_STOPTIMER((l), P); \ | |
427 | LLC_SETFLAG((l), P, 0); \ | |
428 | } | |
429 | #define LLC_STOP_ALL_TIMERS(l) { \ | |
430 | LLC_STOPTIMER((l), ACK); \ | |
431 | LLC_STOPTIMER((l), REJ); \ | |
432 | LLC_STOPTIMER((l), BUSY); \ | |
433 | LLC_STOPTIMER((l), P); \ | |
434 | } | |
435 | ||
436 | ||
437 | #define LLC_INC(i) (i) = ((i)+1) % LLC_MAX_SEQUENCE | |
438 | ||
439 | #define LLC_NR_VALID(l, nr) ((l)->llcl_vs < (l)->llcl_nr_received ? \ | |
440 | (((nr) >= (l)->llcl_nr_received) || \ | |
441 | ((nr) <= (l)->llcl_vs) ? 1 : 0) : \ | |
442 | (((nr) <= (l)->llcl_vs) && \ | |
443 | ((nr) >= (l)->llcl_nr_received) ? 1 : 0)) | |
444 | ||
445 | #define LLC_UPDATE_P_FLAG(l, cr, pf) { \ | |
446 | if ((cr) == LLC_RSP && (pf) == 1) { \ | |
447 | LLC_SETFLAG((l), P, 0); \ | |
448 | LLC_STOPTIMER((l), P); \ | |
449 | } \ | |
450 | } | |
451 | ||
452 | #define LLC_UPDATE_NR_RECEIVED(l, nr) { \ | |
453 | while ((l)->llcl_nr_received != (nr)) { \ | |
454 | struct mbuf *_m; \ | |
455 | register short seq; \ | |
456 | if (_m = (l)->llcl_output_buffers[seq = llc_seq2slot((l), (l)->llcl_nr_received)]) \ | |
457 | m_freem(_m); \ | |
458 | (l)->llcl_output_buffers[seq] = NULL; \ | |
459 | LLC_INC((l)->llcl_nr_received); \ | |
460 | (l)->llcl_slotsfree++; \ | |
461 | } \ | |
462 | (l)->llcl_retry = 0; \ | |
463 | if ((l)->llcl_slotsfree < (l)->llcl_window) { \ | |
464 | LLC_START_ACK_TIMER(l); \ | |
465 | } else LLC_STOP_ACK_TIMER(l); \ | |
466 | LLC_STARTTIMER((l), DACTION); \ | |
467 | } | |
468 | ||
469 | #define LLC_SET_REMOTE_BUSY(l,a) { \ | |
470 | if (LLC_GETFLAG((l), REMOTE_BUSY) == 0) { \ | |
471 | LLC_SETFLAG((l), REMOTE_BUSY, 1); \ | |
472 | LLC_STARTTIMER((l), BUSY); \ | |
473 | (a) = LLC_REMOTE_BUSY; \ | |
474 | } else { \ | |
475 | (a) = 0; \ | |
476 | } \ | |
477 | } | |
478 | #define LLC_CLEAR_REMOTE_BUSY(l,a) { \ | |
479 | if (LLC_GETFLAG((l), REMOTE_BUSY) == 1) { \ | |
480 | LLC_SETFLAG((l), REMOTE_BUSY, 1); \ | |
481 | LLC_STOPTIMER((l), BUSY); \ | |
482 | if (LLC_STATEEQ((l), NORMAL) || \ | |
483 | LLC_STATEEQ((l), REJECT) || \ | |
484 | LLC_STATEEQ((l), BUSY)) \ | |
485 | llc_resend((l), LLC_CMD, 0); \ | |
486 | (a) = LLC_REMOTE_NOT_BUSY; \ | |
487 | } else { \ | |
488 | (a) = 0; \ | |
489 | } \ | |
490 | } | |
491 | ||
492 | #define LLC_DACKCMD 0x1 | |
493 | #define LLC_DACKCMDPOLL 0x2 | |
494 | #define LLC_DACKRSP 0x3 | |
495 | #define LLC_DACKRSPFINAL 0x4 | |
496 | ||
497 | #define LLC_SENDACKNOWLEDGE(l, cmd, pf) { \ | |
498 | if ((cmd) == LLC_CMD) { \ | |
499 | LLC_SETFLAG((l), DACTION, ((pf) == 0 ? LLC_DACKCMD : LLC_DACKCMDPOLL)); \ | |
500 | } else { \ | |
501 | LLC_SETFLAG((l), DACTION, ((pf) == 0 ? LLC_DACKRSP : LLC_DACKRSPFINAL)); \ | |
502 | } \ | |
503 | } | |
504 | ||
505 | #define LLC_FRMR_W (1<<0) | |
506 | #define LLC_FRMR_X (1<<1) | |
507 | #define LLC_FRMR_Y (1<<2) | |
508 | #define LLC_FRMR_Z (1<<3) | |
509 | #define LLC_FRMR_V (1<<4) | |
510 | ||
511 | #define LLC_SETFRMR(l, f, cr, c) { \ | |
512 | if ((f)->llc_control & 0x3) { \ | |
513 | (l)->llcl_frmr_pdu0 = (f)->llc_control; \ | |
514 | (l)->llcl_frmr_pdu1 = 0; \ | |
515 | } else { \ | |
516 | (l)->llcl_frmr_pdu0 = (f)->llc_control; \ | |
517 | (l)->llcl_frmr_pdu1 = (f)->llc_control_ext; \ | |
518 | } \ | |
519 | LLCCSBITS((l)->llcl_frmr_control, f_vs, (l)->llcl_vs); \ | |
520 | LLCCSBITS((l)->llcl_frmr_control_ext, f_cr, (cr)); \ | |
521 | LLCSBITS((l)->llcl_frmr_control_ext, f_vr, (l)->llcl_vr); \ | |
522 | LLCCSBITS((l)->llcl_frmr_cause, f_wxyzv, (c)); \ | |
523 | } | |
524 | ||
525 | /* | |
526 | * LLC tracing levels: | |
527 | * LLCTR_INTERESTING interesting event, we might care to know about | |
528 | * it, but then again, we might not ... | |
529 | * LLCTR_SHOULDKNOW we probably should know about this event | |
530 | * LLCTR_URGENT something has gone utterly wrong ... | |
531 | */ | |
532 | #define LLCTR_INTERESTING 1 | |
533 | #define LLCTR_SHOULDKNOW 2 | |
534 | #define LLCTR_URGENT 3 | |
535 | ||
536 | #ifdef LLCDEBUG | |
537 | #define LLC_TRACE(lp, l, msg) llc_trace((lp), (l), (msg)) | |
538 | #else /* LLCDEBUG */ | |
539 | #define LLC_TRACE(lp, l, msg) /* NOOP */ | |
540 | #endif /* LLCDEBUG */ | |
541 | ||
542 | #define LLC_N2_VALUE 15 /* up to 15 retries */ | |
543 | #define LLC_ACK_TIMER 10 /* 5 secs */ | |
544 | #define LLC_P_TIMER 4 /* 2 secs */ | |
545 | #define LLC_BUSY_TIMER 12 /* 6 secs */ | |
546 | #define LLC_REJ_TIMER 12 /* 6 secs */ | |
547 | #define LLC_AGE_TIMER 40 /* 20 secs */ | |
548 | #define LLC_DACTION_TIMER 2 /* 1 secs */ | |
549 | ||
550 | #if defined (KERNEL) && defined(LLC) | |
551 | extern int llc_n2; | |
552 | extern int llc_ACK_timer; | |
553 | extern int llc_P_timer; | |
554 | extern int llc_REJ_timer; | |
555 | extern int llc_BUSY_timer; | |
556 | extern int llc_AGE_timer; | |
557 | extern int llc_DACTION_timer; | |
558 | ||
1e4f18be DH |
559 | extern int af_link_rts_init_done; |
560 | ||
561 | #define USES_AF_LINK_RTS { \ | |
562 | if (!af_link_rts_init_done) { \ | |
563 | rn_inithead((void **)&rt_tables[AF_LINK], 32); \ | |
564 | af_link_rts_init_done++; \ | |
565 | } \ | |
566 | } | |
567 | ||
c462de67 KS |
568 | struct ifqueue llcintrq; |
569 | ||
570 | extern struct llccb_q llccb_q; | |
571 | extern char *frame_names[]; | |
572 | ||
573 | /* | |
574 | * Function prototypes | |
575 | */ | |
576 | int sdl_cmp __P((struct sockaddr_dl *, struct sockaddr_dl *)); | |
577 | int sdl_copy __P((struct sockaddr_dl *, struct sockaddr_dl *)); | |
578 | int sdl_swapaddr __P((struct sockaddr_dl *, struct sockaddr_dl *)); | |
579 | int sdl_checkaddrif __P((struct ifnet *, struct sockaddr_dl *)); | |
580 | int sdl_setaddrif __P((struct ifnet *, u_char *, u_char, u_char, | |
581 | struct sockaddr_dl *)); | |
582 | int sdl_sethdrif __P((struct ifnet *, u_char *, u_char, u_char *, u_char, u_char, | |
583 | struct sdl_hdr *)); | |
584 | struct npaidbentry *llc_setsapinfo __P((struct ifnet *, u_char, u_char, | |
585 | struct dllconfig *)); | |
586 | struct npaidbentry *llc_getsapinfo __P((u_char, struct ifnet *)); | |
587 | struct rtentry *npaidb_enrich __P((short, caddr_t, struct sockaddr_dl *)); | |
588 | int npaidb_destroy __P((struct rtentry *)); | |
589 | short llc_seq2slot __P((struct llc_linkcb *, short)); | |
590 | int llc_state_ADM __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
591 | int llc_state_CONN __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
592 | int llc_state_RESET_WAIT __P((struct llc_linkcb *, struct llc *, | |
593 | int, int, int)); | |
594 | int llc_state_RESET_CHECK __P((struct llc_linkcb *, struct llc *, | |
595 | int, int, int)); | |
596 | int llc_state_SETUP __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
597 | int llc_state_RESET __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
598 | int llc_state_D_CONN __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
599 | int llc_state_ERROR __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
600 | int llc_state_NBRAcore __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
601 | int llc_state_NORMAL __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
602 | int llc_state_BUSY __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
603 | int llc_state_REJECT __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
604 | int llc_state_AWAIT __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
605 | int llc_state_AWAIT_BUSY __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
606 | int llc_state_AWAIT_REJECT __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
607 | int llc_statehandler __P((struct llc_linkcb *, struct llc *, int, int, int)); | |
608 | int llc_init __P((void)); | |
609 | struct llc_linkcb *llc_newlink __P((struct sockaddr_dl *, struct ifnet *, | |
610 | struct rtentry *, caddr_t, struct rtentry *)); | |
611 | int llc_dellink __P((struct llc_linkcb *)); | |
612 | int llc_anytimersup __P((struct llc_linkcb *)); | |
613 | char * llc_getstatename __P((struct llc_linkcb *)); | |
614 | void llc_link_dump __P((struct llc_linkcb *, const char *)); | |
615 | void llc_trace __P((struct llc_linkcb *, int, const char *)); | |
616 | void llc_resetwindow __P((struct llc_linkcb *)); | |
617 | int llc_decode __P((struct llc *, struct llc_linkcb *)); | |
618 | void llc_timer __P((void)); | |
619 | void llcintr __P((void)); | |
620 | int llc_input __P((struct llc_linkcb *, struct mbuf *, u_char)); | |
621 | caddr_t llc_ctlinput __P((int, struct sockaddr *, caddr_t)); | |
622 | int llc_output __P((struct llc_linkcb *, struct mbuf *)); | |
623 | void llc_start __P((struct llc_linkcb *)); | |
624 | int llc_send __P((struct llc_linkcb *, int, int, int)); | |
625 | int llc_resend __P((struct llc_linkcb *, int, int)); | |
626 | int llc_rawsend __P((struct llc_linkcb *, struct mbuf *, struct llc *, int, int, | |
627 | int, int)); | |
628 | int cons_rtrequest __P((int, struct rtentry *, struct sockaddr *)); | |
629 | int x25_llcglue __P((int, struct sockaddr *)); | |
630 | ||
631 | #endif | |
632 | ||
633 |