Centralize if queue handling.
[dragonfly.git] / sys / netproto / atm / atm_stack.h
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
8  * This Host ATM Research Platform ("HARP") file (the "Software") is
9  * made available by Network Computing Services, Inc. ("NetworkCS")
10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
11  * support of any kind.
12  *
13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17  * In no event shall NetworkCS be responsible for any damages, including
18  * but not limited to consequential damages, arising from or relating to
19  * any use of the Software or related support.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD: src/sys/netatm/atm_stack.h,v 1.2 1999/08/28 00:48:38 peter Exp $
27  *      @(#) $DragonFly: src/sys/netproto/atm/atm_stack.h,v 1.3 2003/08/23 10:06:21 rob Exp $
28  *
29  */
30
31 /*
32  * Core ATM Services
33  * -----------------
34  *
35  * ATM Stack definitions
36  *
37  */
38
39 #ifndef _NETATM_ATM_STACK_H
40 #define _NETATM_ATM_STACK_H
41
42 #ifdef ATM_KERNEL
43 /*
44  * Structure used to define a kernel-provided ATM stack service and its
45  * associated entry points.  Each stack service provider must register
46  * themselves before they will be used.  ATM stack service providers include 
47  * kernel modules (both linked and loaded) and device drivers, which must list
48  * (via its atm_pif) any of its available hardware-supplied stack services 
49  * (such as on-card AAL processing).
50  */
51 struct stack_defn {
52         struct stack_defn *sd_next;     /* Next in registry list */
53         Sap_t           sd_sap;         /* Stack instance SAP */
54         u_char          sd_flag;        /* Flags (see below) */
55 /* Exported functions */
56         int             (*sd_inst)      /* Stack instantiation */
57                                 (struct stack_defn **, Atm_connvc *);
58         void            (*sd_lower)     /* Lower (from above) command handler */
59                                 (int, void *, int, int);
60         void            (*sd_upper)     /* Upper (from below) command handler */
61                                 (int, void *, int, int);
62 /* Variables used during stack instantiation */
63         void            *sd_toku;       /* Stack service instance token */
64 };
65
66 /*
67  * Stack Service Flags
68  */
69 #define SDF_TERM        0x01            /* Terminal (to lowest layer) service */
70
71
72 /*
73  * Stack Specification List  
74  *
75  * The list names the stack services and their layering relationships in
76  * order to construct a stack to provide the protocol services defined
77  * by the list.  The list is ordered starting from the stack service 
78  * interfacing with the user "down" to the ATM cell service.
79  */
80 #define STACK_CNT       8               /* Max services in a stack list */
81 struct stack_list {
82         Sap_t           sl_sap[STACK_CNT];      /* Stack service SAP list */
83 };
84
85
86 /*
87  * Structure used during the construction and instantiation of a stack 
88  * instance from a supplied stack list.  It contains pointers to the stack 
89  * service definitions which will be used to implement the stack.  The first 
90  * element in the array is reserved for the user's "stack service".
91  */
92 struct stack_inst {
93         struct stack_defn *si_srvc[STACK_CNT+1];        /* Assigned services */
94 };
95
96
97 /*
98  * Macros to update buffer headroom values during stack instantiation.
99  *
100  * These values are advisory, i.e. every service must verify the amount
101  * of available space in input/output messages and allocate new buffers
102  * if needed.
103  *
104  * The 'maximum' and 'minimum' values used below may be chosen by a 
105  * service to reflect the typical, expected message traffic pattern 
106  * for a specific connection.
107  * 
108  * The macro arguments are:
109  *      cvp = pointer to connection vcc;
110  *      hi = maximum amount of buffer headroom required by the current
111  *           service during input message processing;
112  *      si = minimum amount of buffer data stripped off the front 
113  *           of an input message by the current service;
114  *      ho = maximum amount of buffer headroom required by the current
115  *           service during output message processing;
116  *      ao = maximum amount of buffer data added to the front 
117  *           of an output message by the current service;
118  */
119 #define HEADIN(cvp, hi, si)                                     \
120 {                                                               \
121         short   t = (cvp)->cvc_attr.headin - (si);              \
122         t = (t >= (hi)) ? t : (hi);                             \
123         (cvp)->cvc_attr.headin = roundup(t, sizeof(long));      \
124 }
125
126 #define HEADOUT(cvp, ho, ao)                                    \
127 {                                                               \
128         short   t = (cvp)->cvc_attr.headout + (ao);             \
129         t = (t >= (ho)) ? t : (ho);                             \
130         (cvp)->cvc_attr.headout = roundup(t, sizeof(long));     \
131 }
132
133
134 /*
135  * Stack command codes - All stack command codes are specific to the 
136  * defined stack SAP across which the command is used.  Command values 0-15 
137  * are reserved for any common codes, which all stack SAPs must support.
138  */
139 #define STKCMD(s, d, v) (((s) << 16) | (d) | (v))
140 #define STKCMD_DOWN     0
141 #define STKCMD_UP       0x00008000
142 #define STKCMD_SAP_MASK 0xffff0000
143 #define STKCMD_VAL_MASK 0x00007fff
144
145 /* Common command values (0-15) */
146 #define CCV_INIT        1               /* DOWN */
147 #define CCV_TERM        2               /* DOWN */
148
149 /* SAP_ATM */
150 #define ATM_INIT                STKCMD(SAP_ATM, STKCMD_DOWN, CCV_INIT)
151 #define ATM_TERM                STKCMD(SAP_ATM, STKCMD_DOWN, CCV_TERM)
152 #define ATM_DATA_REQ            STKCMD(SAP_ATM, STKCMD_DOWN, 16)
153 #define ATM_DATA_IND            STKCMD(SAP_ATM, STKCMD_UP, 17)
154
155 /* SAP_SAR */
156 #define SAR_INIT                STKCMD(SAP_SAR, STKCMD_DOWN, CCV_INIT)
157 #define SAR_TERM                STKCMD(SAP_SAR, STKCMD_DOWN, CCV_TERM)
158 #define SAR_UNITDATA_INV        STKCMD(SAP_SAR, STKCMD_DOWN, 16)
159 #define SAR_UNITDATA_SIG        STKCMD(SAP_SAR, STKCMD_UP, 17)
160 #define SAR_UABORT_INV          STKCMD(SAP_SAR, STKCMD_DOWN, 18)
161 #define SAR_UABORT_SIG          STKCMD(SAP_SAR, STKCMD_UP, 19)
162 #define SAR_PABORT_SIG          STKCMD(SAP_SAR, STKCMD_UP, 20)
163
164 /* SAP_CPCS */
165 #define CPCS_INIT               STKCMD(SAP_CPCS, STKCMD_DOWN, CCV_INIT)
166 #define CPCS_TERM               STKCMD(SAP_CPCS, STKCMD_DOWN, CCV_TERM)
167 #define CPCS_UNITDATA_INV       STKCMD(SAP_CPCS, STKCMD_DOWN, 16)
168 #define CPCS_UNITDATA_SIG       STKCMD(SAP_CPCS, STKCMD_UP, 17)
169 #define CPCS_UABORT_INV         STKCMD(SAP_CPCS, STKCMD_DOWN, 18)
170 #define CPCS_UABORT_SIG         STKCMD(SAP_CPCS, STKCMD_UP, 19)
171 #define CPCS_PABORT_SIG         STKCMD(SAP_CPCS, STKCMD_UP, 20)
172
173 /* SAP_SSCOP */
174 #define SSCOP_INIT              STKCMD(SAP_SSCOP, STKCMD_DOWN, CCV_INIT)
175 #define SSCOP_TERM              STKCMD(SAP_SSCOP, STKCMD_DOWN, CCV_TERM)
176 #define SSCOP_ESTABLISH_REQ     STKCMD(SAP_SSCOP, STKCMD_DOWN, 16)
177 #define SSCOP_ESTABLISH_IND     STKCMD(SAP_SSCOP, STKCMD_UP, 17)
178 #define SSCOP_ESTABLISH_RSP     STKCMD(SAP_SSCOP, STKCMD_DOWN, 18)
179 #define SSCOP_ESTABLISH_CNF     STKCMD(SAP_SSCOP, STKCMD_UP, 19)
180 #define SSCOP_RELEASE_REQ       STKCMD(SAP_SSCOP, STKCMD_DOWN, 20)
181 #define SSCOP_RELEASE_IND       STKCMD(SAP_SSCOP, STKCMD_UP, 21)
182 #define SSCOP_RELEASE_CNF       STKCMD(SAP_SSCOP, STKCMD_UP, 22)
183 #define SSCOP_DATA_REQ          STKCMD(SAP_SSCOP, STKCMD_DOWN, 23)
184 #define SSCOP_DATA_IND          STKCMD(SAP_SSCOP, STKCMD_UP, 24)
185 #define SSCOP_RESYNC_REQ        STKCMD(SAP_SSCOP, STKCMD_DOWN, 25)
186 #define SSCOP_RESYNC_IND        STKCMD(SAP_SSCOP, STKCMD_UP, 26)
187 #define SSCOP_RESYNC_RSP        STKCMD(SAP_SSCOP, STKCMD_DOWN, 27)
188 #define SSCOP_RESYNC_CNF        STKCMD(SAP_SSCOP, STKCMD_UP, 28)
189 #define SSCOP_RECOVER_IND       STKCMD(SAP_SSCOP, STKCMD_UP, 29)
190 #define SSCOP_RECOVER_RSP       STKCMD(SAP_SSCOP, STKCMD_DOWN, 30)
191 #define SSCOP_UNITDATA_REQ      STKCMD(SAP_SSCOP, STKCMD_DOWN, 31)
192 #define SSCOP_UNITDATA_IND      STKCMD(SAP_SSCOP, STKCMD_UP, 32)
193 #define SSCOP_RETRIEVE_REQ      STKCMD(SAP_SSCOP, STKCMD_DOWN, 33)
194 #define SSCOP_RETRIEVE_IND      STKCMD(SAP_SSCOP, STKCMD_UP, 34)
195 #define SSCOP_RETRIEVECMP_IND   STKCMD(SAP_SSCOP, STKCMD_UP, 35)
196
197 /* SAP_SSCF_UNI */
198 #define SSCF_UNI_INIT           STKCMD(SAP_SSCF_UNI, STKCMD_DOWN, CCV_INIT)
199 #define SSCF_UNI_TERM           STKCMD(SAP_SSCF_UNI, STKCMD_DOWN, CCV_TERM)
200 #define SSCF_UNI_ESTABLISH_REQ  STKCMD(SAP_SSCF_UNI, STKCMD_DOWN, 16)
201 #define SSCF_UNI_ESTABLISH_IND  STKCMD(SAP_SSCF_UNI, STKCMD_UP, 17)
202 #define SSCF_UNI_ESTABLISH_CNF  STKCMD(SAP_SSCF_UNI, STKCMD_UP, 18)
203 #define SSCF_UNI_RELEASE_REQ    STKCMD(SAP_SSCF_UNI, STKCMD_DOWN, 19)
204 #define SSCF_UNI_RELEASE_IND    STKCMD(SAP_SSCF_UNI, STKCMD_UP, 20)
205 #define SSCF_UNI_RELEASE_CNF    STKCMD(SAP_SSCF_UNI, STKCMD_UP, 21)
206 #define SSCF_UNI_DATA_REQ       STKCMD(SAP_SSCF_UNI, STKCMD_DOWN, 22)
207 #define SSCF_UNI_DATA_IND       STKCMD(SAP_SSCF_UNI, STKCMD_UP, 23)
208 #define SSCF_UNI_UNITDATA_REQ   STKCMD(SAP_SSCF_UNI, STKCMD_DOWN, 24)
209 #define SSCF_UNI_UNITDATA_IND   STKCMD(SAP_SSCF_UNI, STKCMD_UP, 25)
210
211
212 /*
213  * The STACK_CALL macro must be used for all stack calls between adjacent
214  * entities.  In order to avoid the problem with recursive stack calls 
215  * modifying protocol state, this macro will only allow calls to proceed if 
216  * they are not "against the flow" of any currently pending calls for a
217  * stack instance.  If the requested call can't be processed now, it will 
218  * be deferred and queued until a later, safe time (but before control is 
219  * returned back to the kernel scheduler) when it will be dispatched.
220  *
221  * The STACK_CALL macro arguments are:
222  *      cmd = command code;
223  *      fn  = Destination entity processing function
224  *      tok = Destination layer's session token;
225  *      cvp = Connection VCC address;
226  *      a1  = command specific argument;
227  *      a2  = command specific argument;
228  *      ret = call result value (0 => success)
229  *
230  * The receiving entity command processing function prototype is:
231  *
232  *      void (fn)(int cmd, int tok, int arg1, int arg2)
233  *
234  */
235 #define STACK_CALL(cmd, fn, tok, cvp, a1, a2, ret)                      \
236 {                                                                       \
237         if ((cmd) & STKCMD_UP) {                                        \
238                 if ((cvp)->cvc_downcnt) {                               \
239                         (ret) = atm_stack_enq((cmd), (fn), (tok),       \
240                                                 (cvp), (a1), (a2));     \
241                 } else {                                                \
242                         (cvp)->cvc_upcnt++;                             \
243                         (*fn)(cmd, tok, a1, a2);                        \
244                         (cvp)->cvc_upcnt--;                             \
245                         (ret) = 0;                                      \
246                 }                                                       \
247         } else {                                                        \
248                 if ((cvp)->cvc_upcnt) {                                 \
249                         (ret) = atm_stack_enq((cmd), (fn), (tok),       \
250                                                 (cvp), (a1), (a2));     \
251                 } else {                                                \
252                         (cvp)->cvc_downcnt++;                           \
253                         (*fn)(cmd, tok, a1, a2);                        \
254                         (cvp)->cvc_downcnt--;                           \
255                         (ret) = 0;                                      \
256                 }                                                       \
257         }                                                               \
258 }
259
260
261 /*
262  * Stack queue entry - The stack queue will contain stack calls which have 
263  * been deferred in order to avoid recursive calls to a single protocol 
264  * control block.  The queue entries are allocated from its own storage pool.
265  */
266 struct stackq_entry {
267         struct stackq_entry *sq_next;   /* Next entry in queue */
268         int             sq_cmd;         /* Stack command */
269         void            (*sq_func)      /* Destination function */
270                                 (int, void *, int, int);
271         void            *sq_token;      /* Destination token */
272         int             sq_arg1;        /* Command-specific argument */
273         int             sq_arg2;        /* Command-specific argument */
274         Atm_connvc      *sq_connvc;     /* Connection VCC */
275 };
276
277
278 /*
279  * Macro to avoid unnecessary function call when draining the stack queue.
280  */
281 #define STACK_DRAIN()                                                   \
282 {                                                                       \
283         if (atm_stackq_head)                                            \
284                 atm_stack_drain();                                      \
285 }
286 #endif  /* ATM_KERNEL */
287
288 #endif  /* _NETATM_ATM_STACK_H */