xref: /original-bsd/sys/netccitt/llc_var.h (revision 8f8e557c)
1 /*
2  * Copyright (C) Dirk Husemann, Computer Science Department IV,
3  * 		 University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992
4  * Copyright (c) 1992, 1993
5  *	The Regents of the University of California.  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  *
13  *	@(#)llc_var.h	8.2 (Berkeley) 02/09/95
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 			void (*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 
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 
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 void cons_rtrequest __P((int, struct rtentry *, struct sockaddr *));
629 int x25_llcglue __P((int, struct sockaddr *));
630 
631 #endif
632 
633 
634