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

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [net/] [802/] [llc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *      802.2 Class 2 LLC service.
3
 */
4
 
5
 
6
int llc_rx_adm(struct sock *sk,struct sk_buff *skb, int type, int cmd, int pf, int nr, int ns)
7
{
8
        if(type==CMD)
9
        {
10
                if(cmd==DISC)
11
                        send_response(sk,DM|pf);
12
                else if(cmd==SABM)
13
                {
14
                        if(sk->state!=TCP_LISTEN)
15
                                send_response(sk. DM|pf);
16
                        else
17
                        {
18
                                sk=ll_rx_accept(sk);
19
                                if(sk!=NULL)
20
                                {
21
                                        send_response(sk, UA|pf);
22
                                        sk->llc.vs=0;
23
                                        sk->llc.vr=0;
24
                                        sk->llc.p_flag=0;
25
                                        sk->llc.remote_busy=0;
26
                                        llc_state(sk,LLC_NORMAL);
27
                                }
28
                        }
29
                }
30
                else if(pf)
31
                        send_response(sk, DM|PF);
32
        }
33
        return 0;
34
}
35
 
36
int llc_rx_setup(struct sock *sk, struct sk_buff *skb, int type, int cmd, int pf, int nr, int ns)
37
{
38
        if(type==CMD)
39
        {
40
                if(cmd==SABM)
41
                {
42
                        sk->llc.vs=0;
43
                        sk->llc.vr=0;
44
                        send_response(sk, UA|pf);
45
                }
46
                if(cmd==DISC)
47
                {
48
                        send_response(sk, DM|pf);
49
                        llc_error(sk,ECONNRESET);
50
                        llc_state(sk, LLC_ADM);
51
                }
52
        }
53
        else
54
        {
55
                if(cmd==UA && pf==sk->llc.p_flag)
56
                {
57
                        del_timer(&sk->llc.t1);
58
                        sk->llc.vs=0;
59
                        llc_update_p_flag(sk,pf);
60
                        llc_state(sk,LLC_NORMAL);
61
                }
62
                if(cmd==DM)
63
                {
64
                        llc_error(sk, ECONNRESET);
65
                        llc_state(sk, LLC_ADM);
66
                }
67
        }
68
}
69
 
70
int llc_rx_reset(struct sock *sk, struct sk_buff *skb, int type, int cmd, int pf, int nr, int ns)
71
{
72
        if(type==CMD)
73
        {
74
                if(cmd==SABM)
75
                {
76
                        sk->llc.vr=0;
77
                        sk->llc.vs=0;
78
                        send_response(sk, UA|pf);
79
                }
80
                else if(cmd==DISC)
81
                {
82
                        if(sk->llc.cause_flag==1)
83
                                llc_shutdown(sk,SHUTDOWN_MASK);
84
                        else
85
                                llc_eror(sk, ECONNREFUSED);
86
                        send_response(sk, DM|pf);
87
                        llc_state(sk, LLC_ADM);
88
                }
89
        }
90
        else
91
        {
92
                if(cmd==UA)
93
                {
94
                        if(sk->llc.p_flag==pf)
95
                        {
96
                                del_timer(&sk->llc.t1);
97
                                sk->llc.vs=0;
98
                                sk->llc.vr=0;
99
                                llc_update_p_flag(sk,pf);
100
                                llc_confirm_reset(sk, sk->llc.cause_flag);
101
                                sk->llc.remote_busy=0;
102
                                llc_state(sk, LLC_NORMAL);
103
                        }
104
                }
105
                if(cmd==DM)
106
                {       /* Should check cause_flag */
107
                        llc_shutdown(sk, SHUTDOWN_MASK);
108
                        llc_state(sk, LLC_ADM);
109
                }
110
        }
111
        return 0;
112
}
113
 
114
int llc_rx_d_conn(struct sock *sk, struct sk_buff *skb, int type, int cmd, int pf, int nr, int ns)
115
{
116
        if(type==CMD)
117
        {
118
                if(cmd==SABM)
119
                {
120
                        llc_error(sk, ECONNRESET);
121
                        llc_state(sk, ADM);
122
                }
123
                else if(cmd==DISC)
124
                {
125
                        send_response(UA|pf);
126
                        llc_state(sk, LLC_D_CONN);
127
                }
128
                else if(pf)
129
                        send_response(sk, DM|PF);
130
        }
131
        else
132
        {
133
                if(cmd==UA && pf==sk->llc.p_flag)
134
                {
135
                        del_timer(&sk->llc.t1);
136
                        llc_state(sk, ADM);
137
                        llc_confirm_reset(sk, sk->llc.cause_flag);
138
                }
139
                if(cmd==DM)
140
                {
141
                        del_timer(&sk->llc.t1);
142
                        /*if(sk->llc.cause_flag)*/
143
                        llc_shutdown(sk, SHUTDOWN_MASK);
144
                }
145
 
146
        }
147
        return 0;
148
}
149
 
150
int llc_rx_error(struct sock *sk, struct sk_buff *skb, int type, int cmd, int pf, int nr, int ns)
151
{
152
        if(type==CMD)
153
        {
154
                if(cmd==SABM)
155
                {
156
                        sk->llc.vs=0;
157
                        sk->llc.vr=0;
158
                        send_response(sk, UA|pf);
159
                        llc_error(sk,ECONNRESET);
160
                        sk->llc.p_flag=0;
161
                        sk->llc.remote_busy=0;
162
                        llc_state(sk, LLC_NORMAL);
163
                }
164
                else if(cmd==DISC)
165
                {
166
                        send_response(sk, UA|pf);
167
                        llc_shutdown(sk, SHUTDOWN_MASK);
168
                        llc_state(sk, LLC_ADM);
169
                }
170
                else
171
                        llc_resend_frmr_rsp(sk,pf);
172
        }
173
        else
174
        {
175
                if(cmd==DM)
176
                {
177
                        llc_error(sk, ECONNRESET);
178
                        del_timer(&sk->llc.t1);
179
                        llc_state(sk, LLC_ADM);
180
                }
181
                if(cmd==FRMR)
182
                {
183
                        send_command(sk, SABM);
184
                        sk->llc.p_flag=pf;
185
                        llc_start_t1();
186
                        sk->llc.retry_count=0;
187
                        sk->llc.cause_flag=0;
188
                        llc_error(sk, EPROTO);
189
                        llc_state(sk, LLC_RESET);
190
                }
191
        }
192
}
193
 
194
 
195
/*
196
 *      Subroutine for handling the shared cases of the data modes.
197
 */
198
 
199
int llc_rx_nr_shared(struct sock *sk, struct sk_buff *skb, int type, int cmd, int pf, int nr, int ns)
200
{
201
        if(type==CMD)
202
        {
203
                if(cmd==SABM)
204
                {
205
                        /*
206
                         *      Optional reset processing. We decline resets.
207
                         */
208
                        send_response(sk,DM|pf);
209
                        llc_error(sk, ECONNRESET);
210
                        llc_state(sk, LLC_ADM);
211
                }
212
                else if(cmd==DISC)
213
                {
214
                        send_response(sk,UA|pf);
215
                        llc_state(sk, LLC_ADM);
216
                        llc_shutdown(sk, SHUTDOWN_MASK);
217
                }
218
                /*
219
                 *      We only ever use windows of 7, so there is no illegal NR/NS value
220
                 *      otherwise we would FRMR here and go to ERROR state
221
                 */
222
                else if(cmd==ILLEGAL)
223
                {
224
                        llc_send_frmr_response(sk, ILLEGAL_TYPE,pf);
225
                        llc_state(sk, LLC_ERROR);
226
                        llc_error(sk, EPROTO);
227
                }
228
                else
229
                        /*
230
                         *      Not covered by general rule
231
                         */
232
                        return 0;
233
        }
234
        else
235
        {
236
                /*
237
                 *      We close on errors
238
                 */
239
                if(cmd==FRMR)
240
                {
241
                        send_command(sk, DM|pf);
242
                        sk->llc.p_flag=pf;
243
                        llc_start_t1(sk);
244
                        llc_error(sk, EPROTO);
245
                        sk->llc.cause_flag=0;
246
                        llc_state(sk, LLC_D_CONN):
247
                }
248
                else if(cmd==DM)
249
                {
250
                        llc_state(sk, LLC_ADM);
251
                        llc_error(sk, ECONNREFUSED);
252
                }
253
                /*
254
                 *      We always use a window of 7 so can't get I resp
255
                 *      with invalid NS,  or any resp with invalid NR. If
256
                 *      we add this they do the same as..
257
                 */
258
                else if(cmd==UA)
259
                {
260
                        llc_send_frmr_response(sk, UNEXPECTED_CONTROL, pf);
261
                        llc_state(sk, LLC_ERROR);
262
                        llc_error(sk, EPROTO);
263
                }
264
                else if(pf==1 && sk->llc.p_flag==0)
265
                {
266
                        llc_send_frmr_response(sk, UNEXPECTED_RESPONSE, pf);
267
                        llc_state(sk, LLC_ERROR);
268
                        llc_error(sk, EPROTO);
269
                }
270
                else if(cmd==ILLEGAL)
271
                {
272
                        llc_send_frmr_response(sk, ILLEGAL_TYPE,pf);
273
                        llc_state(sk, LLC_ERROR);
274
                        llc_error(sk, EPROTO);
275
                }
276
                else
277
                        /*
278
                         *      Not covered by general rule
279
                         */
280
                        return 0
281
        }
282
        /*
283
         *      Processed.
284
         */
285
        return 1;
286
}
287
 
288
int llc_rx_normal(struct sock *sk, struct sk_buff *skb, int type, int cmd, int pf, int nr, int ns)
289
{
290
        if(llc_rx_nr_shared(sk, skb, type, cmd, pf, nr, ns))
291
                return 0;
292
        if(cmd==I)
293
        {
294
                if(llc_invalid_ns(sk,ns))
295
                {
296
                        if((type==RESP && sk->llc.p_flag==pf)||(type==CMD && pf==0 && sk->llc.p_flag==0))
297
                        {
298
                                llc_command(sk, REJ|PF);
299
                                llc_ack_frames(sk,nr);  /* Ack frames and update N(R) */
300
                                sk->llc.p_flag=PF;
301
                                llc_state(sk, LLC_REJECT);
302
                                sk->llc.retry_count=0;
303
                                llc_start_t1(sk);
304
                                sk->llc.remote_busy=0;
305
                        }
306
                        else if((type==CMD && !pf && sk->llc.p_flag==1) || (type==RESP && !pf && sk->llc.p_flag==1))
307
                        {
308
                                if(type==CMD)
309
                                        llc_response(sk, REJ);
310
                                else
311
                                        llc_command(sk, REJ);
312
                                llc_ack_frames(sk,nr);
313
                                sk->llc.retry_count=0;
314
                                llc_state(sk, LLC_REJECT);
315
                                llc_start_t1(sk);
316
                        }
317
                        else if(pf && type==CMD)
318
                        {
319
                                llc_response(sk, REJ|PF);
320
                                llc_ack_frames(sk,nr);
321
                                sk->llc.retry_count=0;
322
                                llc_start_t1(sk);
323
                        }
324
                }
325
                else
326
                {
327
                        /*
328
                         *      Valid I frame cases
329
                         */
330
 
331
                         if(sk->llc.p_flag==pf && !(type==CMD && pf))
332
                         {
333
                                sk->llc.vr=(sk->llc.vr+1)&7;
334
                                llc_queue_rr_cmd(sk, PF);
335
                                sk->llc.retry_count=0;
336
                                llc_start_t1(sk);
337
                                sk->llc.p_flag=1;
338
                                llc_ack_frames(sk,nr);
339
                                sk->llc.remote_busy=0;
340
                         }
341
                         else if(sk->ppc.p_flag!=pf)
342
                         {
343
                                sk->llc.vr=(sk->llc.vr+1)&7;
344
                                if(type==CMD)
345
                                        llc_queue_rr_resp(sk, 0);
346
                                else
347
                                        llc_queue_rr_cmd(sk, 0);
348
                                if(sk->llc.nr!=nr)
349
                                {
350
                                        llc_ack_frames(sk,nr);
351
                                        llc_reset_t1(sk);
352
                                }
353
                         }
354
                         else if(pf)
355
                         {
356
                                sk->llc.vr=(sk->llc.vr+1)&7;
357
                                llc_queue_rr_resp(sk,PF);
358
                                if(sk->llc.nr!=nr)
359
                                {
360
                                        llc_ack_frames(sk,nr);
361
                                        llc_reset_t1(sk);
362
                                }
363
                         }
364
                         llc_queue_data(sk,skb);
365
                         return 1;
366
                }
367
        }
368
        else if(cmd==RR||cmd==RNR)
369
        {
370
                if(type==CMD || (type==RESP && (!pf || pf==1 && sk->llc.p_flag==1)))
371
                {
372
                        llc_update_p_flag(sk,pf);
373
                        if(sk->llc.nr!=nr)
374
                        {
375
                                llc_ack_frames(sk,nr);
376
                                llc_reset_t1(sk);
377
                        }
378
                        if(cmd==RR)
379
                                sk->llc.remote_busy=0;
380
                        else
381
                        {       sk->llc.remote_busy=1;
382
                                        if(!llc_t1_running(sk))
383
                                        llc_start_t1(sk);
384
                        }
385
                }
386
                else if(type==cmd && pf)
387
                {
388
                        if(cmd==RR)
389
                                llc_queue_rr_resp(sk,PF);
390
                        else
391
                        {
392
                                send_response(sk, RR|PF);
393
                                if(!llc_t1_running(sk))
394
                                        llc_start_t1(sk);
395
                        }
396
                        if(sk->llc.nr!=nr)
397
                        {
398
                                llc_ack_frames(sk,nr);
399
                                llc_reset_t1(sk);
400
                        }
401
                        if(cmd==RR)
402
                                sk->llc.remote_busy=0;
403
                        else
404
                                sk->llc.remote_busy=1;
405
                }
406
        }
407
        else if(cmd==REJ)
408
        {
409
 
410
        }
411
}
412
 

powered by: WebSVN 2.1.0

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