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