OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [802/] [llc_utility.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * NET          An implementation of the IEEE 802.2 LLC protocol for the
3
 *              LINUX operating system.  LLC is implemented as a set of
4
 *              state machines and callbacks for higher networking layers.
5
 *
6
 *              Small utilities, Linux timer handling.
7
 *
8
 *              Written by Tim Alpaerts, Tim_Alpaerts@toyota-motor-europe.com
9
 *
10
 *              This program is free software; you can redistribute it and/or
11
 *              modify it under the terms of the GNU General Public License
12
 *              as published by the Free Software Foundation; either version
13
 *              2 of the License, or (at your option) any later version.
14
 *
15
 *      Changes
16
 *              Alan Cox        :       Chainsawed into Linux form.
17
 *                                      Added llc_ function name prefixes.
18
 *                                      Fixed bug in stop/start timer.
19
 *                                      Added llc_cancel_timers for closing
20
 *                                              down an llc
21
 */
22
 
23
#include <linux/types.h>
24
#include <linux/kernel.h>
25
#include <linux/netdevice.h>
26
#include <linux/skbuff.h>
27
#include <linux/proc_fs.h>
28
#include <linux/stat.h>
29
#include <net/llc_frame.h>
30
#include <net/llc.h>
31
 
32
int llc_decode_frametype(frameptr fr)
33
{
34
        if (IS_UFRAME(fr))
35
        {      /* unnumbered cmd/rsp */
36
                switch(fr->u_mm.mm & 0x3B)
37
                {
38
                        case 0x1B:
39
                            return(SABME_CMD);
40
                            break;
41
                        case 0x10:
42
                            return(DISC_CMD);
43
                            break;
44
                        case 0x18:
45
                            return(UA_RSP);
46
                            break;
47
                        case 0x03:
48
                            return(DM_RSP);
49
                            break;
50
                        case 0x21:
51
                            return(FRMR_RSP);
52
                            break;
53
                        case 0x00:
54
                            return(UI_CMD);
55
                            break;
56
                        case 0x2B:
57
                            if (IS_RSP(fr))
58
                                return(XID_RSP);
59
                            else
60
                                return(XID_CMD);
61
                            break;
62
                        case 0x38:
63
                            if (IS_RSP(fr))
64
                                return(TEST_RSP);
65
                            else
66
                                return(TEST_CMD);
67
                            break;
68
                        default:
69
                            return(BAD_FRAME);
70
                }
71
        }
72
        else if (IS_SFRAME(fr))
73
        {  /* supervisory cmd/rsp */
74
                switch(fr->s_hdr.ss)
75
                {
76
                        case 0x00:
77
                            if (IS_RSP(fr))
78
                                return(RR_RSP);
79
                            else
80
                                return(RR_CMD);
81
                            break;
82
                        case 0x02:
83
                            if (IS_RSP(fr))
84
                                return(REJ_RSP);
85
                            else
86
                                return(REJ_CMD);
87
                            break;
88
                        case 0x01:
89
                            if (IS_RSP(fr))
90
                                return(RNR_RSP);
91
                            else
92
                                return(RNR_CMD);
93
                            break;
94
                        default:
95
                            return(BAD_FRAME);
96
                }
97
        }
98
        else
99
        {                         /* information xfer */
100
                if (IS_RSP(fr))
101
                        return(I_RSP);
102
                else
103
                        return(I_CMD);
104
        }
105
}
106
 
107
 
108
/*
109
 *      Validate_seq_nos will check N(S) and N(R) to see if they are
110
 *      invalid or unexpected.
111
 *      "unexpected" is explained on p44 Send State Variable.
112
 *      The return value is:
113
 *              4 * invalid N(R) +
114
 *              2 * invalid N(S) +
115
 *              1 * unexpected N(S)
116
 */
117
 
118
int llc_validate_seq_nos(llcptr lp, frameptr fr)
119
{
120
        int res;
121
 
122
        /*
123
         *      A U-frame is always good
124
         */
125
 
126
        if (IS_UFRAME(fr))
127
                return(0);
128
 
129
        /*
130
         *      For S- and I-frames check N(R):
131
         */
132
 
133
        if (fr->i_hdr.nr == lp->vs)
134
        {       /* if N(R) = V(S)  */
135
                res = 0;                        /* N(R) is good */
136
        }
137
        else
138
        {                               /* lp->k = transmit window size */
139
                if (lp->vs >= lp->k)
140
                {       /* if window not wrapped around 127 */
141
                        if ((fr->i_hdr.nr < lp->vs) &&
142
                                (fr->i_hdr.nr > (lp->vs - lp->k)))
143
                                res = 0;
144
                        else
145
                                res = 4;                /* N(R) invalid */
146
                }
147
                else
148
                {       /* window wraps around 127 */
149
                        if ((fr->i_hdr.nr < lp->vs) ||
150
                                (fr->i_hdr.nr > (128 + lp->vs - lp->k)))
151
                                res = 0;
152
                        else
153
                                res = 4;                /* N(R) invalid */
154
                }
155
        }
156
 
157
        /*
158
         *      For an I-frame, must check N(S) also:
159
         */
160
 
161
        if (IS_IFRAME(fr))
162
        {
163
                if (fr->i_hdr.ns == lp->vr)
164
                        return res;   /* N(S) good */
165
                if (lp->vr >= lp->rw)
166
                {
167
                        /* if receive window not wrapped */
168
 
169
                        if ((fr->i_hdr.ns < lp->vr) &&
170
                                (fr->i_hdr.ns > (lp->vr - lp->k)))
171
                                res = res +1;           /* N(S) unexpected */
172
                        else
173
                                res = res +2;         /* N(S) invalid */
174
                }
175
                else
176
                {
177
                        /* Window wraps around 127 */
178
 
179
                        if ((fr->i_hdr.ns < lp->vr) ||
180
                                (fr->i_hdr.ns > (128 + lp->vr - lp->k)))
181
                                res = res +1;           /* N(S) unexpected */
182
                        else
183
                                res = res +2;         /* N(S) invalid */
184
                }
185
        }
186
        return(res);
187
}
188
 
189
/* **************** timer management routines ********************* */
190
 
191
static void llc_p_timer_expired(unsigned long ulp)
192
{
193
        llc_timer_expired((llcptr) ulp, P_TIMER);
194
}
195
 
196
static void llc_rej_timer_expired(unsigned long ulp)
197
{
198
        llc_timer_expired((llcptr) ulp, REJ_TIMER);
199
}
200
 
201
static void llc_ack_timer_expired(unsigned long ulp)
202
{
203
        llc_timer_expired((llcptr) ulp, ACK_TIMER);
204
}
205
 
206
static void llc_busy_timer_expired(unsigned long ulp)
207
{
208
        llc_timer_expired((llcptr) ulp, BUSY_TIMER);
209
}
210
 
211
/* exp_fcn is an array holding the 4 entry points of the
212
   timer expiry routines above.
213
   It is required to keep start_timer() generic.
214
   Thank you cdecl.
215
 */
216
 
217
static void (* exp_fcn[])(unsigned long) =
218
{
219
        llc_p_timer_expired,
220
        llc_rej_timer_expired,
221
        llc_ack_timer_expired,
222
        llc_busy_timer_expired
223
};
224
 
225
void llc_start_timer(llcptr lp, int t)
226
{
227
        if (lp->timer_state[t] == TIMER_IDLE)
228
        {
229
                lp->tl[t].expires = jiffies + lp->timer_interval[t];
230
                lp->tl[t].data = (unsigned long) lp;
231
                lp->tl[t].function = exp_fcn[t];
232
                add_timer(&lp->tl[t]);
233
                lp->timer_state[t] = TIMER_RUNNING;
234
        }
235
}
236
 
237
void llc_stop_timer(llcptr lp, int t)
238
{
239
        if (lp->timer_state[t] == TIMER_RUNNING)
240
        {
241
                del_timer(&lp->tl[t]);
242
                lp->timer_state[t] = TIMER_IDLE;
243
        }
244
}
245
 
246
void llc_cancel_timers(llcptr lp)
247
{
248
        llc_stop_timer(lp, P_TIMER);
249
        llc_stop_timer(lp, REJ_TIMER);
250
        llc_stop_timer(lp, ACK_TIMER);
251
        llc_stop_timer(lp, BUSY_TIMER);
252
}
253
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.