2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
25 *---------------------------------------------------------------------------
27 * i4b_l4if.c - Layer 3 interface to Layer 4
28 * -------------------------------------------
30 * $Id: i4b_l4if.c,v 1.27 2000/08/24 11:48:58 hm Exp $
32 * $FreeBSD: src/sys/i4b/layer3/i4b_l4if.c,v 1.6.2.1 2001/08/10 14:08:42 obrien Exp $
33 * $DragonFly: src/sys/net/i4b/layer3/i4b_l4if.c,v 1.2 2003/06/17 04:28:40 dillon Exp $
35 * last edit-date: [Fri Jun 2 14:32:19 2000]
37 *---------------------------------------------------------------------------*/
46 #include <sys/param.h>
47 #include <sys/systm.h>
50 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
51 #include <sys/callout.h>
55 #include <machine/i4b_debug.h>
56 #include <machine/i4b_ioctl.h>
57 #include <machine/i4b_cause.h>
59 #include <i4b/i4b_debug.h>
60 #include <i4b/i4b_ioctl.h>
61 #include <i4b/i4b_cause.h>
64 #include <i4b/include/i4b_l2l3.h>
65 #include <i4b/include/i4b_l3l4.h>
66 #include <i4b/include/i4b_global.h>
68 #include <i4b/layer3/i4b_l3.h>
69 #include <i4b/layer3/i4b_l3fsm.h>
71 #include <i4b/layer4/i4b_l4.h>
73 extern void isic_settrace(int unit, int val); /*XXX*/
74 extern int isic_gettrace(int unit); /*XXX*/
76 static void n_connect_request(u_int cdid);
77 static void n_connect_response(u_int cdid, int response, int cause);
78 static void n_disconnect_request(u_int cdid, int cause);
79 static void n_alert_request(u_int cdid);
80 static void n_mgmt_command(int unit, int cmd, void *parm);
82 /*---------------------------------------------------------------------------*
83 * i4b_mdl_status_ind - status indication from lower layers
84 *---------------------------------------------------------------------------*/
86 i4b_mdl_status_ind(int unit, int status, int parm)
91 NDBGL3(L3_MSG, "unit = %d, status = %d, parm = %d", unit, status, parm);
96 NDBGL3(L3_MSG, "STI_ATTACH: attaching unit %d to controller %d", unit, nctrl);
98 /* init function pointers */
100 ctrl_desc[nctrl].N_CONNECT_REQUEST = n_connect_request;
101 ctrl_desc[nctrl].N_CONNECT_RESPONSE = n_connect_response;
102 ctrl_desc[nctrl].N_DISCONNECT_REQUEST = n_disconnect_request;
103 ctrl_desc[nctrl].N_ALERT_REQUEST = n_alert_request;
104 ctrl_desc[nctrl].N_DOWNLOAD = NULL; /* only used by active cards */
105 ctrl_desc[nctrl].N_DIAGNOSTICS = NULL; /* only used by active cards */
106 ctrl_desc[nctrl].N_MGMT_COMMAND = n_mgmt_command;
108 /* init type and unit */
110 ctrl_desc[nctrl].unit = unit;
111 ctrl_desc[nctrl].ctrl_type = CTRL_PASSIVE;
112 ctrl_desc[nctrl].card_type = parm;
116 ctrl_desc[nctrl].dl_est = DL_DOWN;
117 ctrl_desc[nctrl].nbch = 2; /* XXX extra param? */
118 for (i = 0; i < ctrl_desc[nctrl].nbch; i++)
119 ctrl_desc[nctrl].bch_state[i] = BCH_ST_FREE;
121 ctrl_desc[nctrl].tei = -1;
123 /* init unit to controller table */
125 utoc_tab[unit] = nctrl;
127 /* increment no. of controllers */
134 i4b_l4_l12stat(unit, 1, parm);
135 NDBGL3(L3_MSG, "STI_L1STAT: unit %d layer 1 = %s", unit, status ? "up" : "down");
139 i4b_l4_l12stat(unit, 2, parm);
140 NDBGL3(L3_MSG, "STI_L2STAT: unit %d layer 2 = %s", unit, status ? "up" : "down");
144 ctrl_desc[unit].tei = parm;
145 i4b_l4_teiasg(unit, parm);
146 NDBGL3(L3_MSG, "STI_TEIASG: unit %d TEI = %d = 0x%02x", unit, parm, parm);
149 case STI_PDEACT: /* L1 T4 timeout */
150 NDBGL3(L3_ERR, "STI_PDEACT: unit %d TEI = %d = 0x%02x", unit, parm, parm);
154 for(i=0; i < N_CALL_DESC; i++)
156 if( (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
157 (ctrl_desc[call_desc[i].controller].unit == unit))
159 i4b_l3_stop_all_timers(&(call_desc[i]));
160 if(call_desc[i].cdid != CDID_UNUSED)
165 ctrl_desc[utoc_tab[unit]].dl_est = DL_DOWN;
166 for (i = 0; i < ctrl_desc[utoc_tab[unit]].nbch; i++)
167 ctrl_desc[utoc_tab[unit]].bch_state[i] = BCH_ST_FREE;
168 ctrl_desc[utoc_tab[unit]].tei = -1;
172 i4b_l4_pdeact(unit, sendup);
173 call_desc[i].cdid = CDID_UNUSED;
177 case STI_NOL1ACC: /* no outgoing access to S0 */
178 NDBGL3(L3_ERR, "STI_NOL1ACC: unit %d no outgoing access to S0", unit);
180 for(i=0; i < N_CALL_DESC; i++)
182 if( (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
183 (ctrl_desc[call_desc[i].controller].unit == unit))
185 if(call_desc[i].cdid != CDID_UNUSED)
187 SET_CAUSE_TYPE(call_desc[i].cause_in, CAUSET_I4B);
188 SET_CAUSE_VAL(call_desc[i].cause_in, CAUSE_I4B_L1ERROR);
189 i4b_l4_disconnect_ind(&(call_desc[i]));
194 ctrl_desc[utoc_tab[unit]].dl_est = DL_DOWN;
195 for (i = 0; i < ctrl_desc[utoc_tab[unit]].nbch; i++)
196 ctrl_desc[utoc_tab[unit]].bch_state[i] = BCH_ST_FREE;
197 ctrl_desc[utoc_tab[unit]].tei = -1;
201 NDBGL3(L3_ERR, "ERROR, unit %d, unknown status value %d!", unit, status);
207 /*---------------------------------------------------------------------------*
208 * send command to the lower layers
209 *---------------------------------------------------------------------------*/
211 n_mgmt_command(int unit, int cmd, void *parm)
218 NDBGL3(L3_MSG, "CMR_DOPEN for unit %d", unit);
220 for(i=0; i < N_CALL_DESC; i++)
222 if( (ctrl_desc[call_desc[i].controller].ctrl_type == CTRL_PASSIVE) &&
223 (ctrl_desc[call_desc[i].controller].unit == unit))
225 call_desc[i].cdid = CDID_UNUSED;
229 ctrl_desc[utoc_tab[unit]].dl_est = DL_DOWN;
230 for (i = 0; i < ctrl_desc[utoc_tab[unit]].nbch; i++)
231 ctrl_desc[utoc_tab[unit]].bch_state[i] = BCH_ST_FREE;
232 ctrl_desc[utoc_tab[unit]].tei = -1;
236 NDBGL3(L3_MSG, "CMR_DCLOSE for unit %d", unit);
240 NDBGL3(L3_MSG, "CMR_SETTRACE for unit %d", unit);
244 NDBGL3(L3_MSG, "unknown cmd %d for unit %d", cmd, unit);
248 MDL_Command_Req(unit, cmd, parm);
252 /*---------------------------------------------------------------------------*
253 * handle connect request message from userland
254 *---------------------------------------------------------------------------*/
256 n_connect_request(u_int cdid)
260 cd = cd_by_cdid(cdid);
262 next_l3state(cd, EV_SETUPRQ);
265 /*---------------------------------------------------------------------------*
266 * handle setup response message from userland
267 *---------------------------------------------------------------------------*/
269 n_connect_response(u_int cdid, int response, int cause)
274 cd = cd_by_cdid(cdid);
278 cd->response = response;
279 cd->cause_out = cause;
283 case SETUP_RESP_ACCEPT:
284 next_l3state(cd, EV_SETACRS);
285 chstate = BCH_ST_USED;
288 case SETUP_RESP_REJECT:
289 next_l3state(cd, EV_SETRJRS);
290 chstate = BCH_ST_FREE;
293 case SETUP_RESP_DNTCRE:
294 next_l3state(cd, EV_SETDCRS);
295 chstate = BCH_ST_FREE;
298 default: /* failsafe */
299 next_l3state(cd, EV_SETDCRS);
300 chstate = BCH_ST_FREE;
301 NDBGL3(L3_ERR, "unknown response, doing SETUP_RESP_DNTCRE");
305 if((cd->channelid >= 0) && (cd->channelid < ctrl_desc[cd->controller].nbch))
307 ctrl_desc[cd->controller].bch_state[cd->channelid] = chstate;
311 NDBGL3(L3_MSG, "Warning, invalid channelid %d, response = %d\n", cd->channelid, response);
315 /*---------------------------------------------------------------------------*
316 * handle disconnect request message from userland
317 *---------------------------------------------------------------------------*/
319 n_disconnect_request(u_int cdid, int cause)
323 cd = cd_by_cdid(cdid);
325 cd->cause_out = cause;
327 next_l3state(cd, EV_DISCRQ);
330 /*---------------------------------------------------------------------------*
331 * handle alert request message from userland
332 *---------------------------------------------------------------------------*/
334 n_alert_request(u_int cdid)
338 cd = cd_by_cdid(cdid);
340 next_l3state(cd, EV_ALERTRQ);
343 #endif /* NI4BQ931 > 0 */