157028Ssklower /* 257028Ssklower * Copyright (C) Dirk Husemann, Computer Science Department IV, 357028Ssklower * University of Erlangen-Nuremberg, Germany, 1990, 1991, 1992 463216Sbostic * Copyright (c) 1992, 1993 563216Sbostic * The Regents of the University of California. All rights reserved. 657028Ssklower * 757028Ssklower * This code is derived from software contributed to Berkeley by 857028Ssklower * Dirk Husemann and the Computer Science Department (IV) of 957028Ssklower * the University of Erlangen-Nuremberg, Germany. 1057028Ssklower * 1157028Ssklower * %sccs.include.redist.c% 1257028Ssklower * 13*68257Scgd * @(#)llc_var.h 8.2 (Berkeley) 02/09/95 1457028Ssklower */ 1557028Ssklower 1657028Ssklower #ifdef __STDC__ 1757028Ssklower /* 1857028Ssklower * Forward structure declarations for function prototypes [sic]. 1957028Ssklower */ 2057028Ssklower struct llc; 2157028Ssklower #endif 2257028Ssklower 2357028Ssklower #define NPAIDB_LINK 0 2457028Ssklower 2557028Ssklower struct npaidbentry { 2657028Ssklower union { 2757028Ssklower /* MAC,DLSAP -> CONS */ 2857028Ssklower struct { 2957028Ssklower struct llc_linkcb *NE_link; 3057028Ssklower struct rtentry *NE_rt; 3157028Ssklower } NE; 3257028Ssklower /* SAP info for unconfigured incoming calls */ 3357028Ssklower struct { 3457028Ssklower u_short SI_class; 3557028Ssklower #define LLC_CLASS_I 0x1 3657028Ssklower #define LLC_CLASS_II 0x3 3757028Ssklower #define LLC_CLASS_III 0x4 /* Future */ 3857028Ssklower #define LLC_CLASS_IV 0x7 /* Future */ 3957028Ssklower u_short SI_window; 4057028Ssklower u_short SI_trace; 4157028Ssklower u_short SI_xchxid; 4261656Ssklower void (*SI_input) 4357028Ssklower __P((struct mbuf *)); 4457028Ssklower caddr_t (*SI_ctlinput) 4557028Ssklower __P((int, struct sockaddr *, caddr_t)); 4657028Ssklower } SI; 4757028Ssklower } NESIun; 4857028Ssklower }; 4957028Ssklower #define np_link NESIun.NE.NE_link 5057028Ssklower #define np_rt NESIun.NE.NE_rt 5157028Ssklower #define si_class NESIun.SI.SI_class 5257028Ssklower #define si_window NESIun.SI.SI_window 5357028Ssklower #define si_trace NESIun.SI.SI_trace 5457028Ssklower #define si_xchxid NESIun.SI.SI_xchxid 5557028Ssklower #define si_input NESIun.SI.SI_input 5657028Ssklower #define si_ctlinput NESIun.SI.SI_ctlinput 5757028Ssklower 5857028Ssklower #define NPDL_SAPNETMASK 0x7e 5957028Ssklower 6057028Ssklower /* 6157028Ssklower * Definitions for accessing bitfields/bitslices inside 6257028Ssklower * LLC2 headers 6357028Ssklower */ 6457028Ssklower struct bitslice { 6557028Ssklower unsigned int bs_mask; 6657028Ssklower unsigned int bs_shift; 6757028Ssklower }; 6857028Ssklower 6957028Ssklower 7057028Ssklower #define i_z 0 7157028Ssklower #define i_ns 1 7257028Ssklower #define i_pf 0 7357028Ssklower #define i_nr 1 7457028Ssklower #define s_oz 2 7557028Ssklower #define s_selector 3 7657028Ssklower #define s_pf 0 7757028Ssklower #define s_nr 1 7857028Ssklower #define u_bb 2 7957028Ssklower #define u_select_other 3 8057028Ssklower #define u_pf 4 8157028Ssklower #define u_select 5 8257028Ssklower #define f_vs 1 8357028Ssklower #define f_cr 0 8457028Ssklower #define f_vr 1 8557028Ssklower #define f_wxyzv 6 8657028Ssklower 8757028Ssklower #define LLCGBITS(Arg, Index) (((Arg) & llc_bitslice[(Index)].bs_mask) >> llc_bitslice[(Index)].bs_shift) 8857028Ssklower #define LLCSBITS(Arg, Index, Val) (Arg) |= (((Val) << llc_bitslice[(Index)].bs_shift) & llc_bitslice[(Index)].bs_mask) 8957028Ssklower #define LLCCSBITS(Arg, Index, Val) (Arg) = (((Val) << llc_bitslice[(Index)].bs_shift) & llc_bitslice[(Index)].bs_mask) 9057028Ssklower 9157028Ssklower extern struct bitslice llc_bitslice[]; 9257028Ssklower 9357028Ssklower #define LLC_CMD 0 9457028Ssklower #define LLC_RSP 1 9557028Ssklower #define LLC_MAXCMDRSP 2 9657028Ssklower 9757028Ssklower /* 9857028Ssklower * LLC events --- These events may either be frames received from the 9957028Ssklower * remote LLC DSAP, request from the network layer user, 10057028Ssklower * timer events from llc_timer(), or diagnostic events from 10157028Ssklower * llc_input(). 10257028Ssklower */ 10357028Ssklower 10457028Ssklower /* LLC frame types */ 10557028Ssklower #define LLCFT_INFO 0 * LLC_MAXCMDRSP 10657028Ssklower #define LLCFT_RR 1 * LLC_MAXCMDRSP 10757028Ssklower #define LLCFT_RNR 2 * LLC_MAXCMDRSP 10857028Ssklower #define LLCFT_REJ 3 * LLC_MAXCMDRSP 10957028Ssklower #define LLCFT_DM 4 * LLC_MAXCMDRSP 11057028Ssklower #define LLCFT_SABME 5 * LLC_MAXCMDRSP 11157028Ssklower #define LLCFT_DISC 6 * LLC_MAXCMDRSP 11257028Ssklower #define LLCFT_UA 7 * LLC_MAXCMDRSP 11357028Ssklower #define LLCFT_FRMR 8 * LLC_MAXCMDRSP 11457028Ssklower #define LLCFT_UI 9 * LLC_MAXCMDRSP 11557028Ssklower #define LLCFT_XID 10 * LLC_MAXCMDRSP 11657028Ssklower #define LLCFT_TEST 11 * LLC_MAXCMDRSP 11757028Ssklower 11857028Ssklower /* LLC2 timer events */ 11957028Ssklower #define LLC_ACK_TIMER_EXPIRED 12 * LLC_MAXCMDRSP 12057028Ssklower #define LLC_P_TIMER_EXPIRED 13 * LLC_MAXCMDRSP 12157028Ssklower #define LLC_REJ_TIMER_EXPIRED 14 * LLC_MAXCMDRSP 12257028Ssklower #define LLC_BUSY_TIMER_EXPIRED 15 * LLC_MAXCMDRSP 12357028Ssklower 12457028Ssklower /* LLC2 diagnostic events */ 12557028Ssklower #define LLC_INVALID_NR 16 * LLC_MAXCMDRSP 12657028Ssklower #define LLC_INVALID_NS 17 * LLC_MAXCMDRSP 12757028Ssklower #define LLC_BAD_PDU 18 * LLC_MAXCMDRSP 12857028Ssklower #define LLC_LOCAL_BUSY_DETECTED 19 * LLC_MAXCMDRSP 12957028Ssklower #define LLC_LOCAL_BUSY_CLEARED 20 * LLC_MAXCMDRSP 13057028Ssklower 13157028Ssklower /* Network layer user requests */ 13257028Ssklower /* 13357028Ssklower * NL_CONNECT_REQUEST --- The user has requested that a data link connection 13457028Ssklower * be established with a remote LLC DSAP. 13557028Ssklower */ 13657028Ssklower #define NL_CONNECT_REQUEST 21 * LLC_MAXCMDRSP 13757028Ssklower /* 13857028Ssklower * NL_CONNECT_RESPONSE --- The user has accepted the data link connection. 13957028Ssklower */ 14057028Ssklower #define NL_CONNECT_RESPONSE 22 * LLC_MAXCMDRSP 14157028Ssklower /* 14257028Ssklower * NL_RESET_REQUEST --- The user has requested that the data link with the 14357028Ssklower * remote LLC DSAP be reset. 14457028Ssklower */ 14557028Ssklower #define NL_RESET_REQUEST 23 * LLC_MAXCMDRSP 14657028Ssklower /* 14757028Ssklower * NL_RESET_RESPONSE --- The user has accepted the reset of the data link 14857028Ssklower * connection. 14957028Ssklower */ 15057028Ssklower #define NL_RESET_RESPONSE 24 * LLC_MAXCMDRSP 15157028Ssklower /* 15257028Ssklower * NL_DISCONNECT_REQUEST --- The user has requested that the data link 15357028Ssklower * connection with remote LLC DSAP be terminated. 15457028Ssklower */ 15557028Ssklower #define NL_DISCONNECT_REQUEST 25 * LLC_MAXCMDRSP 15657028Ssklower /* 15757028Ssklower * NL_DATA_REQUEST --- The user has requested that a data unit be sent ot the 15857028Ssklower * remote LLC DSAP. 15957028Ssklower */ 16057028Ssklower #define NL_DATA_REQUEST 26 * LLC_MAXCMDRSP 16157028Ssklower /* 16257028Ssklower * NL_INITIATE_PF_CYCLE --- The local LLC wants to initiate a P/F cycle. 16357028Ssklower */ 16457028Ssklower #define NL_INITIATE_PF_CYCLE 27 * LLC_MAXCMDRSP 16557028Ssklower /* 16657028Ssklower * NL_LOCAL_BUSY_DETECTED --- The local entity has encountered a busy condition 16757028Ssklower */ 16857028Ssklower #define NL_LOCAL_BUSY_DETECTED 28 * LLC_MAXCMDRSP 16957028Ssklower 17057028Ssklower #define LLCFT_NONE 255 17157028Ssklower 17257028Ssklower /* return message from state handlers */ 17357028Ssklower 17457028Ssklower /* 17557028Ssklower * LLC_CONNECT_INDICATION --- Inform the user that a connection has been 17657028Ssklower * requested by a remote LLC SSAP. 17757028Ssklower */ 17857028Ssklower #define LLC_CONNECT_INDICATION 1 17957028Ssklower /* 18057028Ssklower * LLC_CONNECT_CONFIRM --- The connection service component indicates that the 18157028Ssklower * remote network entity has accepted the connection. 18257028Ssklower */ 18357028Ssklower #define LLC_CONNECT_CONFIRM 2 18457028Ssklower /* 18557028Ssklower * LLC_DISCONNECT_INDICATION --- Inform the user that the remote network 18657028Ssklower * entity has intiated disconnection of the data 18757028Ssklower * link connection. 18857028Ssklower */ 18957028Ssklower #define LLC_DISCONNECT_INDICATION 3 19057028Ssklower /* 19157028Ssklower * LLC_RESET_CONFIRM --- The connection service component indicates that the 19257028Ssklower * remote network entity has accepted the reset. 19357028Ssklower */ 19457028Ssklower #define LLC_RESET_CONFIRM 4 19557028Ssklower /* 19657028Ssklower * LLC_RESET_INDICATION_REMOTE --- The remote network entity or remote peer 19757028Ssklower * has initiated a reset of the data link 19857028Ssklower * connection. 19957028Ssklower */ 20057028Ssklower #define LLC_RESET_INDICATION_REMOTE 5 20157028Ssklower /* 20257028Ssklower * LLC_RESET_INDICATION_LOCAL --- The local LLC has determined that the data 20357028Ssklower * link connection is in need of 20457028Ssklower * reinitialization. 20557028Ssklower */ 20657028Ssklower #define LLC_RESET_INDICATION_LOCAL 6 20757028Ssklower /* 20857028Ssklower * LLC_FRMR_RECEIVED --- The local connection service component has received a 20957028Ssklower * FRMR response PDU. 21057028Ssklower */ 21157028Ssklower #define LLC_FRMR_RECEIVED 7 21257028Ssklower /* 21357028Ssklower * LLC_FRMR_SENT --- The local connection component has received an ivalid 21457028Ssklower * PDU, and has sent a FRMR response PDU. 21557028Ssklower */ 21657028Ssklower #define LLC_FRMR_SENT 8 21757028Ssklower /* 21857028Ssklower * LLC_DATA_INDICATION --- The connection service component passes the data 21957028Ssklower * unit from the received I PDU to the user. 22057028Ssklower */ 22157028Ssklower #define LLC_DATA_INDICATION 9 22257028Ssklower /* 22357028Ssklower * LLC_REMOTE_NOT_BUSY --- The remote LLC DSAP is no longer busy. The local 22457028Ssklower * connection service component will now accept a 22557028Ssklower * DATA_REQUEST. 22657028Ssklower */ 22757028Ssklower #define LLC_REMOTE_NOT_BUSY 10 22857028Ssklower /* 22957028Ssklower * LLC_REMOTE_BUSY --- The remote LLC DSAP is busy. The local connection 23057028Ssklower * service component will not accept a DATA_REQUEST. 23157028Ssklower */ 23257028Ssklower #define LLC_REMOTE_BUSY 11 23357028Ssklower 23457028Ssklower /* Internal return code */ 23557028Ssklower #define LLC_PASSITON 255 23657028Ssklower 23757028Ssklower #define INFORMATION_CONTROL 0x00 23857028Ssklower #define SUPERVISORY_CONTROL 0x02 23957028Ssklower #define UNUMBERED_CONTROL 0x03 24057028Ssklower 24157028Ssklower /* 24257028Ssklower * Other necessary definitions 24357028Ssklower */ 24457028Ssklower 24557028Ssklower #define LLC_MAX_SEQUENCE 128 24657028Ssklower #define LLC_MAX_WINDOW 127 24757028Ssklower #define LLC_WINDOW_SIZE 7 24857028Ssklower 24957028Ssklower /* 25057028Ssklower * Don't we love this one? CCITT likes to suck on bits 8=) 25157028Ssklower */ 25257028Ssklower #define NLHDRSIZEGUESS 3 25357028Ssklower 25457028Ssklower /* 25557028Ssklower * LLC control block 25657028Ssklower */ 25757028Ssklower 25857028Ssklower struct llc_linkcb { 25957028Ssklower struct llccb_q { 26057028Ssklower struct llccb_q *q_forw; /* admin chain */ 26157028Ssklower struct llccb_q *q_backw; 26257028Ssklower } llcl_q; 26357028Ssklower struct npaidbentry *llcl_sapinfo; /* SAP information */ 26457028Ssklower struct sockaddr_dl llcl_addr; /* link snpa address */ 26557028Ssklower struct rtentry *llcl_nlrt; /* layer 3 -> LLC */ 26657028Ssklower struct rtentry *llcl_llrt; /* LLC -> layer 3 */ 26757028Ssklower struct ifnet *llcl_if; /* our interface */ 26857028Ssklower caddr_t llcl_nlnext; /* cb for network layer */ 26957028Ssklower struct mbuf *llcl_writeqh; /* Write queue head */ 27057028Ssklower struct mbuf *llcl_writeqt; /* Write queue tail */ 27157028Ssklower struct mbuf **llcl_output_buffers; 27257028Ssklower short llcl_timers[6]; /* timer array */ 27357028Ssklower long llcl_timerflags; /* flags signalling running timers */ 27457028Ssklower int (*llcl_statehandler) 27557028Ssklower __P((struct llc_linkcb *, struct llc *, int, int, int)); 27657028Ssklower int llcl_P_flag; 27757028Ssklower int llcl_F_flag; 27857028Ssklower int llcl_S_flag; 27957028Ssklower int llcl_DATA_flag; 28057028Ssklower int llcl_REMOTE_BUSY_flag; 28157028Ssklower int llcl_DACTION_flag; /* delayed action */ 28257028Ssklower int llcl_retry; 28357028Ssklower /* 28457028Ssklower * The following components deal --- in one way or the other --- 28557028Ssklower * with the LLC2 window. Indicated by either [L] or [W] is the 28657028Ssklower * domain of the specific component: 28757028Ssklower * 28857028Ssklower * [L] The domain is 0--LLC_MAX_WINDOW 28957028Ssklower * [W] The domain is 0--llcl_window 29057028Ssklower */ 29157028Ssklower short llcl_vr; /* next to receive [L] */ 29257028Ssklower short llcl_vs; /* next to send [L] */ 29357028Ssklower short llcl_nr_received; /* next frame to b ack'd [L] */ 29457028Ssklower short llcl_freeslot; /* next free slot [W] */ 29557028Ssklower short llcl_projvs; /* V(S) associated with freeslot */ 29657028Ssklower short llcl_slotsfree; /* free slots [W] */ 29757028Ssklower short llcl_window; /* window size */ 29857028Ssklower /* 29957028Ssklower * In llcl_frmrinfo we jot down the last frmr info field, which we 30057028Ssklower * need to do as we need to be able to resend it in the ERROR state. 30157028Ssklower */ 30257028Ssklower struct frmrinfo llcl_frmrinfo; /* last FRMR info field */ 30357028Ssklower }; 30457028Ssklower #define llcl_frmr_pdu0 llcl_frmrinfo.rej_pdu_0 30557028Ssklower #define llcl_frmr_pdu1 llcl_frmrinfo.rej_pdu_1 30657028Ssklower #define llcl_frmr_control llcl_frmrinfo.frmr_control 30757028Ssklower #define llcl_frmr_control_ext llcl_frmrinfo.frmr_control_ext 30857028Ssklower #define llcl_frmr_cause llcl_frmrinfo.frmr_cause 30957028Ssklower 31057028Ssklower #define LQNEXT(l) (struct llc_linkcb *)((l)->llcl_q.q_forw) 31157028Ssklower #define LQEMPTY (llccb_q.q_forw == &llccb_q) 31257028Ssklower #define LQFIRST (struct llc_linkcb *)(llccb_q.q_forw) 31357028Ssklower #define LQVALID(l) (!((struct llccb_q *)(l) == &llccb_q)) 31457028Ssklower 31557028Ssklower #define LLC_ENQUEUE(l, m) if ((l)->llcl_writeqh == NULL) { \ 31657028Ssklower (l)->llcl_writeqh = (m); \ 31757028Ssklower (l)->llcl_writeqt = (m); \ 31857028Ssklower } else { \ 31957028Ssklower (l)->llcl_writeqt->m_nextpkt = (m); \ 32057028Ssklower (l)->llcl_writeqt = (m); \ 32157028Ssklower } 32257028Ssklower 32357028Ssklower #define LLC_DEQUEUE(l, m) if ((l)->llcl_writeqh == NULL) \ 32457028Ssklower (m) = NULL; \ 32557028Ssklower else { \ 32657028Ssklower (m) = (l)->llcl_writeqh; \ 32757028Ssklower (l)->llcl_writeqh = (l)->llcl_writeqh->m_nextpkt; \ 32857028Ssklower } 32957028Ssklower 33057028Ssklower #define LLC_SETFRAME(l, m) { \ 33157028Ssklower if ((l)->llcl_slotsfree > 0) { \ 33257028Ssklower (l)->llcl_slotsfree--; \ 33357028Ssklower (l)->llcl_output_buffers[(l)->llcl_freeslot] = (m); \ 33457028Ssklower (l)->llcl_freeslot = ((l)->llcl_freeslot+1) % (l)->llcl_window; \ 33557028Ssklower LLC_INC((l)->llcl_projvs); \ 33657028Ssklower } \ 33757028Ssklower } 33857028Ssklower 33957028Ssklower /* 34057028Ssklower * handling of sockaddr_dl's 34157028Ssklower */ 34257028Ssklower 34357028Ssklower #define LLADDRLEN(s) ((s)->sdl_alen + (s)->sdl_nlen) 34457028Ssklower #define LLSAPADDR(s) ((s)->sdl_data[LLADDRLEN(s)-1] & 0xff) 34557028Ssklower #define LLSAPLOC(s, if) ((s)->sdl_nlen + (if)->if_addrlen) 34657028Ssklower 34757028Ssklower struct sdl_hdr { 34857028Ssklower struct sockaddr_dl sdlhdr_dst; 34957028Ssklower struct sockaddr_dl sdlhdr_src; 35057028Ssklower long sdlhdr_len; 35157028Ssklower }; 35257028Ssklower 35357028Ssklower #define LLC_GETHDR(f,m) { \ 35457028Ssklower struct mbuf *_m = (struct mbuf *) (m); \ 35557028Ssklower if (_m) { \ 35657028Ssklower M_PREPEND(_m, LLC_ISFRAMELEN, M_DONTWAIT); \ 35757028Ssklower bzero(mtod(_m, caddr_t), LLC_ISFRAMELEN); \ 35857028Ssklower } else { \ 35957028Ssklower MGETHDR (_m, M_DONTWAIT, MT_HEADER); \ 36057028Ssklower if (_m != NULL) { \ 36157028Ssklower _m->m_pkthdr.len = _m->m_len = LLC_UFRAMELEN; \ 36257028Ssklower _m->m_next = _m->m_act = NULL; \ 36357028Ssklower bzero(mtod(_m, caddr_t), LLC_UFRAMELEN); \ 36457028Ssklower } else return; \ 36557028Ssklower } \ 36657028Ssklower (m) = _m; \ 36757028Ssklower (f) = mtod(m, struct llc *); \ 36857028Ssklower } 36957028Ssklower 37057028Ssklower #define LLC_NEWSTATE(l, LLCstate) (l)->llcl_statehandler = llc_state_##LLCstate 37157028Ssklower #define LLC_STATEEQ(l, LLCstate) ((l)->llcl_statehandler == llc_state_##LLCstate ? 1 : 0) 37257028Ssklower 37357028Ssklower #define LLC_ACK_SHIFT 0 37457028Ssklower #define LLC_P_SHIFT 1 37557028Ssklower #define LLC_BUSY_SHIFT 2 37657028Ssklower #define LLC_REJ_SHIFT 3 37757028Ssklower #define LLC_AGE_SHIFT 4 37857028Ssklower #define LLC_DACTION_SHIFT 5 37957028Ssklower 38057028Ssklower #define LLC_TIMER_NOTRUNNING 0 38157028Ssklower #define LLC_TIMER_RUNNING 1 38257028Ssklower #define LLC_TIMER_EXPIRED 2 38357028Ssklower 38457028Ssklower #define LLC_STARTTIMER(l, LLCtimer) { \ 38557028Ssklower (l)->llcl_timers[LLC_##LLCtimer##_SHIFT] = llc_##LLCtimer##_timer; \ 38657028Ssklower (l)->llcl_timerflags |= (1<<LLC_##LLCtimer##_SHIFT); \ 38757028Ssklower } 38857028Ssklower #define LLC_STOPTIMER(l, LLCtimer) { \ 38957028Ssklower (l)->llcl_timers[LLC_##LLCtimer##_SHIFT] = 0; \ 39057028Ssklower (l)->llcl_timerflags &= ~(1<<LLC_##LLCtimer##_SHIFT); \ 39157028Ssklower } 39257028Ssklower #define LLC_AGETIMER(l, LLCtimer) if ((l)->llcl_timers[LLC_##LLCtimer##_SHIFT] > 0) \ 39357028Ssklower (l)->llcl_timers[LLC_##LLCtimer##_SHIFT]--; 39457028Ssklower 39557028Ssklower #define LLC_TIMERXPIRED(l, LLCtimer) \ 39657028Ssklower (((l)->llcl_timerflags & (1<<LLC_##LLCtimer##_SHIFT)) ? \ 39757028Ssklower (((l)->llcl_timers[LLC_##LLCtimer##_SHIFT] == 0 ) ? \ 39857028Ssklower LLC_TIMER_EXPIRED : LLC_TIMER_RUNNING) : LLC_TIMER_NOTRUNNING) 39957028Ssklower 40057028Ssklower #define FOR_ALL_LLC_TIMERS(t) for ((t) = LLC_ACK_SHIFT; (t) < LLC_AGE_SHIFT; (t)++) 40157028Ssklower 40257028Ssklower #define LLC_SETFLAG(l, LLCflag, v) (l)->llcl_##LLCflag##_flag = (v) 40357028Ssklower #define LLC_GETFLAG(l, LLCflag) (l)->llcl_##LLCflag##_flag 40457028Ssklower 40557028Ssklower #define LLC_RESETCOUNTER(l) { \ 40657028Ssklower (l)->llcl_vs = (l)->llcl_vr = (l)->llcl_retry = 0; \ 40757028Ssklower llc_resetwindow((l)); \ 40857028Ssklower } 40957028Ssklower 41057028Ssklower /* 41157028Ssklower * LLC2 macro definitions 41257028Ssklower */ 41357028Ssklower 41457028Ssklower 41557028Ssklower #define LLC_START_ACK_TIMER(l) LLC_STARTTIMER((l), ACK) 41657028Ssklower #define LLC_STOP_ACK_TIMER(l) LLC_STOPTIMER((l), ACK) 41757028Ssklower #define LLC_START_REJ_TIMER(l) LLC_STARTTIMER((l), REJ) 41857028Ssklower #define LLC_STOP_REJ_TIMER(l) LLC_STOPTIMER((l), REJ) 41957028Ssklower #define LLC_START_P_TIMER(l) { \ 42057028Ssklower LLC_STARTTIMER((l), P); \ 42157028Ssklower if (LLC_GETFLAG((l), P) == 0) \ 42257028Ssklower (l)->llcl_retry = 0; \ 42357028Ssklower LLC_SETFLAG((l), P, 1); \ 42457028Ssklower } 42557028Ssklower #define LLC_STOP_P_TIMER(l) { \ 42657028Ssklower LLC_STOPTIMER((l), P); \ 42757028Ssklower LLC_SETFLAG((l), P, 0); \ 42857028Ssklower } 42957028Ssklower #define LLC_STOP_ALL_TIMERS(l) { \ 43057028Ssklower LLC_STOPTIMER((l), ACK); \ 43157028Ssklower LLC_STOPTIMER((l), REJ); \ 43257028Ssklower LLC_STOPTIMER((l), BUSY); \ 43357028Ssklower LLC_STOPTIMER((l), P); \ 43457028Ssklower } 43557028Ssklower 43657028Ssklower 43757028Ssklower #define LLC_INC(i) (i) = ((i)+1) % LLC_MAX_SEQUENCE 43857028Ssklower 43957028Ssklower #define LLC_NR_VALID(l, nr) ((l)->llcl_vs < (l)->llcl_nr_received ? \ 44057028Ssklower (((nr) >= (l)->llcl_nr_received) || \ 44157028Ssklower ((nr) <= (l)->llcl_vs) ? 1 : 0) : \ 44257028Ssklower (((nr) <= (l)->llcl_vs) && \ 44357028Ssklower ((nr) >= (l)->llcl_nr_received) ? 1 : 0)) 44457028Ssklower 44557028Ssklower #define LLC_UPDATE_P_FLAG(l, cr, pf) { \ 44657028Ssklower if ((cr) == LLC_RSP && (pf) == 1) { \ 44757028Ssklower LLC_SETFLAG((l), P, 0); \ 44857028Ssklower LLC_STOPTIMER((l), P); \ 44957028Ssklower } \ 45057028Ssklower } 45157028Ssklower 45257028Ssklower #define LLC_UPDATE_NR_RECEIVED(l, nr) { \ 45357028Ssklower while ((l)->llcl_nr_received != (nr)) { \ 45457028Ssklower struct mbuf *_m; \ 45557028Ssklower register short seq; \ 45657028Ssklower if (_m = (l)->llcl_output_buffers[seq = llc_seq2slot((l), (l)->llcl_nr_received)]) \ 45757028Ssklower m_freem(_m); \ 45857028Ssklower (l)->llcl_output_buffers[seq] = NULL; \ 45957028Ssklower LLC_INC((l)->llcl_nr_received); \ 46057028Ssklower (l)->llcl_slotsfree++; \ 46157028Ssklower } \ 46257028Ssklower (l)->llcl_retry = 0; \ 46357028Ssklower if ((l)->llcl_slotsfree < (l)->llcl_window) { \ 46457028Ssklower LLC_START_ACK_TIMER(l); \ 46557028Ssklower } else LLC_STOP_ACK_TIMER(l); \ 46657028Ssklower LLC_STARTTIMER((l), DACTION); \ 46757028Ssklower } 46857028Ssklower 46957028Ssklower #define LLC_SET_REMOTE_BUSY(l,a) { \ 47057028Ssklower if (LLC_GETFLAG((l), REMOTE_BUSY) == 0) { \ 47157028Ssklower LLC_SETFLAG((l), REMOTE_BUSY, 1); \ 47257028Ssklower LLC_STARTTIMER((l), BUSY); \ 47357028Ssklower (a) = LLC_REMOTE_BUSY; \ 47457028Ssklower } else { \ 47557028Ssklower (a) = 0; \ 47657028Ssklower } \ 47757028Ssklower } 47857028Ssklower #define LLC_CLEAR_REMOTE_BUSY(l,a) { \ 47957028Ssklower if (LLC_GETFLAG((l), REMOTE_BUSY) == 1) { \ 48057028Ssklower LLC_SETFLAG((l), REMOTE_BUSY, 1); \ 48157028Ssklower LLC_STOPTIMER((l), BUSY); \ 48257028Ssklower if (LLC_STATEEQ((l), NORMAL) || \ 48357028Ssklower LLC_STATEEQ((l), REJECT) || \ 48457028Ssklower LLC_STATEEQ((l), BUSY)) \ 48557028Ssklower llc_resend((l), LLC_CMD, 0); \ 48657028Ssklower (a) = LLC_REMOTE_NOT_BUSY; \ 48757028Ssklower } else { \ 48857028Ssklower (a) = 0; \ 48957028Ssklower } \ 49057028Ssklower } 49157028Ssklower 49257028Ssklower #define LLC_DACKCMD 0x1 49357028Ssklower #define LLC_DACKCMDPOLL 0x2 49457028Ssklower #define LLC_DACKRSP 0x3 49557028Ssklower #define LLC_DACKRSPFINAL 0x4 49657028Ssklower 49757028Ssklower #define LLC_SENDACKNOWLEDGE(l, cmd, pf) { \ 49857028Ssklower if ((cmd) == LLC_CMD) { \ 49957028Ssklower LLC_SETFLAG((l), DACTION, ((pf) == 0 ? LLC_DACKCMD : LLC_DACKCMDPOLL)); \ 50057028Ssklower } else { \ 50157028Ssklower LLC_SETFLAG((l), DACTION, ((pf) == 0 ? LLC_DACKRSP : LLC_DACKRSPFINAL)); \ 50257028Ssklower } \ 50357028Ssklower } 50457028Ssklower 50557028Ssklower #define LLC_FRMR_W (1<<0) 50657028Ssklower #define LLC_FRMR_X (1<<1) 50757028Ssklower #define LLC_FRMR_Y (1<<2) 50857028Ssklower #define LLC_FRMR_Z (1<<3) 50957028Ssklower #define LLC_FRMR_V (1<<4) 51057028Ssklower 51157028Ssklower #define LLC_SETFRMR(l, f, cr, c) { \ 51257028Ssklower if ((f)->llc_control & 0x3) { \ 51357028Ssklower (l)->llcl_frmr_pdu0 = (f)->llc_control; \ 51457028Ssklower (l)->llcl_frmr_pdu1 = 0; \ 51557028Ssklower } else { \ 51657028Ssklower (l)->llcl_frmr_pdu0 = (f)->llc_control; \ 51757028Ssklower (l)->llcl_frmr_pdu1 = (f)->llc_control_ext; \ 51857028Ssklower } \ 51957028Ssklower LLCCSBITS((l)->llcl_frmr_control, f_vs, (l)->llcl_vs); \ 52057028Ssklower LLCCSBITS((l)->llcl_frmr_control_ext, f_cr, (cr)); \ 52157028Ssklower LLCSBITS((l)->llcl_frmr_control_ext, f_vr, (l)->llcl_vr); \ 52257028Ssklower LLCCSBITS((l)->llcl_frmr_cause, f_wxyzv, (c)); \ 52357028Ssklower } 52457028Ssklower 52557028Ssklower /* 52657028Ssklower * LLC tracing levels: 52757028Ssklower * LLCTR_INTERESTING interesting event, we might care to know about 52857028Ssklower * it, but then again, we might not ... 52957028Ssklower * LLCTR_SHOULDKNOW we probably should know about this event 53057028Ssklower * LLCTR_URGENT something has gone utterly wrong ... 53157028Ssklower */ 53257028Ssklower #define LLCTR_INTERESTING 1 53357028Ssklower #define LLCTR_SHOULDKNOW 2 53457028Ssklower #define LLCTR_URGENT 3 53557028Ssklower 53657028Ssklower #ifdef LLCDEBUG 53757028Ssklower #define LLC_TRACE(lp, l, msg) llc_trace((lp), (l), (msg)) 53857028Ssklower #else /* LLCDEBUG */ 53957028Ssklower #define LLC_TRACE(lp, l, msg) /* NOOP */ 54057028Ssklower #endif /* LLCDEBUG */ 54157028Ssklower 54257028Ssklower #define LLC_N2_VALUE 15 /* up to 15 retries */ 54357028Ssklower #define LLC_ACK_TIMER 10 /* 5 secs */ 54457028Ssklower #define LLC_P_TIMER 4 /* 2 secs */ 54557028Ssklower #define LLC_BUSY_TIMER 12 /* 6 secs */ 54657028Ssklower #define LLC_REJ_TIMER 12 /* 6 secs */ 54757028Ssklower #define LLC_AGE_TIMER 40 /* 20 secs */ 54857028Ssklower #define LLC_DACTION_TIMER 2 /* 1 secs */ 54957028Ssklower 55057028Ssklower #if defined (KERNEL) && defined(LLC) 55157028Ssklower extern int llc_n2; 55257028Ssklower extern int llc_ACK_timer; 55357028Ssklower extern int llc_P_timer; 55457028Ssklower extern int llc_REJ_timer; 55557028Ssklower extern int llc_BUSY_timer; 55657028Ssklower extern int llc_AGE_timer; 55757028Ssklower extern int llc_DACTION_timer; 55857028Ssklower 55958150Sdkhusema extern int af_link_rts_init_done; 56058150Sdkhusema 56158150Sdkhusema #define USES_AF_LINK_RTS { \ 56258150Sdkhusema if (!af_link_rts_init_done) { \ 56358150Sdkhusema rn_inithead((void **)&rt_tables[AF_LINK], 32); \ 56458150Sdkhusema af_link_rts_init_done++; \ 56558150Sdkhusema } \ 56658150Sdkhusema } 56758150Sdkhusema 56857028Ssklower struct ifqueue llcintrq; 56957028Ssklower 57057028Ssklower extern struct llccb_q llccb_q; 57157028Ssklower extern char *frame_names[]; 57257028Ssklower 57357028Ssklower /* 57457028Ssklower * Function prototypes 57557028Ssklower */ 57657028Ssklower int sdl_cmp __P((struct sockaddr_dl *, struct sockaddr_dl *)); 57757028Ssklower int sdl_copy __P((struct sockaddr_dl *, struct sockaddr_dl *)); 57857028Ssklower int sdl_swapaddr __P((struct sockaddr_dl *, struct sockaddr_dl *)); 57957028Ssklower int sdl_checkaddrif __P((struct ifnet *, struct sockaddr_dl *)); 58057028Ssklower int sdl_setaddrif __P((struct ifnet *, u_char *, u_char, u_char, 58157028Ssklower struct sockaddr_dl *)); 58257028Ssklower int sdl_sethdrif __P((struct ifnet *, u_char *, u_char, u_char *, u_char, u_char, 58357028Ssklower struct sdl_hdr *)); 58457028Ssklower struct npaidbentry *llc_setsapinfo __P((struct ifnet *, u_char, u_char, 58557028Ssklower struct dllconfig *)); 58657028Ssklower struct npaidbentry *llc_getsapinfo __P((u_char, struct ifnet *)); 58757028Ssklower struct rtentry *npaidb_enrich __P((short, caddr_t, struct sockaddr_dl *)); 58857028Ssklower int npaidb_destroy __P((struct rtentry *)); 58957028Ssklower short llc_seq2slot __P((struct llc_linkcb *, short)); 59057028Ssklower int llc_state_ADM __P((struct llc_linkcb *, struct llc *, int, int, int)); 59157028Ssklower int llc_state_CONN __P((struct llc_linkcb *, struct llc *, int, int, int)); 59257028Ssklower int llc_state_RESET_WAIT __P((struct llc_linkcb *, struct llc *, 59357028Ssklower int, int, int)); 59457028Ssklower int llc_state_RESET_CHECK __P((struct llc_linkcb *, struct llc *, 59557028Ssklower int, int, int)); 59657028Ssklower int llc_state_SETUP __P((struct llc_linkcb *, struct llc *, int, int, int)); 59757028Ssklower int llc_state_RESET __P((struct llc_linkcb *, struct llc *, int, int, int)); 59857028Ssklower int llc_state_D_CONN __P((struct llc_linkcb *, struct llc *, int, int, int)); 59957028Ssklower int llc_state_ERROR __P((struct llc_linkcb *, struct llc *, int, int, int)); 60057028Ssklower int llc_state_NBRAcore __P((struct llc_linkcb *, struct llc *, int, int, int)); 60157028Ssklower int llc_state_NORMAL __P((struct llc_linkcb *, struct llc *, int, int, int)); 60257028Ssklower int llc_state_BUSY __P((struct llc_linkcb *, struct llc *, int, int, int)); 60357028Ssklower int llc_state_REJECT __P((struct llc_linkcb *, struct llc *, int, int, int)); 60457028Ssklower int llc_state_AWAIT __P((struct llc_linkcb *, struct llc *, int, int, int)); 60557028Ssklower int llc_state_AWAIT_BUSY __P((struct llc_linkcb *, struct llc *, int, int, int)); 60657028Ssklower int llc_state_AWAIT_REJECT __P((struct llc_linkcb *, struct llc *, int, int, int)); 60757028Ssklower int llc_statehandler __P((struct llc_linkcb *, struct llc *, int, int, int)); 60857028Ssklower int llc_init __P((void)); 60957028Ssklower struct llc_linkcb *llc_newlink __P((struct sockaddr_dl *, struct ifnet *, 61057028Ssklower struct rtentry *, caddr_t, struct rtentry *)); 61157028Ssklower int llc_dellink __P((struct llc_linkcb *)); 61257028Ssklower int llc_anytimersup __P((struct llc_linkcb *)); 61357028Ssklower char * llc_getstatename __P((struct llc_linkcb *)); 61457028Ssklower void llc_link_dump __P((struct llc_linkcb *, const char *)); 61557028Ssklower void llc_trace __P((struct llc_linkcb *, int, const char *)); 61657028Ssklower void llc_resetwindow __P((struct llc_linkcb *)); 61757028Ssklower int llc_decode __P((struct llc *, struct llc_linkcb *)); 61857028Ssklower void llc_timer __P((void)); 61957028Ssklower void llcintr __P((void)); 62057028Ssklower int llc_input __P((struct llc_linkcb *, struct mbuf *, u_char)); 62157028Ssklower caddr_t llc_ctlinput __P((int, struct sockaddr *, caddr_t)); 62257028Ssklower int llc_output __P((struct llc_linkcb *, struct mbuf *)); 62357028Ssklower void llc_start __P((struct llc_linkcb *)); 62457028Ssklower int llc_send __P((struct llc_linkcb *, int, int, int)); 62557028Ssklower int llc_resend __P((struct llc_linkcb *, int, int)); 62657028Ssklower int llc_rawsend __P((struct llc_linkcb *, struct mbuf *, struct llc *, int, int, 62757028Ssklower int, int)); 628*68257Scgd void cons_rtrequest __P((int, struct rtentry *, struct sockaddr *)); 62957028Ssklower int x25_llcglue __P((int, struct sockaddr *)); 63057028Ssklower 63157028Ssklower #endif 63257028Ssklower 63357028Ssklower 634