1 /* $NetBSD: i4b_l2.c,v 1.23 2007/07/09 21:11:14 ad Exp $ */
4 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 *---------------------------------------------------------------------------
29 * i4b_l2.c - ISDN layer 2 (Q.921)
30 * -------------------------------
32 * $Id: i4b_l2.c,v 1.24 2008/07/20 01:05:27 martin Exp $
36 * last edit-date: [Fri Jan 5 11:33:47 2001]
38 *---------------------------------------------------------------------------*/
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: i4b_l2.c,v 1.23 2007/07/09 21:11:14 ad Exp $");
50 #include <sys/param.h>
51 #include <sys/kernel.h>
52 #include <sys/systm.h>
54 #include <sys/socket.h>
57 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
58 #include <sys/callout.h>
62 #include <machine/i4b_debug.h>
63 #include <machine/i4b_ioctl.h>
65 #include <netisdn/i4b_debug.h>
66 #include <netisdn/i4b_ioctl.h>
69 #include <netisdn/i4b_l3l4.h>
70 #include <netisdn/i4b_l2.h>
71 #include <netisdn/i4b_l1l2.h>
72 #include <netisdn/i4b_isdnq931.h>
73 #include <netisdn/i4b_mbuf.h>
74 #include <netisdn/i4b_global.h>
76 #include <netisdn/i4b_l2fsm.h>
78 /* this layers debug level */
80 unsigned int i4b_l2_debug
= L2_DEBUG_DEFAULT
;
82 /*---------------------------------------------------------------------------*
83 * DL_ESTABLISH_REQ from layer 3
84 *---------------------------------------------------------------------------*/
85 int i4b_dl_establish_req(l2_softc_t
*l2sc
, struct isdn_l3_driver
*drv
)
87 NDBGL2(L2_PRIM
, "isdnif %d", l2sc
->drv
->isdnif
);
88 i4b_l1_activate(l2sc
);
89 i4b_next_l2state(l2sc
, drv
, EV_DLESTRQ
);
93 /*---------------------------------------------------------------------------*
94 * DL_RELEASE_REQ from layer 3
95 *---------------------------------------------------------------------------*/
96 int i4b_dl_release_req(l2_softc_t
*l2sc
, struct isdn_l3_driver
*drv
)
98 NDBGL2(L2_PRIM
, "isdnif %d", l2sc
->drv
->isdnif
);
99 i4b_next_l2state(l2sc
, drv
, EV_DLRELRQ
);
103 /*---------------------------------------------------------------------------*
104 * DL UNIT DATA REQUEST from Layer 3
105 *---------------------------------------------------------------------------*/
106 int i4b_dl_unit_data_req(l2_softc_t
*l2sc
, struct isdn_l3_driver
*drv
, struct mbuf
*m
)
109 NDBGL2(L2_PRIM
, "isdnif %d", l2sc
->isdnif
);
114 /*---------------------------------------------------------------------------*
115 * DL DATA REQUEST from Layer 3
116 *---------------------------------------------------------------------------*/
117 int i4b_dl_data_req(l2_softc_t
*l2sc
, struct isdn_l3_driver
*drv
, struct mbuf
*m
)
119 switch(l2sc
->Q921_state
)
125 if(IF_QFULL(&l2sc
->i_queue
))
127 NDBGL2(L2_ERROR
, "i_queue full!!");
135 IF_ENQUEUE(&l2sc
->i_queue
, m
);
138 i4b_i_frame_queued_up(l2sc
);
143 NDBGL2(L2_ERROR
, "isdnif %d ERROR in state [%s], freeing mbuf", l2sc
->drv
->isdnif
, i4b_print_l2state(l2sc
));
150 /*---------------------------------------------------------------------------*
151 * isdn_layer2_activate_ind - link activation/deactivation indication from layer 1
152 *---------------------------------------------------------------------------*/
154 isdn_layer2_activate_ind(struct l2_softc
*l2sc
, struct isdn_l3_driver
*drv
, int event_activate
)
156 if (event_activate
) {
157 l2sc
->ph_active
= PH_ACTIVE
;
159 l2sc
->ph_active
= PH_INACTIVE
;
164 /*---------------------------------------------------------------------------*
165 * i4b_l2_unit_init - place layer 2 unit into known state
166 *---------------------------------------------------------------------------*/
168 i4b_l2_unit_init(l2_softc_t
*l2sc
)
173 l2sc
->Q921_state
= ST_TEI_UNAS
;
174 l2sc
->tei_valid
= TEI_INVALID
;
182 l2sc
->l3initiated
= 0;
188 l2sc
->iframe_sent
= 0;
190 l2sc
->postfsmfunc
= NULL
;
192 if(l2sc
->ua_num
!= UA_EMPTY
)
194 i4b_Dfreembuf(l2sc
->ua_frame
);
195 l2sc
->ua_num
= UA_EMPTY
;
196 l2sc
->ua_frame
= NULL
;
206 /*---------------------------------------------------------------------------*
207 * isdn_layer2_status_ind - status indication upward
208 *---------------------------------------------------------------------------*/
210 isdn_layer2_status_ind(l2_softc_t
*l2sc
, struct isdn_l3_driver
*drv
, int status
, int parm
)
217 NDBGL2(L2_PRIM
, "isdnif %d, status=%d, parm=%d", l2sc
->drv
->isdnif
, status
, parm
);
224 callout_stop(&l2sc
->T200_callout
);
225 callout_stop(&l2sc
->T202_callout
);
226 callout_stop(&l2sc
->T203_callout
);
227 callout_stop(&l2sc
->IFQU_callout
);
231 l2sc
->i_queue
.ifq_maxlen
= IQUEUE_MAXLEN
;
232 l2sc
->ua_frame
= NULL
;
233 memset(&l2sc
->stat
, 0, sizeof(lapdstat_t
));
235 /* initialize the callout handles for timeout routines */
236 callout_init(&l2sc
->T200_callout
, 0);
237 callout_init(&l2sc
->T202_callout
, 0);
238 callout_init(&l2sc
->T203_callout
, 0);
239 callout_init(&l2sc
->IFQU_callout
, 0);
241 i4b_l2_unit_init(l2sc
);
244 case STI_L1STAT
: /* state of layer 1 */
247 case STI_PDEACT
: /* Timer 4 expired */
248 /*XXX*/ if((l2sc
->Q921_state
>= ST_AW_EST
) &&
249 (l2sc
->Q921_state
<= ST_TIMREC
))
251 NDBGL2(L2_ERROR
, "isdnif %d, persistent deactivation!", l2sc
->drv
->isdnif
);
252 i4b_l2_unit_init(l2sc
);
253 parm
= -1; /* this is passed as the new
254 * TEI to upper layers */
263 i4b_l2_unit_init(l2sc
);
264 NDBGL2(L2_ERROR
, "isdnif %d, cannot access S0 bus!", l2sc
->drv
->isdnif
);
268 NDBGL2(L2_ERROR
, "ERROR, isdnif %d, unknown status message!", l2sc
->drv
->isdnif
);
273 i4b_mdl_status_ind(l2sc
->drv
, status
, parm
); /* send up to layer 3 */
280 /*---------------------------------------------------------------------------*
281 * MDL_COMMAND_REQ from layer 3
282 *---------------------------------------------------------------------------*/
283 int i4b_mdl_command_req(struct isdn_l3_driver
*drv
, int command
, void *parm
)
285 struct l2_softc
*sc
= (l2_softc_t
*)drv
->l1_token
;
287 NDBGL2(L2_PRIM
, "isdnif %d, command=%d, parm=%p", drv
->isdnif
, command
, parm
);
292 i4b_l2_unit_init(sc
);
293 /* XXX - enable interrupts */
296 /* XXX - disable interrupts */
300 /* pass down to layer 1 driver */
302 sc
->driver
->mph_command_req(sc
->l1_token
, command
, parm
);
307 /*---------------------------------------------------------------------------*
308 * isdn_layer2_data_ind - process a rx'd frame got from layer 1
309 *---------------------------------------------------------------------------*/
311 isdn_layer2_data_ind(l2_softc_t
*l2sc
, struct isdn_l3_driver
*drv
, struct mbuf
*m
)
313 u_char
*ptr
= m
->m_data
;
315 if ( (*(ptr
+ OFF_CNTL
) & 0x01) == 0 )
317 if(m
->m_len
< 4) /* 6 oct - 2 chksum oct */
319 l2sc
->stat
.err_rx_len
++;
320 NDBGL2(L2_ERROR
, "ERROR, I-frame < 6 octetts!");
324 i4b_rxd_i_frame(l2sc
, drv
, m
);
326 else if ( (*(ptr
+ OFF_CNTL
) & 0x03) == 0x01 )
328 if(m
->m_len
< 4) /* 6 oct - 2 chksum oct */
330 l2sc
->stat
.err_rx_len
++;
331 NDBGL2(L2_ERROR
, "ERROR, S-frame < 6 octetts!");
335 i4b_rxd_s_frame(l2sc
, drv
, m
);
337 else if ( (*(ptr
+ OFF_CNTL
) & 0x03) == 0x03 )
339 if(m
->m_len
< 3) /* 5 oct - 2 chksum oct */
341 l2sc
->stat
.err_rx_len
++;
342 NDBGL2(L2_ERROR
, "ERROR, U-frame < 5 octetts!");
346 i4b_rxd_u_frame(l2sc
, drv
, m
);
350 l2sc
->stat
.err_rx_badf
++;
351 NDBGL2(L2_ERROR
, "ERROR, bad frame rx'd - ");
352 i4b_print_frame(m
->m_len
, m
->m_data
);
358 int i4b_l2_channel_get_state(struct isdn_l3_driver
*drv
, int b_chanid
)
360 l2_softc_t
*sc
= drv
->l1_token
;
361 return sc
->bchan_state
[b_chanid
];
364 void i4b_l2_channel_set_state(struct isdn_l3_driver
*drv
, int b_chanid
, int state
)
366 l2_softc_t
*sc
= drv
->l1_token
;
367 sc
->bchan_state
[b_chanid
] = state
;
370 /*---------------------------------------------------------------------------*
371 * telephony silence detection
372 *---------------------------------------------------------------------------*/
374 #define TEL_IDLE_MIN (BCH_MAX_DATALEN/2)
377 isdn_bchan_silence(unsigned char *data
, int len
)
382 /* count idle bytes */
386 if((*data
>= 0xaa) && (*data
<= 0xac))
392 printf("isic_hscx_silence: got %d silence bytes in frame\n", j
);
395 if(j
< (TEL_IDLE_MIN
))
403 #endif /* NI4BQ921 > 0 */