]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i4b/layer2/i4b_l2.c
This commit was generated by cvs2svn to compensate for changes in r61201,
[FreeBSD/FreeBSD.git] / sys / i4b / layer2 / i4b_l2.c
1 /*
2  * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      i4b_l2.c - ISDN layer 2 (Q.921)
28  *      -------------------------------
29  *
30  *      $Id: i4b_l2.c,v 1.30 1999/12/13 21:25:27 hm Exp $ 
31  *
32  * $FreeBSD$
33  *
34  *      last edit-date: [Mon Dec 13 22:03:23 1999]
35  *
36  *---------------------------------------------------------------------------*/
37
38 #ifdef __FreeBSD__
39 #include "i4bq921.h"
40 #else
41 #define NI4BQ921        1
42 #endif
43 #if NI4BQ921 > 0
44
45 #include <sys/param.h>
46
47 #if defined(__FreeBSD__)
48 #else
49 #include <sys/ioctl.h>
50 #endif
51
52 #include <sys/systm.h>
53 #include <sys/mbuf.h>
54 #include <sys/socket.h>
55 #include <net/if.h>
56
57 #ifdef __FreeBSD__
58 #include <machine/i4b_debug.h>
59 #include <machine/i4b_ioctl.h>
60 #else
61 #include <i4b/i4b_debug.h>
62 #include <i4b/i4b_ioctl.h>
63 #endif
64
65 #include <i4b/include/i4b_l1l2.h>
66 #include <i4b/include/i4b_l2l3.h>
67 #include <i4b/include/i4b_isdnq931.h>
68 #include <i4b/include/i4b_mbuf.h>
69 #include <i4b/include/i4b_global.h>
70
71 #include <i4b/layer2/i4b_l2.h>
72 #include <i4b/layer2/i4b_l2fsm.h>
73
74 int i4b_dl_establish_ind(int);
75 int i4b_dl_establish_cnf(int);
76 int i4b_dl_release_ind(int);
77 int i4b_dl_release_cnf(int);
78 int i4b_dl_data_ind(int, struct mbuf *);
79 int i4b_dl_unit_data_ind(int, struct mbuf *);
80
81 static int i4b_mdl_command_req(int, int, int);
82
83 /* from layer 2 */
84
85 extern int i4b_mdl_attach_ind(int, int);
86 extern int i4b_mdl_status_ind(int, int, int);
87
88 /* this layers debug level */
89
90 unsigned int i4b_l2_debug = L2_DEBUG_DEFAULT;
91
92 struct i4b_l2l3_func i4b_l2l3_func = {
93
94         /* Layer 2 --> Layer 3 */
95         
96         (int (*)(int))                          i4b_dl_establish_ind,
97         (int (*)(int))                          i4b_dl_establish_cnf,
98         (int (*)(int))                          i4b_dl_release_ind,
99         (int (*)(int))                          i4b_dl_release_cnf,
100         (int (*)(int, struct mbuf *))           i4b_dl_data_ind,
101         (int (*)(int, struct mbuf *))           i4b_dl_unit_data_ind,
102
103         /* Layer 3 --> Layer 2 */
104
105         (int (*)(int))                          i4b_dl_establish_req,
106         (int (*)(int))                          i4b_dl_release_req,
107         (int (*)(int, struct mbuf *))           i4b_dl_data_req,
108         (int (*)(int, struct mbuf *))           i4b_dl_unit_data_req,
109
110         /* Layer 2 --> Layer 3 management */
111         
112         (int (*)(int, int, int))                i4b_mdl_status_ind,
113
114         /* Layer 3  --> Layer 2 management */
115         
116         (int (*)(int, int, int))                i4b_mdl_command_req     
117 };
118
119 /*---------------------------------------------------------------------------*
120  *      DL_ESTABLISH_REQ from layer 3
121  *---------------------------------------------------------------------------*/
122 int i4b_dl_establish_req(int unit)
123 {
124         l2_softc_t *l2sc = &l2_softc[unit];
125         
126         DBGL2(L2_PRIM, "DL-ESTABLISH-REQ", ("unit %d\n",unit));
127         i4b_l1_activate(l2sc);
128         i4b_next_l2state(l2sc, EV_DLESTRQ);
129         return(0);
130 }
131
132 /*---------------------------------------------------------------------------*
133  *      DL_RELEASE_REQ from layer 3
134  *---------------------------------------------------------------------------*/
135 int i4b_dl_release_req(int unit)
136 {
137         l2_softc_t *l2sc = &l2_softc[unit];
138
139         DBGL2(L2_PRIM, "DL-RELEASE-REQ", ("unit %d\n",unit));   
140         i4b_next_l2state(l2sc, EV_DLRELRQ);
141         return(0);      
142 }
143
144 /*---------------------------------------------------------------------------*
145  *      DL UNIT DATA REQUEST from Layer 3
146  *---------------------------------------------------------------------------*/
147 int i4b_dl_unit_data_req(int unit, struct mbuf *m)
148 {
149 #ifdef NOTDEF
150         DBGL2(L2_PRIM, "DL-UNIT-DATA-REQ", ("unit %d\n",unit));
151 #endif
152         return(0);
153 }
154
155 /*---------------------------------------------------------------------------*
156  *      DL DATA REQUEST from Layer 3
157  *---------------------------------------------------------------------------*/
158 int i4b_dl_data_req(int unit, struct mbuf *m)
159 {
160         l2_softc_t *l2sc = &l2_softc[unit];
161
162 #ifdef NOTDEF
163         DBGL2(L2_PRIM, "DL-DATA-REQ", ("unit %d\n",unit));
164 #endif
165         switch(l2sc->Q921_state)
166         {
167                 case ST_AW_EST:
168                 case ST_MULTIFR:
169                 case ST_TIMREC:
170                 
171                         if(IF_QFULL(&l2sc->i_queue))
172                         {
173                                 DBGL2(L2_ERROR, "i4b_dl_data_req", ("i_queue full!!\n"));
174                                 i4b_Dfreembuf(m);
175                         }
176                         else
177                         {
178                                 CRIT_VAR;
179
180                                 CRIT_BEG;
181                                 IF_ENQUEUE(&l2sc->i_queue, m);
182                                 CRIT_END;
183
184                                 i4b_i_frame_queued_up(l2sc);
185                         }
186                         break;
187                         
188                 default:
189                         DBGL2(L2_ERROR, "i4b_dl_data_req", ("unit %d ERROR in state [%s], freeing mbuf\n", unit, i4b_print_l2state(l2sc)));
190                         i4b_Dfreembuf(m);
191                         break;
192         }               
193         return(0);
194 }
195
196 /*---------------------------------------------------------------------------*
197  *      i4b_ph_activate_ind - link activation indication from layer 1
198  *---------------------------------------------------------------------------*/
199 int
200 i4b_ph_activate_ind(int unit)
201 {
202         l2_softc_t *l2sc = &l2_softc[unit];
203
204         DBGL1(L1_PRIM, "PH-ACTIVATE-IND", ("unit %d\n",unit));
205         l2sc->ph_active = PH_ACTIVE;
206         return(0);
207 }
208
209 /*---------------------------------------------------------------------------*
210  *      i4b_ph_deactivate_ind - link deactivation indication from layer 1
211  *---------------------------------------------------------------------------*/
212 int
213 i4b_ph_deactivate_ind(int unit)
214 {
215         l2_softc_t *l2sc = &l2_softc[unit];
216
217         DBGL1(L1_PRIM, "PH-DEACTIVATE-IND", ("unit %d\n",unit));
218         l2sc->ph_active = PH_INACTIVE;
219         return(0);
220 }
221
222
223 /*---------------------------------------------------------------------------*
224  *      i4b_l2_unit_init - place layer 2 unit into known state
225  *---------------------------------------------------------------------------*/
226 static void
227 i4b_l2_unit_init(int unit)
228 {
229         l2_softc_t *l2sc = &l2_softc[unit];
230         CRIT_VAR;
231
232         CRIT_BEG;
233         l2sc->Q921_state = ST_TEI_UNAS;
234         l2sc->tei_valid = TEI_INVALID;
235         l2sc->vr = 0;
236         l2sc->vs = 0;
237         l2sc->va = 0;
238         l2sc->ack_pend = 0;
239         l2sc->rej_excpt = 0;
240         l2sc->peer_busy = 0;
241         l2sc->own_busy = 0;
242         l2sc->l3initiated = 0;
243
244         l2sc->rxd_CR = 0;
245         l2sc->rxd_PF = 0;
246         l2sc->rxd_NR = 0;
247         l2sc->RC = 0;
248         l2sc->iframe_sent = 0;
249                 
250         l2sc->postfsmfunc = NULL;
251
252         if(l2sc->ua_num != UA_EMPTY)
253         {
254                 i4b_Dfreembuf(l2sc->ua_frame);
255                 l2sc->ua_num = UA_EMPTY;
256                 l2sc->ua_frame = NULL;
257         }
258
259         i4b_T200_stop(l2sc);
260         i4b_T202_stop(l2sc);
261         i4b_T203_stop(l2sc);
262
263         CRIT_END;       
264 }
265
266 /*---------------------------------------------------------------------------*
267  *      i4b_mph_status_ind - status indication upward
268  *---------------------------------------------------------------------------*/
269 int
270 i4b_mph_status_ind(int unit, int status, int parm)
271 {
272         l2_softc_t *l2sc = &l2_softc[unit];
273         CRIT_VAR;
274         int sendup = 1;
275         
276         CRIT_BEG;
277
278         DBGL1(L1_PRIM, "MPH-STATUS-IND", ("unit %d, status=%d, parm=%d\n", unit, status, parm));
279
280         switch(status)
281         {
282                 case STI_ATTACH:
283                         l2sc->unit = unit;
284                         l2sc->i_queue.ifq_maxlen = IQUEUE_MAXLEN;
285                         l2sc->ua_frame = NULL;
286                         bzero(&l2sc->stat, sizeof(lapdstat_t));                 
287                         i4b_l2_unit_init(unit);
288                         
289 #if defined(__FreeBSD__)
290                         /* initialize the callout handles for timeout routines */
291                         callout_handle_init(&l2sc->T200_callout);
292                         callout_handle_init(&l2sc->T202_callout);
293                         callout_handle_init(&l2sc->T203_callout);
294                         callout_handle_init(&l2sc->IFQU_callout);
295 #endif
296                         break;
297
298                 case STI_L1STAT:        /* state of layer 1 */
299                         break;
300                 
301                 case STI_PDEACT:        /* Timer 4 expired */
302 /*XXX*/                 if((l2sc->Q921_state >= ST_AW_EST) &&
303                            (l2sc->Q921_state <= ST_TIMREC))
304                         {
305                                 DBGL2(L2_ERROR, "i4b_mph_status_ind", ("unit %d, persistent deactivation!\n", unit));
306                                 i4b_l2_unit_init(unit);
307                         }
308                         else
309                         {
310                                 sendup = 0;
311                         }
312                         break;
313
314                 case STI_NOL1ACC:
315                         i4b_l2_unit_init(unit);
316                         DBGL2(L2_ERROR, "i4b_mph_status_ind", ("unit %d, cannot access S0 bus!\n", unit));
317                         break;
318                         
319                 default:
320                         DBGL2(L2_ERROR, "i4b_mph_status_ind", ("ERROR, unit %d, unknown status message!\n", unit));
321                         break;
322         }
323         
324         if(sendup)
325                 MDL_Status_Ind(unit, status, parm);  /* send up to layer 3 */
326
327         CRIT_END;
328         
329         return(0);
330 }
331
332 /*---------------------------------------------------------------------------*
333  *      MDL_COMMAND_REQ from layer 3
334  *---------------------------------------------------------------------------*/
335 int i4b_mdl_command_req(int unit, int command, int parm)
336 {
337         DBGL2(L2_PRIM, "MDL-COMMAND-REQ", ("unit %d, command=%d, parm=%d\n", unit, command, parm));
338
339         switch(command)
340         {
341                 case CMR_DOPEN:
342                         i4b_l2_unit_init(unit);
343                         break;
344         }               
345
346         MPH_Command_Req(unit, command, parm);
347         
348         return(0);
349 }
350
351 /*---------------------------------------------------------------------------*
352  *      i4b_ph_data_ind - process a rx'd frame got from layer 1
353  *---------------------------------------------------------------------------*/
354 int
355 i4b_ph_data_ind(int unit, struct mbuf *m)
356 {
357         l2_softc_t *l2sc = &l2_softc[unit];
358 #ifdef NOTDEF
359         DBGL1(L1_PRIM, "PH-DATA-IND", ("unit %d\n", unit));
360 #endif
361         u_char *ptr = m->m_data;
362
363         if ( (*(ptr + OFF_CNTL) & 0x01) == 0 )
364         {
365                 if(m->m_len < 4)        /* 6 oct - 2 chksum oct */
366                 {
367                         l2sc->stat.err_rx_len++;
368                         DBGL2(L2_ERROR, "i4b_ph_data_ind", ("ERROR, I-frame < 6 octetts!\n"));
369                         i4b_Dfreembuf(m);
370                         return(0);
371                 }
372                 i4b_rxd_i_frame(unit, m);
373         }
374         else if ( (*(ptr + OFF_CNTL) & 0x03) == 0x01 )
375         {
376                 if(m->m_len < 4)        /* 6 oct - 2 chksum oct */
377                 {
378                         l2sc->stat.err_rx_len++;
379                         DBGL2(L2_ERROR, "i4b_ph_data_ind", ("ERROR, S-frame < 6 octetts!\n"));
380                         i4b_Dfreembuf(m);
381                         return(0);
382                 }
383                 i4b_rxd_s_frame(unit, m);
384         }
385         else if ( (*(ptr + OFF_CNTL) & 0x03) == 0x03 )
386         {
387                 if(m->m_len < 3)        /* 5 oct - 2 chksum oct */
388                 {
389                         l2sc->stat.err_rx_len++;
390                         DBGL2(L2_ERROR, "i4b_ph_data_ind", ("ERROR, U-frame < 5 octetts!\n"));
391                         i4b_Dfreembuf(m);
392                         return(0);
393                 }
394                 i4b_rxd_u_frame(unit, m);
395         }
396         else
397         {
398                 l2sc->stat.err_rx_badf++;
399                 DBGL2(L2_ERROR, "i4b_ph_data_ind", ("ERROR, bad frame rx'd - "));
400                 i4b_print_frame(m->m_len, m->m_data);
401                 i4b_Dfreembuf(m);
402         }
403         return(0);
404 }
405
406 #endif /* NI4BQ921 > 0 */