Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / sys / net / i4b / layer2 / i4b_uframe.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_uframe.c - routines for handling U-frames
28  *      -----------------------------------------------
29  *
30  *      $Id: i4b_uframe.c,v 1.13 2000/08/24 11:48:58 hm Exp $ 
31  *
32  * $FreeBSD: src/sys/i4b/layer2/i4b_uframe.c,v 1.6.2.1 2001/08/10 14:08:41 obrien Exp $
33  * $DragonFly: src/sys/net/i4b/layer2/i4b_uframe.c,v 1.5 2005/06/14 21:19:19 joerg Exp $
34  *
35  *      last edit-date: [Mon May 29 16:55:30 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/mbuf.h>
45 #include <sys/socket.h>
46 #include <net/if.h>
47
48 #include <net/i4b/include/machine/i4b_debug.h>
49
50 #include "../include/i4b_l1l2.h"
51 #include "../include/i4b_l2l3.h"
52 #include "../include/i4b_mbuf.h"
53
54 #include "i4b_l2.h"
55 #include "i4b_l2fsm.h"
56
57 /*---------------------------------------------------------------------------*
58  *      process a received U-frame
59  *---------------------------------------------------------------------------*/
60 void
61 i4b_rxd_u_frame(int unit, struct mbuf *m)
62 {
63         l2_softc_t *l2sc = &l2_softc[unit];
64         u_char *ptr = m->m_data;
65
66         int sapi = GETSAPI(*(ptr + OFF_SAPI));
67         int tei = GETTEI(*(ptr + OFF_TEI));     
68         int pfbit = GETUPF(*(ptr + OFF_CNTL));
69         
70         switch(*(ptr + OFF_CNTL) & ~UPFBIT)
71         {
72                 /* commands */
73
74                 case SABME:
75                         if((l2sc->tei_valid == TEI_VALID) &&
76                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
77                         {
78                                 l2sc->stat.rx_sabme++;
79                                 NDBGL2(L2_U_MSG, "SABME, sapi = %d, tei = %d", sapi, tei);
80                                 l2sc->rxd_PF = pfbit;
81                                 i4b_next_l2state(l2sc, EV_RXSABME);
82                         }
83                         i4b_Dfreembuf(m);
84                         break;
85
86                 case UI:
87                         if(sapi == SAPI_L2M &&
88                            tei == GROUP_TEI &&
89                            *(ptr + OFF_MEI) == MEI)
90                         {
91                                 /* layer 2 management (SAPI = 63) */
92                                 l2sc->stat.rx_tei++;
93                                 i4b_tei_rxframe(unit, m);
94                         }
95                         else if(sapi == SAPI_CCP && tei == GROUP_TEI)
96                         {
97                                 /* call control (SAPI = 0) */
98                                 l2sc->stat.rx_ui++;
99                                 /* strip ui header */
100                                 m_adj(m, UI_HDR_LEN);
101                                 /* to upper layer */
102                                 DL_Unit_Data_Ind(unit, m);
103                         }
104                         else
105                         {
106                                 l2sc->stat.err_rx_badui++;
107                                 NDBGL2(L2_U_ERR, "unknown UI frame!");
108                                 i4b_Dfreembuf(m);                               
109                         }
110                         break;
111                         
112                 case DISC:
113                         if((l2sc->tei_valid == TEI_VALID) &&
114                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
115                         {               
116                                 l2sc->stat.rx_disc++;
117                                 NDBGL2(L2_U_MSG, "DISC, sapi = %d, tei = %d", sapi, tei);
118                                 l2sc->rxd_PF = pfbit;
119                                 i4b_next_l2state(l2sc, EV_RXDISC);
120                         }
121                         i4b_Dfreembuf(m);
122                         break;
123
124                 case XID:
125                         if((l2sc->tei_valid == TEI_VALID) &&
126                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
127                         {               
128                                 l2sc->stat.rx_xid++;
129                                 NDBGL2(L2_U_MSG, "XID, sapi = %d, tei = %d", sapi, tei);
130                         }
131                         i4b_Dfreembuf(m);                       
132                         break;
133                         
134                 /* responses */
135
136                 case DM:
137                         if((l2sc->tei_valid == TEI_VALID) &&
138                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
139                         {               
140                                 l2sc->stat.rx_dm++;
141                                 NDBGL2(L2_U_MSG, "DM, sapi = %d, tei = %d", sapi, tei);
142                                 i4b_print_frame(m->m_len, m->m_data);
143                                 l2sc->rxd_PF = pfbit;
144                                 i4b_next_l2state(l2sc, EV_RXDM);
145                         }
146                         i4b_Dfreembuf(m);
147                         break;
148                         
149                 case UA:
150                         if((l2sc->tei_valid == TEI_VALID) &&
151                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
152                         {               
153                                 l2sc->stat.rx_ua++;
154                                 NDBGL2(L2_U_MSG, "UA, sapi = %d, tei = %d", sapi, tei);
155                                 l2sc->rxd_PF = pfbit;
156                                 i4b_next_l2state(l2sc, EV_RXUA);
157                         }
158                         i4b_Dfreembuf(m);                       
159                         break;                  
160
161                 case FRMR:
162                         if((l2sc->tei_valid == TEI_VALID) &&
163                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
164                         {
165                                 l2sc->stat.rx_frmr++;
166                                 NDBGL2(L2_U_MSG, "FRMR, sapi = %d, tei = %d", sapi, tei);
167                                 l2sc->rxd_PF = pfbit;
168                                 i4b_next_l2state(l2sc, EV_RXFRMR);
169                         }
170                         i4b_Dfreembuf(m);                       
171                         break;
172
173                 default:
174                         if((l2sc->tei_valid == TEI_VALID) &&
175                            (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))
176                         {               
177                                 NDBGL2(L2_U_ERR, "UNKNOWN TYPE ERROR, sapi = %d, tei = %d, frame = ", sapi, tei);
178                                 i4b_print_frame(m->m_len, m->m_data);
179                         }
180                         else
181                         {               
182                                 NDBGL2(L2_U_ERR, "not mine -  UNKNOWN TYPE ERROR, sapi = %d, tei = %d, frame = ", sapi, tei);
183                                 i4b_print_frame(m->m_len, m->m_data);
184                         }
185                         l2sc->stat.err_rx_badui++;                      
186                         i4b_Dfreembuf(m);                       
187                         break;
188         }
189 }
190
191 /*---------------------------------------------------------------------------*
192  *      build U-frame for sending
193  *---------------------------------------------------------------------------*/
194 struct mbuf *
195 i4b_build_u_frame(l2_softc_t *l2sc, crbit_to_nt_t crbit, pbit_t pbit, u_char type)
196 {
197         struct mbuf *m;
198         
199         if((m = i4b_Dgetmbuf(U_FRAME_LEN)) == NULL)
200                 return(NULL);
201
202         PUTSAPI(SAPI_CCP, crbit, m->m_data[OFF_SAPI]);
203                 
204         PUTTEI(l2sc->tei, m->m_data[OFF_TEI]);
205
206         if(pbit)
207                 m->m_data[OFF_CNTL] = type | UPBITSET;
208         else
209                 m->m_data[OFF_CNTL] = type & ~UPBITSET;
210
211         return(m);
212 }
213
214 /*---------------------------------------------------------------------------*
215  *      transmit SABME command
216  *---------------------------------------------------------------------------*/
217 void
218 i4b_tx_sabme(l2_softc_t *l2sc, pbit_t pbit)
219 {
220         struct mbuf *m;
221
222         l2sc->stat.tx_sabme++;
223         NDBGL2(L2_U_MSG, "tx SABME, tei = %d", l2sc->tei);
224         m = i4b_build_u_frame(l2sc, CR_CMD_TO_NT, pbit, SABME);
225         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
226 }
227
228 /*---------------------------------------------------------------------------*
229  *      transmit DM response
230  *---------------------------------------------------------------------------*/
231 void
232 i4b_tx_dm(l2_softc_t *l2sc, fbit_t fbit)
233 {
234         struct mbuf *m;
235
236         l2sc->stat.tx_dm++;     
237         NDBGL2(L2_U_MSG, "tx DM, tei = %d", l2sc->tei);
238         m = i4b_build_u_frame(l2sc, CR_RSP_TO_NT, fbit, DM);
239         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
240 }
241
242 /*---------------------------------------------------------------------------*
243  *      transmit DISC command
244  *---------------------------------------------------------------------------*/
245 void
246 i4b_tx_disc(l2_softc_t *l2sc, pbit_t pbit)
247 {
248         struct mbuf *m;
249         
250         l2sc->stat.tx_disc++;
251         NDBGL2(L2_U_MSG, "tx DISC, tei = %d", l2sc->tei);
252         m = i4b_build_u_frame(l2sc, CR_CMD_TO_NT, pbit, DISC);
253         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
254 }
255
256 /*---------------------------------------------------------------------------*
257  *      transmit UA response
258  *---------------------------------------------------------------------------*/
259 void
260 i4b_tx_ua(l2_softc_t *l2sc, fbit_t fbit)
261 {
262         struct mbuf *m;
263         
264         l2sc->stat.tx_ua++;
265         NDBGL2(L2_U_MSG, "tx UA, tei = %d", l2sc->tei);
266         m = i4b_build_u_frame(l2sc, CR_RSP_TO_NT, fbit, UA);
267         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
268 }
269
270 /*---------------------------------------------------------------------------*
271  *      transmit FRMR response
272  *---------------------------------------------------------------------------*/
273 void
274 i4b_tx_frmr(l2_softc_t *l2sc, fbit_t fbit)
275 {
276         struct mbuf *m;
277         
278         l2sc->stat.tx_frmr++;
279         NDBGL2(L2_U_MSG, "tx FRMR, tei = %d", l2sc->tei);
280         m = i4b_build_u_frame(l2sc, CR_RSP_TO_NT, fbit, FRMR);
281         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
282 }
283
284 #endif /* NI4BQ921 > 0 */