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