binutils/ld: Don't add /usr/lib to the library search path twice.
[dragonfly.git] / sys / net / i4b / layer2 / i4b_tei.c
1 /*
2  * Copyright (c) 1997, 2000 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_tei.c - tei handling procedures
28  *      -----------------------------------
29  *
30  *      $Id: i4b_tei.c,v 1.25 2000/09/01 14:11:51 hm Exp $ 
31  *
32  * $FreeBSD: src/sys/i4b/layer2/i4b_tei.c,v 1.6.2.2 2001/08/10 14:08:41 obrien Exp $
33  * $DragonFly: src/sys/net/i4b/layer2/i4b_tei.c,v 1.7 2006/09/03 18:52:29 dillon Exp $
34  *
35  *      last edit-date: [Fri Oct 13 15:56:35 2000]
36  *
37  *---------------------------------------------------------------------------*/
38
39 #include "use_i4bq921.h"
40 #if NI4BQ921 > 0
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/syslog.h>
45 #include <sys/mbuf.h>
46 #include <sys/socket.h>
47 #include <net/if.h>
48
49 #include <net/i4b/include/machine/i4b_debug.h>
50
51 #include "../include/i4b_global.h"
52 #include "../include/i4b_l1l2.h"
53 #include "../include/i4b_l2l3.h"
54 #include "../include/i4b_mbuf.h"
55
56 #include "i4b_l2.h"
57 #include "i4b_l2fsm.h"
58
59 /*---------------------------------------------------------------------------*
60  *      handle a received TEI management frame
61  *---------------------------------------------------------------------------*/
62 void
63 i4b_tei_rxframe(int unit, struct mbuf *m)
64 {
65         l2_softc_t *l2sc = &l2_softc[unit];
66         u_char *ptr = m->m_data;
67         
68         switch(*(ptr + OFF_MT))
69         {
70                 case MT_ID_ASSIGN:
71                         if( (*(ptr + OFF_RIL) == l2sc->last_ril) &&
72                             (*(ptr + OFF_RIH) == l2sc->last_rih))
73                         {
74                                 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
75                                 l2sc->tei_valid = TEI_VALID;
76
77                                 if(l2sc->T202 == TIMER_ACTIVE)
78                                         i4b_T202_stop(l2sc);
79
80                                 MDL_Status_Ind(l2sc->unit, STI_TEIASG, l2sc->tei);
81
82                                 log(LOG_INFO, "i4b: unit %d, assigned TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
83
84                                 NDBGL2(L2_TEI_MSG, "TEI ID Assign - TEI = %d", l2sc->tei);
85
86                                 i4b_next_l2state(l2sc, EV_MDASGRQ);
87                         }
88                         break;
89                         
90                 case MT_ID_DENY:
91                         if( (*(ptr + OFF_RIL) == l2sc->last_ril) &&
92                             (*(ptr + OFF_RIH) == l2sc->last_rih))
93                         {
94                                 l2sc->tei_valid = TEI_INVALID;
95                                 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
96
97                                 if(l2sc->tei == GROUP_TEI)
98                                 {
99                                         log(LOG_WARNING, "i4b: unit %d, denied TEI, no TEI values available from exchange!\n", l2sc->unit);
100                                         NDBGL2(L2_TEI_ERR, "TEI ID Denied, No TEI values available from exchange!");
101                                 }
102                                 else
103                                 {
104                                         log(LOG_WARNING, "i4b: unit %d, denied TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
105                                         NDBGL2(L2_TEI_ERR, "TEI ID Denied - TEI = %d", l2sc->tei);
106                                 }                                       
107                                 MDL_Status_Ind(l2sc->unit, STI_TEIASG, -1);
108                                 i4b_next_l2state(l2sc, EV_MDERRRS);
109                         }
110                         break;
111                         
112                 case MT_ID_CHK_REQ:
113                         if( (l2sc->tei_valid == TEI_VALID) &&
114                             ( (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI))) ||
115                               (GROUP_TEI == GET_TEIFROMAI(*(ptr+OFF_AI))) ))
116                         {
117                                 static int lasttei = -1;
118
119                                 if(l2sc->tei != lasttei)
120                                 {
121                                         NDBGL2(L2_TEI_MSG, "TEI ID Check Req - TEI = %d", l2sc->tei);
122                                         lasttei = l2sc->tei;
123                                 }
124                                 
125                                 if(l2sc->T202 == TIMER_ACTIVE)
126                                         i4b_T202_stop(l2sc);
127                                 i4b_tei_chkresp(l2sc);
128                         }
129                         break;
130                         
131                 case MT_ID_REMOVE:
132                         if( (l2sc->tei_valid == TEI_VALID) &&
133                             ( (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI))) ||
134                               (l2sc->tei == GET_TEIFROMAI(*(ptr+OFF_AI)))))
135                         {
136                                 l2sc->tei_valid = TEI_INVALID;
137                                 l2sc->tei = GET_TEIFROMAI(*(ptr+OFF_AI));
138
139                                 log(LOG_INFO, "i4b: unit %d, removed TEI = %d = 0x%02x\n", l2sc->unit, l2sc->tei, l2sc->tei);
140                                 NDBGL2(L2_TEI_MSG, "TEI ID Remove - TEI = %d", l2sc->tei);
141                                 MDL_Status_Ind(l2sc->unit, STI_TEIASG, -1);
142                                 i4b_next_l2state(l2sc, EV_MDREMRQ);
143                         }
144                         break;
145                         
146                 default:
147                         NDBGL2(L2_TEI_ERR, "UNKNOWN TEI MGMT Frame, type = 0x%x", *(ptr + OFF_MT));
148                         i4b_print_frame(m->m_len, m->m_data);
149                         break;
150         }
151         i4b_Dfreembuf(m);
152 }
153
154 /*---------------------------------------------------------------------------*
155  *      allocate and fill up a TEI management frame for sending
156  *---------------------------------------------------------------------------*/
157 static struct mbuf *
158 build_tei_mgmt_frame(l2_softc_t *l2sc, unsigned char type)
159 {
160         struct mbuf *m;
161         
162         if((m = i4b_Dgetmbuf(TEI_MGMT_FRM_LEN)) == NULL)
163                 return(NULL);
164
165         m->m_data[TEIM_SAPIO] = 0xfc;   /* SAPI = 63, CR = 0, EA = 0 */
166         m->m_data[TEIM_TEIO]  = 0xff;   /* TEI = 127, EA = 1 */
167         m->m_data[TEIM_UIO]   = UI;     /* UI */
168         m->m_data[TEIM_MEIO]  = MEI;    /* MEI */
169         m->m_data[TEIM_MTO]   = type;   /* message type */
170         
171         switch(type)
172         {
173                 case MT_ID_REQEST:
174                         i4b_make_rand_ri(l2sc);
175                         m->m_data[TEIM_RILO] = l2sc->last_ril;
176                         m->m_data[TEIM_RIHO] = l2sc->last_rih;
177                         m->m_data[TEIM_AIO] = (GROUP_TEI << 1) | 0x01;
178                         break;
179
180                 case MT_ID_CHK_RSP:
181                         i4b_make_rand_ri(l2sc);
182                         m->m_data[TEIM_RILO] = l2sc->last_ril;
183                         m->m_data[TEIM_RIHO] = l2sc->last_rih;
184                         m->m_data[TEIM_AIO] = (l2sc->tei << 1) | 0x01;
185                         break;
186                         
187                 case MT_ID_VERIFY:
188                         m->m_data[TEIM_RILO] = 0;
189                         m->m_data[TEIM_RIHO] = 0;
190                         m->m_data[TEIM_AIO] = (l2sc->tei << 1) | 0x01;
191                         break;
192
193                 default:
194                         i4b_Dfreembuf(m);
195                         panic("build_tei_mgmt_frame: invalid type");
196                         break;
197         }
198         l2sc->stat.tx_tei++;
199         return(m);
200 }
201
202 /*---------------------------------------------------------------------------*
203  *      i4b_tei_assign - TEI assignment procedure (Q.921, 5.3.2, pp 24)
204  *      T202func and N202 _MUST_ be set prior to calling this function !
205  *---------------------------------------------------------------------------*/
206 void
207 i4b_tei_assign(l2_softc_t *l2sc)
208 {
209         struct mbuf *m;
210
211         NDBGL2(L2_TEI_MSG, "tx TEI ID_Request");
212         
213         m = build_tei_mgmt_frame(l2sc, MT_ID_REQEST);
214
215         if(m == NULL)
216                 panic("i4b_tei_assign: no mbuf");               
217
218         i4b_T202_start(l2sc);
219         
220         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
221 }
222
223 /*---------------------------------------------------------------------------*
224  *      i4b_tei_assign - TEI verify procedure (Q.921, 5.3.5, pp 29)
225  *      T202func and N202 _MUST_ be set prior to calling this function !
226  *---------------------------------------------------------------------------*/
227 void
228 i4b_tei_verify(l2_softc_t *l2sc)
229 {
230         struct mbuf *m;
231
232         NDBGL2(L2_TEI_MSG, "tx TEI ID_Verify");
233
234         m = build_tei_mgmt_frame(l2sc, MT_ID_VERIFY);
235
236         if(m == NULL)
237                 panic("i4b_tei_verify: no mbuf");               
238
239         i4b_T202_start(l2sc);
240         
241         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
242 }
243
244 /*---------------------------------------------------------------------------*
245  *      i4b_tei_chkresp - TEI check response procedure (Q.921, 5.3.5, pp 29)
246  *---------------------------------------------------------------------------*/
247 void
248 i4b_tei_chkresp(l2_softc_t *l2sc)
249 {
250         struct mbuf *m;
251         static int lasttei = 0;
252
253         if(l2sc->tei != lasttei)
254         {
255                 lasttei = l2sc->tei;
256                 NDBGL2(L2_TEI_MSG, "tx TEI ID_Check_Response");
257         }
258
259         m = build_tei_mgmt_frame(l2sc, MT_ID_CHK_RSP);
260
261         if(m == NULL)
262                 panic("i4b_tei_chkresp: no mbuf");              
263
264         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
265 }
266
267 /*---------------------------------------------------------------------------*
268  *      generate some 16 bit "random" number used for TEI mgmt Ri field
269  *---------------------------------------------------------------------------*/
270 void
271 i4b_make_rand_ri(l2_softc_t *l2sc)
272 {
273
274         u_short val;
275
276 #ifdef RANDOMDEV
277         read_random((char *)&val, sizeof(val));
278 #else
279         val = (u_short)krandom();
280 #endif /* RANDOMDEV */ 
281         l2sc->last_rih = (val >> 8) & 0x00ff;
282         l2sc->last_ril = val & 0x00ff;
283 }
284
285 #endif /* NI4BQ921 > 0 */