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