Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / net / i4b / layer2 / i4b_sframe.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_sframe.c - s frame handling routines
28  *      ----------------------------------------
29  *
30  *      $Id: i4b_sframe.c,v 1.15 2000/08/24 11:48:58 hm Exp $ 
31  *
32  * $FreeBSD: src/sys/i4b/layer2/i4b_sframe.c,v 1.6.2.1 2001/08/10 14:08:41 obrien Exp $
33  *
34  *      last edit-date: [Mon May 29 16:55:23 2000]
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 #include <sys/systm.h>
47 #include <sys/mbuf.h>
48 #include <sys/socket.h>
49 #include <net/if.h>
50
51 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
52 #include <sys/callout.h>
53 #endif
54
55 #ifdef __FreeBSD__
56 #include <machine/i4b_debug.h>
57 #else
58 #include <i4b/i4b_debug.h>
59 #include <i4b/i4b_ioctl.h>
60 #endif
61
62 #include <i4b/include/i4b_l1l2.h>
63 #include <i4b/include/i4b_mbuf.h>
64
65 #include <i4b/layer2/i4b_l2.h>
66 #include <i4b/layer2/i4b_l2fsm.h>
67
68 /*---------------------------------------------------------------------------*
69  *      process s frame
70  *---------------------------------------------------------------------------*/
71 void
72 i4b_rxd_s_frame(int unit, struct mbuf *m)
73 {
74         l2_softc_t *l2sc = &l2_softc[unit];
75         u_char *ptr = m->m_data;
76         
77         if(!((l2sc->tei_valid == TEI_VALID) &&
78              (l2sc->tei == GETTEI(*(ptr+OFF_TEI)))))
79         {
80                 i4b_Dfreembuf(m);
81                 return;
82         }
83
84         l2sc->rxd_CR = GETCR(*(ptr + OFF_SAPI));
85         l2sc->rxd_PF = GETSPF(*(ptr + OFF_SNR));
86         l2sc->rxd_NR = GETSNR(*(ptr + OFF_SNR));
87
88         i4b_rxd_ack(l2sc, l2sc->rxd_NR);
89         
90         switch(*(ptr + OFF_SRCR))
91         {
92                 case RR:
93                         l2sc->stat.rx_rr++; /* update statistics */
94                         NDBGL2(L2_S_MSG, "rx'd RR, N(R) = %d", l2sc->rxd_NR);
95                         i4b_next_l2state(l2sc, EV_RXRR);
96                         break;
97
98                 case RNR:
99                         l2sc->stat.rx_rnr++; /* update statistics */
100                         NDBGL2(L2_S_MSG, "rx'd RNR, N(R) = %d", l2sc->rxd_NR);
101                         i4b_next_l2state(l2sc, EV_RXRNR);
102                         break;
103
104                 case REJ:
105                         l2sc->stat.rx_rej++; /* update statistics */
106                         NDBGL2(L2_S_MSG, "rx'd REJ, N(R) = %d", l2sc->rxd_NR);
107                         i4b_next_l2state(l2sc, EV_RXREJ);
108                         break;
109
110                 default:
111                         l2sc->stat.err_rx_bads++; /* update statistics */
112                         NDBGL2(L2_S_ERR, "ERROR, unknown code, frame = ");
113                         i4b_print_frame(m->m_len, m->m_data);
114                         break;
115         }
116         i4b_Dfreembuf(m);       
117 }
118
119 /*---------------------------------------------------------------------------*
120  *      transmit RR command
121  *---------------------------------------------------------------------------*/
122 void
123 i4b_tx_rr_command(l2_softc_t *l2sc, pbit_t pbit)
124 {
125         struct mbuf *m;
126
127         NDBGL2(L2_S_MSG, "tx RR, unit = %d", l2sc->unit);
128
129         m = i4b_build_s_frame(l2sc, CR_CMD_TO_NT, pbit, RR);
130
131         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
132
133         l2sc->stat.tx_rr++; /* update statistics */
134 }
135
136 /*---------------------------------------------------------------------------*
137  *      transmit RR response
138  *---------------------------------------------------------------------------*/
139 void
140 i4b_tx_rr_response(l2_softc_t *l2sc, fbit_t fbit)
141 {
142         struct mbuf *m;
143
144         NDBGL2(L2_S_MSG, "tx RR, unit = %d", l2sc->unit);
145
146         m = i4b_build_s_frame(l2sc, CR_RSP_TO_NT, fbit, RR);    
147
148         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
149
150         l2sc->stat.tx_rr++; /* update statistics */
151 }
152
153 /*---------------------------------------------------------------------------*
154  *      transmit RNR command
155  *---------------------------------------------------------------------------*/
156 void
157 i4b_tx_rnr_command(l2_softc_t *l2sc, pbit_t pbit)
158 {
159         struct mbuf *m;
160
161         NDBGL2(L2_S_MSG, "tx RNR, unit = %d", l2sc->unit);
162
163         m = i4b_build_s_frame(l2sc, CR_CMD_TO_NT, pbit, RNR);   
164
165         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
166
167         l2sc->stat.tx_rnr++; /* update statistics */
168 }
169
170 /*---------------------------------------------------------------------------*
171  *      transmit RNR response
172  *---------------------------------------------------------------------------*/
173 void
174 i4b_tx_rnr_response(l2_softc_t *l2sc, fbit_t fbit)
175 {
176         struct mbuf *m;
177
178         NDBGL2(L2_S_MSG, "tx RNR, unit = %d", l2sc->unit);
179
180         m = i4b_build_s_frame(l2sc, CR_RSP_TO_NT, fbit, RNR);
181
182         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
183
184         l2sc->stat.tx_rnr++; /* update statistics */
185 }
186
187 /*---------------------------------------------------------------------------*
188  *      transmit REJ response
189  *---------------------------------------------------------------------------*/
190 void
191 i4b_tx_rej_response(l2_softc_t *l2sc, fbit_t fbit)
192 {
193         struct mbuf *m;
194
195         NDBGL2(L2_S_MSG, "tx REJ, unit = %d", l2sc->unit);
196
197         m = i4b_build_s_frame(l2sc, CR_RSP_TO_NT, fbit, REJ);
198
199         PH_Data_Req(l2sc->unit, m, MBUF_FREE);
200
201         l2sc->stat.tx_rej++; /* update statistics */    
202 }
203
204 /*---------------------------------------------------------------------------*
205  *      build S-frame for sending
206  *---------------------------------------------------------------------------*/
207 struct mbuf *
208 i4b_build_s_frame(l2_softc_t *l2sc, crbit_to_nt_t crbit, pbit_t pbit, u_char type)
209 {
210         struct mbuf *m;
211         
212         if((m = i4b_Dgetmbuf(S_FRAME_LEN)) == NULL)
213                 return(NULL);
214
215         PUTSAPI(SAPI_CCP, crbit, m->m_data[OFF_SAPI]);
216                 
217         PUTTEI(l2sc->tei, m->m_data[OFF_TEI]);
218
219         m->m_data[OFF_SRCR] = type;
220
221         m->m_data[OFF_SNR] = (l2sc->vr << 1) | (pbit & 0x01);
222
223         return(m);
224 }
225
226 #endif /* NI4BQ921 > 0 */