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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [net/] [llc/] [llc_c_ac.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * llc_c_ac.c - actions performed during connection state transition.
3
 *
4
 * Description:
5
 *   Functions in this module are implementation of connection component actions
6
 *   Details of actions can be found in IEEE-802.2 standard document.
7
 *   All functions have one connection and one event as input argument. All of
8
 *   them return 0 On success and 1 otherwise.
9
 *
10
 * Copyright (c) 1997 by Procom Technology, Inc.
11
 *               2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
12
 *
13
 * This program can be redistributed or modified under the terms of the
14
 * GNU General Public License as published by the Free Software Foundation.
15
 * This program is distributed without any warranty or implied warranty
16
 * of merchantability or fitness for a particular purpose.
17
 *
18
 * See the GNU General Public License for more details.
19
 */
20
#include <linux/netdevice.h>
21
#include <net/llc_conn.h>
22
#include <net/llc_sap.h>
23
#include <net/sock.h>
24
#include <net/llc_c_ev.h>
25
#include <net/llc_c_ac.h>
26
#include <net/llc_c_st.h>
27
#include <net/llc_pdu.h>
28
#include <net/llc.h>
29
 
30
 
31
static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb);
32
static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb);
33
static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *ev);
34
 
35
static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb);
36
 
37
static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
38
                                               struct sk_buff *skb);
39
 
40
static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb);
41
 
42
#define INCORRECT 0
43
 
44
int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb)
45
{
46
        struct llc_sock *llc = llc_sk(sk);
47
 
48
        if (llc->remote_busy_flag) {
49
                u8 nr;
50
                struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
51
 
52
                llc->remote_busy_flag = 0;
53
                del_timer(&llc->busy_state_timer.timer);
54
                nr = LLC_I_GET_NR(pdu);
55
                llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
56
        }
57
        return 0;
58
}
59
 
60
int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
61
{
62
        struct llc_conn_state_ev *ev = llc_conn_ev(skb);
63
 
64
        ev->ind_prim = LLC_CONN_PRIM;
65
        return 0;
66
}
67
 
68
int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
69
{
70
        struct llc_conn_state_ev *ev = llc_conn_ev(skb);
71
 
72
        ev->cfm_prim = LLC_CONN_PRIM;
73
        return 0;
74
}
75
 
76
static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb)
77
{
78
        struct llc_conn_state_ev *ev = llc_conn_ev(skb);
79
 
80
        ev->cfm_prim = LLC_DATA_PRIM;
81
        return 0;
82
}
83
 
84
int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb)
85
{
86
        llc_conn_rtn_pdu(sk, skb);
87
        return 0;
88
}
89
 
90
int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb)
91
{
92
        struct llc_conn_state_ev *ev = llc_conn_ev(skb);
93
        u8 reason = 0;
94
        int rc = 0;
95
 
96
        if (ev->type == LLC_CONN_EV_TYPE_PDU) {
97
                struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
98
 
99
                if (LLC_PDU_IS_RSP(pdu) &&
100
                    LLC_PDU_TYPE_IS_U(pdu) &&
101
                    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM)
102
                        reason = LLC_DISC_REASON_RX_DM_RSP_PDU;
103
                else if (LLC_PDU_IS_CMD(pdu) &&
104
                           LLC_PDU_TYPE_IS_U(pdu) &&
105
                           LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC)
106
                        reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
107
        } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)
108
                reason = LLC_DISC_REASON_ACK_TMR_EXP;
109
        else
110
                rc = -EINVAL;
111
        if (!rc) {
112
                ev->reason   = reason;
113
                ev->ind_prim = LLC_DISC_PRIM;
114
        }
115
        return rc;
116
}
117
 
118
int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb)
119
{
120
        struct llc_conn_state_ev *ev = llc_conn_ev(skb);
121
 
122
        ev->reason   = ev->status;
123
        ev->cfm_prim = LLC_DISC_PRIM;
124
        return 0;
125
}
126
 
127
int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
128
{
129
        u8 reason = 0;
130
        int rc = 1;
131
        struct llc_conn_state_ev *ev = llc_conn_ev(skb);
132
        struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
133
        struct llc_sock *llc = llc_sk(sk);
134
 
135
        switch (ev->type) {
136
        case LLC_CONN_EV_TYPE_PDU:
137
                if (LLC_PDU_IS_RSP(pdu) &&
138
                    LLC_PDU_TYPE_IS_U(pdu) &&
139
                    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR) {
140
                        reason = LLC_RESET_REASON_LOCAL;
141
                        rc = 0;
142
                } else if (LLC_PDU_IS_CMD(pdu) &&
143
                           LLC_PDU_TYPE_IS_U(pdu) &&
144
                           LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) {
145
                        reason = LLC_RESET_REASON_REMOTE;
146
                        rc = 0;
147
                }
148
                break;
149
        case LLC_CONN_EV_TYPE_ACK_TMR:
150
        case LLC_CONN_EV_TYPE_P_TMR:
151
        case LLC_CONN_EV_TYPE_REJ_TMR:
152
        case LLC_CONN_EV_TYPE_BUSY_TMR:
153
                if (llc->retry_count > llc->n2) {
154
                        reason = LLC_RESET_REASON_LOCAL;
155
                        rc = 0;
156
                }
157
                break;
158
        }
159
        if (!rc) {
160
                ev->reason   = reason;
161
                ev->ind_prim = LLC_RESET_PRIM;
162
        }
163
        return rc;
164
}
165
 
166
int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb)
167
{
168
        struct llc_conn_state_ev *ev = llc_conn_ev(skb);
169
 
170
        ev->reason   = 0;
171
        ev->cfm_prim = LLC_RESET_PRIM;
172
        return 0;
173
}
174
 
175
int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
176
                                            struct sk_buff *skb)
177
{
178
        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
179
 
180
        if (LLC_PDU_IS_RSP(pdu) &&
181
            LLC_PDU_TYPE_IS_I(pdu) &&
182
            LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf)
183
                llc_conn_ac_clear_remote_busy(sk, skb);
184
        return 0;
185
}
186
 
187
int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
188
                                               struct sk_buff *skb)
189
{
190
        struct llc_sock *llc = llc_sk(sk);
191
 
192
        if (llc->data_flag == 2)
193
                del_timer(&llc->rej_sent_timer.timer);
194
        return 0;
195
}
196
 
197
int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
198
{
199
        int rc = -ENOBUFS;
200
        struct llc_sock *llc = llc_sk(sk);
201
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
202
 
203
        if (nskb) {
204
                struct llc_sap *sap = llc->sap;
205
 
206
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
207
                                    llc->daddr.lsap, LLC_PDU_CMD);
208
                llc_pdu_init_as_disc_cmd(nskb, 1);
209
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
210
                if (unlikely(rc))
211
                        goto free;
212
                llc_conn_send_pdu(sk, nskb);
213
                llc_conn_ac_set_p_flag_1(sk, skb);
214
        }
215
out:
216
        return rc;
217
free:
218
        kfree_skb(nskb);
219
        goto out;
220
}
221
 
222
int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
223
{
224
        int rc = -ENOBUFS;
225
        struct llc_sock *llc = llc_sk(sk);
226
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
227
 
228
        if (nskb) {
229
                struct llc_sap *sap = llc->sap;
230
                u8 f_bit;
231
 
232
                llc_pdu_decode_pf_bit(skb, &f_bit);
233
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
234
                                    llc->daddr.lsap, LLC_PDU_RSP);
235
                llc_pdu_init_as_dm_rsp(nskb, f_bit);
236
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
237
                if (unlikely(rc))
238
                        goto free;
239
                llc_conn_send_pdu(sk, nskb);
240
        }
241
out:
242
        return rc;
243
free:
244
        kfree_skb(nskb);
245
        goto out;
246
}
247
 
248
int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
249
{
250
        int rc = -ENOBUFS;
251
        struct llc_sock *llc = llc_sk(sk);
252
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
253
 
254
        if (nskb) {
255
                struct llc_sap *sap = llc->sap;
256
 
257
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
258
                                    llc->daddr.lsap, LLC_PDU_RSP);
259
                llc_pdu_init_as_dm_rsp(nskb, 1);
260
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
261
                if (unlikely(rc))
262
                        goto free;
263
                llc_conn_send_pdu(sk, nskb);
264
        }
265
out:
266
        return rc;
267
free:
268
        kfree_skb(nskb);
269
        goto out;
270
}
271
 
272
int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
273
{
274
        u8 f_bit;
275
        int rc = -ENOBUFS;
276
        struct sk_buff *nskb;
277
        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
278
        struct llc_sock *llc = llc_sk(sk);
279
 
280
        llc->rx_pdu_hdr = *((u32 *)pdu);
281
        if (LLC_PDU_IS_CMD(pdu))
282
                llc_pdu_decode_pf_bit(skb, &f_bit);
283
        else
284
                f_bit = 0;
285
        nskb = llc_alloc_frame(sk, llc->dev);
286
        if (nskb) {
287
                struct llc_sap *sap = llc->sap;
288
 
289
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
290
                                    llc->daddr.lsap, LLC_PDU_RSP);
291
                llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
292
                                         llc->vR, INCORRECT);
293
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
294
                if (unlikely(rc))
295
                        goto free;
296
                llc_conn_send_pdu(sk, nskb);
297
        }
298
out:
299
        return rc;
300
free:
301
        kfree_skb(nskb);
302
        goto out;
303
}
304
 
305
int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
306
{
307
        int rc = -ENOBUFS;
308
        struct llc_sock *llc = llc_sk(sk);
309
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
310
 
311
        if (nskb) {
312
                struct llc_sap *sap = llc->sap;
313
                struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;
314
 
315
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
316
                                    llc->daddr.lsap, LLC_PDU_RSP);
317
                llc_pdu_init_as_frmr_rsp(nskb, pdu, 0, llc->vS,
318
                                         llc->vR, INCORRECT);
319
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
320
                if (unlikely(rc))
321
                        goto free;
322
                llc_conn_send_pdu(sk, nskb);
323
        }
324
out:
325
        return rc;
326
free:
327
        kfree_skb(nskb);
328
        goto out;
329
}
330
 
331
int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
332
{
333
        u8 f_bit;
334
        int rc = -ENOBUFS;
335
        struct sk_buff *nskb;
336
        struct llc_sock *llc = llc_sk(sk);
337
 
338
        llc_pdu_decode_pf_bit(skb, &f_bit);
339
        nskb = llc_alloc_frame(sk, llc->dev);
340
        if (nskb) {
341
                struct llc_sap *sap = llc->sap;
342
                struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
343
 
344
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
345
                                    llc->daddr.lsap, LLC_PDU_RSP);
346
                llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
347
                                         llc->vR, INCORRECT);
348
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
349
                if (unlikely(rc))
350
                        goto free;
351
                llc_conn_send_pdu(sk, nskb);
352
        }
353
out:
354
        return rc;
355
free:
356
        kfree_skb(nskb);
357
        goto out;
358
}
359
 
360
int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
361
{
362
        int rc;
363
        struct llc_sock *llc = llc_sk(sk);
364
        struct llc_sap *sap = llc->sap;
365
 
366
        llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
367
                            llc->daddr.lsap, LLC_PDU_CMD);
368
        llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
369
        rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
370
        if (likely(!rc)) {
371
                llc_conn_send_pdu(sk, skb);
372
                llc_conn_ac_inc_vs_by_1(sk, skb);
373
        }
374
        return rc;
375
}
376
 
377
static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
378
{
379
        int rc;
380
        struct llc_sock *llc = llc_sk(sk);
381
        struct llc_sap *sap = llc->sap;
382
 
383
        llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
384
                            llc->daddr.lsap, LLC_PDU_CMD);
385
        llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
386
        rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
387
        if (likely(!rc)) {
388
                llc_conn_send_pdu(sk, skb);
389
                llc_conn_ac_inc_vs_by_1(sk, skb);
390
        }
391
        return rc;
392
}
393
 
394
int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
395
{
396
        int rc;
397
        struct llc_sock *llc = llc_sk(sk);
398
        struct llc_sap *sap = llc->sap;
399
 
400
        llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
401
                            llc->daddr.lsap, LLC_PDU_CMD);
402
        llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
403
        rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
404
        if (likely(!rc)) {
405
                llc_conn_send_pdu(sk, skb);
406
                llc_conn_ac_inc_vs_by_1(sk, skb);
407
        }
408
        return 0;
409
}
410
 
411
int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
412
{
413
        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
414
        u8 nr = LLC_I_GET_NR(pdu);
415
 
416
        llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
417
        return 0;
418
}
419
 
420
int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
421
                                                struct sk_buff *skb)
422
{
423
        u8 nr;
424
        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
425
        int rc = -ENOBUFS;
426
        struct llc_sock *llc = llc_sk(sk);
427
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
428
 
429
        if (nskb) {
430
                struct llc_sap *sap = llc->sap;
431
 
432
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
433
                                    llc->daddr.lsap, LLC_PDU_RSP);
434
                llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
435
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
436
                if (likely(!rc))
437
                        llc_conn_send_pdu(sk, nskb);
438
                else
439
                        kfree_skb(skb);
440
        }
441
        if (rc) {
442
                nr = LLC_I_GET_NR(pdu);
443
                rc = 0;
444
                llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
445
        }
446
        return rc;
447
}
448
 
449
int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
450
{
451
        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
452
        u8 nr = LLC_I_GET_NR(pdu);
453
 
454
        llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);
455
        return 0;
456
}
457
 
458
int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
459
{
460
        int rc = -ENOBUFS;
461
        struct llc_sock *llc = llc_sk(sk);
462
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
463
 
464
        if (nskb) {
465
                struct llc_sap *sap = llc->sap;
466
 
467
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
468
                                    llc->daddr.lsap, LLC_PDU_CMD);
469
                llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
470
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
471
                if (unlikely(rc))
472
                        goto free;
473
                llc_conn_send_pdu(sk, nskb);
474
        }
475
out:
476
        return rc;
477
free:
478
        kfree_skb(nskb);
479
        goto out;
480
}
481
 
482
int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
483
{
484
        int rc = -ENOBUFS;
485
        struct llc_sock *llc = llc_sk(sk);
486
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
487
 
488
        if (nskb) {
489
                struct llc_sap *sap = llc->sap;
490
 
491
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
492
                                    llc->daddr.lsap, LLC_PDU_RSP);
493
                llc_pdu_init_as_rej_rsp(nskb, 1, llc->vR);
494
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
495
                if (unlikely(rc))
496
                        goto free;
497
                llc_conn_send_pdu(sk, nskb);
498
        }
499
out:
500
        return rc;
501
free:
502
        kfree_skb(nskb);
503
        goto out;
504
}
505
 
506
int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
507
{
508
        int rc = -ENOBUFS;
509
        struct llc_sock *llc = llc_sk(sk);
510
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
511
 
512
        if (nskb) {
513
                struct llc_sap *sap = llc->sap;
514
 
515
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
516
                                    llc->daddr.lsap, LLC_PDU_RSP);
517
                llc_pdu_init_as_rej_rsp(nskb, 0, llc->vR);
518
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
519
                if (unlikely(rc))
520
                        goto free;
521
                llc_conn_send_pdu(sk, nskb);
522
        }
523
out:
524
        return rc;
525
free:
526
        kfree_skb(nskb);
527
        goto out;
528
}
529
 
530
int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
531
{
532
        int rc = -ENOBUFS;
533
        struct llc_sock *llc = llc_sk(sk);
534
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
535
 
536
        if (nskb) {
537
                struct llc_sap *sap = llc->sap;
538
 
539
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
540
                                    llc->daddr.lsap, LLC_PDU_CMD);
541
                llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
542
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
543
                if (unlikely(rc))
544
                        goto free;
545
                llc_conn_send_pdu(sk, nskb);
546
        }
547
out:
548
        return rc;
549
free:
550
        kfree_skb(nskb);
551
        goto out;
552
}
553
 
554
int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
555
{
556
        int rc = -ENOBUFS;
557
        struct llc_sock *llc = llc_sk(sk);
558
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
559
 
560
        if (nskb) {
561
                struct llc_sap *sap = llc->sap;
562
 
563
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
564
                                    llc->daddr.lsap, LLC_PDU_RSP);
565
                llc_pdu_init_as_rnr_rsp(nskb, 1, llc->vR);
566
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
567
                if (unlikely(rc))
568
                        goto free;
569
                llc_conn_send_pdu(sk, nskb);
570
        }
571
out:
572
        return rc;
573
free:
574
        kfree_skb(nskb);
575
        goto out;
576
}
577
 
578
int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
579
{
580
        int rc = -ENOBUFS;
581
        struct llc_sock *llc = llc_sk(sk);
582
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
583
 
584
        if (nskb) {
585
                struct llc_sap *sap = llc->sap;
586
 
587
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
588
                                    llc->daddr.lsap, LLC_PDU_RSP);
589
                llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
590
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
591
                if (unlikely(rc))
592
                        goto free;
593
                llc_conn_send_pdu(sk, nskb);
594
        }
595
out:
596
        return rc;
597
free:
598
        kfree_skb(nskb);
599
        goto out;
600
}
601
 
602
int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
603
{
604
        struct llc_sock *llc = llc_sk(sk);
605
 
606
        if (!llc->remote_busy_flag) {
607
                llc->remote_busy_flag = 1;
608
                mod_timer(&llc->busy_state_timer.timer,
609
                         jiffies + llc->busy_state_timer.expire);
610
        }
611
        return 0;
612
}
613
 
614
int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
615
{
616
        int rc = -ENOBUFS;
617
        struct llc_sock *llc = llc_sk(sk);
618
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
619
 
620
        if (nskb) {
621
                struct llc_sap *sap = llc->sap;
622
 
623
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
624
                                    llc->daddr.lsap, LLC_PDU_RSP);
625
                llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
626
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
627
                if (unlikely(rc))
628
                        goto free;
629
                llc_conn_send_pdu(sk, nskb);
630
        }
631
out:
632
        return rc;
633
free:
634
        kfree_skb(nskb);
635
        goto out;
636
}
637
 
638
int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
639
{
640
        int rc = -ENOBUFS;
641
        struct llc_sock *llc = llc_sk(sk);
642
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
643
 
644
        if (nskb) {
645
                struct llc_sap *sap = llc->sap;
646
 
647
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
648
                                    llc->daddr.lsap, LLC_PDU_CMD);
649
                llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
650
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
651
                if (unlikely(rc))
652
                        goto free;
653
                llc_conn_send_pdu(sk, nskb);
654
        }
655
out:
656
        return rc;
657
free:
658
        kfree_skb(nskb);
659
        goto out;
660
}
661
 
662
int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
663
{
664
        int rc = -ENOBUFS;
665
        struct llc_sock *llc = llc_sk(sk);
666
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
667
 
668
        if (nskb) {
669
                struct llc_sap *sap = llc->sap;
670
                u8 f_bit = 1;
671
 
672
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
673
                                    llc->daddr.lsap, LLC_PDU_RSP);
674
                llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
675
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
676
                if (unlikely(rc))
677
                        goto free;
678
                llc_conn_send_pdu(sk, nskb);
679
        }
680
out:
681
        return rc;
682
free:
683
        kfree_skb(nskb);
684
        goto out;
685
}
686
 
687
int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
688
{
689
        int rc = -ENOBUFS;
690
        struct llc_sock *llc = llc_sk(sk);
691
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
692
 
693
        if (nskb) {
694
                struct llc_sap *sap = llc->sap;
695
 
696
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
697
                                    llc->daddr.lsap, LLC_PDU_RSP);
698
                llc_pdu_init_as_rr_rsp(nskb, 1, llc->vR);
699
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
700
                if (unlikely(rc))
701
                        goto free;
702
                llc_conn_send_pdu(sk, nskb);
703
        }
704
out:
705
        return rc;
706
free:
707
        kfree_skb(nskb);
708
        goto out;
709
}
710
 
711
int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
712
{
713
        int rc = -ENOBUFS;
714
        struct llc_sock *llc = llc_sk(sk);
715
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
716
 
717
        if (nskb) {
718
                struct llc_sap *sap = llc->sap;
719
 
720
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
721
                                    llc->daddr.lsap, LLC_PDU_RSP);
722
                llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
723
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
724
                if (unlikely(rc))
725
                        goto free;
726
                llc_conn_send_pdu(sk, nskb);
727
        }
728
out:
729
        return rc;
730
free:
731
        kfree_skb(nskb);
732
        goto out;
733
}
734
 
735
int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
736
{
737
        int rc = -ENOBUFS;
738
        struct llc_sock *llc = llc_sk(sk);
739
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
740
 
741
        if (nskb) {
742
                struct llc_sap *sap = llc->sap;
743
 
744
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
745
                                    llc->daddr.lsap, LLC_PDU_RSP);
746
                llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
747
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
748
                if (unlikely(rc))
749
                        goto free;
750
                llc_conn_send_pdu(sk, nskb);
751
        }
752
out:
753
        return rc;
754
free:
755
        kfree_skb(nskb);
756
        goto out;
757
}
758
 
759
void llc_conn_set_p_flag(struct sock *sk, u8 value)
760
{
761
        int state_changed = llc_sk(sk)->p_flag && !value;
762
 
763
        llc_sk(sk)->p_flag = value;
764
 
765
        if (state_changed)
766
                sk->sk_state_change(sk);
767
}
768
 
769
int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
770
{
771
        int rc = -ENOBUFS;
772
        struct llc_sock *llc = llc_sk(sk);
773
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
774
 
775
        if (nskb) {
776
                struct llc_sap *sap = llc->sap;
777
                u8 *dmac = llc->daddr.mac;
778
 
779
                if (llc->dev->flags & IFF_LOOPBACK)
780
                        dmac = llc->dev->dev_addr;
781
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
782
                                    llc->daddr.lsap, LLC_PDU_CMD);
783
                llc_pdu_init_as_sabme_cmd(nskb, 1);
784
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
785
                if (unlikely(rc))
786
                        goto free;
787
                llc_conn_send_pdu(sk, nskb);
788
                llc_conn_set_p_flag(sk, 1);
789
        }
790
out:
791
        return rc;
792
free:
793
        kfree_skb(nskb);
794
        goto out;
795
}
796
 
797
int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
798
{
799
        u8 f_bit;
800
        int rc = -ENOBUFS;
801
        struct llc_sock *llc = llc_sk(sk);
802
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
803
 
804
        llc_pdu_decode_pf_bit(skb, &f_bit);
805
        if (nskb) {
806
                struct llc_sap *sap = llc->sap;
807
 
808
                nskb->dev = llc->dev;
809
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
810
                                    llc->daddr.lsap, LLC_PDU_RSP);
811
                llc_pdu_init_as_ua_rsp(nskb, f_bit);
812
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
813
                if (unlikely(rc))
814
                        goto free;
815
                llc_conn_send_pdu(sk, nskb);
816
        }
817
out:
818
        return rc;
819
free:
820
        kfree_skb(nskb);
821
        goto out;
822
}
823
 
824
int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb)
825
{
826
        llc_sk(sk)->s_flag = 0;
827
        return 0;
828
}
829
 
830
int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb)
831
{
832
        llc_sk(sk)->s_flag = 1;
833
        return 0;
834
}
835
 
836
int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
837
{
838
        struct llc_sock *llc = llc_sk(sk);
839
 
840
        llc_conn_set_p_flag(sk, 1);
841
        mod_timer(&llc->pf_cycle_timer.timer,
842
                  jiffies + llc->pf_cycle_timer.expire);
843
        return 0;
844
}
845
 
846
/**
847
 *      llc_conn_ac_send_ack_if_needed - check if ack is needed
848
 *      @sk: current connection structure
849
 *      @skb: current event
850
 *
851
 *      Checks number of received PDUs which have not been acknowledged, yet,
852
 *      If number of them reaches to "npta"(Number of PDUs To Acknowledge) then
853
 *      sends an RR response as acknowledgement for them.  Returns 0 for
854
 *      success, 1 otherwise.
855
 */
856
int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb)
857
{
858
        u8 pf_bit;
859
        struct llc_sock *llc = llc_sk(sk);
860
 
861
        llc_pdu_decode_pf_bit(skb, &pf_bit);
862
        llc->ack_pf |= pf_bit & 1;
863
        if (!llc->ack_must_be_send) {
864
                llc->first_pdu_Ns = llc->vR;
865
                llc->ack_must_be_send = 1;
866
                llc->ack_pf = pf_bit & 1;
867
        }
868
        if (((llc->vR - llc->first_pdu_Ns + 1 + LLC_2_SEQ_NBR_MODULO)
869
                        % LLC_2_SEQ_NBR_MODULO) >= llc->npta) {
870
                llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, skb);
871
                llc->ack_must_be_send   = 0;
872
                llc->ack_pf             = 0;
873
                llc_conn_ac_inc_npta_value(sk, skb);
874
        }
875
        return 0;
876
}
877
 
878
/**
879
 *      llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag
880
 *      @sk: current connection structure
881
 *      @skb: current event
882
 *
883
 *      This action resets ack_must_be_send flag of given connection, this flag
884
 *      indicates if there is any PDU which has not been acknowledged yet.
885
 *      Returns 0 for success, 1 otherwise.
886
 */
887
int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb)
888
{
889
        llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0;
890
        return 0;
891
}
892
 
893
/**
894
 *      llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs
895
 *      @sk: current connection structure
896
 *      @skb: current event
897
 *
898
 *      Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to
899
 *      all received PDUs which have not been acknowledged, yet. ack_pf flag is
900
 *      set to one if one PDU with p-bit set to one is received.  Returns 0 for
901
 *      success, 1 otherwise.
902
 */
903
static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
904
                                              struct sk_buff *skb)
905
{
906
        int rc;
907
        struct llc_sock *llc = llc_sk(sk);
908
        struct llc_sap *sap = llc->sap;
909
 
910
        llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
911
                            llc->daddr.lsap, LLC_PDU_RSP);
912
        llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
913
        rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
914
        if (likely(!rc)) {
915
                llc_conn_send_pdu(sk, skb);
916
                llc_conn_ac_inc_vs_by_1(sk, skb);
917
        }
918
        return rc;
919
}
920
 
921
/**
922
 *      llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs
923
 *      @sk: current connection structure.
924
 *      @skb: current event.
925
 *
926
 *      This action sends an I-format PDU as acknowledge to received PDUs which
927
 *      have not been acknowledged, yet, if there is any. By using of this
928
 *      action number of acknowledgements decreases, this technic is called
929
 *      piggy backing. Returns 0 for success, 1 otherwise.
930
 */
931
int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
932
{
933
        struct llc_sock *llc = llc_sk(sk);
934
 
935
        if (llc->ack_must_be_send) {
936
                llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
937
                llc->ack_must_be_send = 0 ;
938
                llc->ack_pf = 0;
939
        } else
940
                llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
941
        return 0;
942
}
943
 
944
/**
945
 *      llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked
946
 *      @sk: current connection structure.
947
 *      @skb: current event.
948
 *
949
 *      This action sends an RR response with f-bit set to ack_pf flag as
950
 *      acknowledge to all received PDUs which have not been acknowledged, yet,
951
 *      if there is any. ack_pf flag indicates if a PDU has been received with
952
 *      p-bit set to one. Returns 0 for success, 1 otherwise.
953
 */
954
static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
955
                                               struct sk_buff *skb)
956
{
957
        int rc = -ENOBUFS;
958
        struct llc_sock *llc = llc_sk(sk);
959
        struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
960
 
961
        if (nskb) {
962
                struct llc_sap *sap = llc->sap;
963
 
964
                llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
965
                                    llc->daddr.lsap, LLC_PDU_RSP);
966
                llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
967
                rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
968
                if (unlikely(rc))
969
                        goto free;
970
                llc_conn_send_pdu(sk, nskb);
971
        }
972
out:
973
        return rc;
974
free:
975
        kfree_skb(nskb);
976
        goto out;
977
}
978
 
979
/**
980
 *      llc_conn_ac_inc_npta_value - tries to make value of npta greater
981
 *      @sk: current connection structure.
982
 *      @skb: current event.
983
 *
984
 *      After "inc_cntr" times calling of this action, "npta" increase by one.
985
 *      this action tries to make vale of "npta" greater as possible; number of
986
 *      acknowledgements decreases by increasing of "npta". Returns 0 for
987
 *      success, 1 otherwise.
988
 */
989
static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb)
990
{
991
        struct llc_sock *llc = llc_sk(sk);
992
 
993
        if (!llc->inc_cntr) {
994
                llc->dec_step = 0;
995
                llc->dec_cntr = llc->inc_cntr = 2;
996
                ++llc->npta;
997
                if (llc->npta > (u8) ~LLC_2_SEQ_NBR_MODULO)
998
                        llc->npta = (u8) ~LLC_2_SEQ_NBR_MODULO;
999
        } else
1000
                --llc->inc_cntr;
1001
        return 0;
1002
}
1003
 
1004
/**
1005
 *      llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one
1006
 *      @sk: current connection structure.
1007
 *      @skb: current event.
1008
 *
1009
 *      After receiving "dec_cntr" times RR command, this action decreases
1010
 *      "npta" by one. Returns 0 for success, 1 otherwise.
1011
 */
1012
int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb)
1013
{
1014
        struct llc_sock *llc = llc_sk(sk);
1015
 
1016
        if (!llc->connect_step && !llc->remote_busy_flag) {
1017
                if (!llc->dec_step) {
1018
                        if (!llc->dec_cntr) {
1019
                                llc->inc_cntr = llc->dec_cntr = 2;
1020
                                if (llc->npta > 0)
1021
                                        llc->npta = llc->npta - 1;
1022
                        } else
1023
                                llc->dec_cntr -=1;
1024
                }
1025
        } else
1026
                llc->connect_step = 0 ;
1027
        return 0;
1028
}
1029
 
1030
/**
1031
 *      llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one
1032
 *      @sk: current connection structure.
1033
 *      @skb: current event.
1034
 *
1035
 *      After receiving "dec_cntr" times RNR command, this action decreases
1036
 *      "npta" by one. Returns 0 for success, 1 otherwise.
1037
 */
1038
int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb)
1039
{
1040
        struct llc_sock *llc = llc_sk(sk);
1041
 
1042
        if (llc->remote_busy_flag)
1043
                if (!llc->dec_step) {
1044
                        if (!llc->dec_cntr) {
1045
                                llc->inc_cntr = llc->dec_cntr = 2;
1046
                                if (llc->npta > 0)
1047
                                        --llc->npta;
1048
                        } else
1049
                                --llc->dec_cntr;
1050
                }
1051
        return 0;
1052
}
1053
 
1054
/**
1055
 *      llc_conn_ac_dec_tx_win_size - decreases tx window size
1056
 *      @sk: current connection structure.
1057
 *      @skb: current event.
1058
 *
1059
 *      After receiving of a REJ command or response, transmit window size is
1060
 *      decreased by number of PDUs which are outstanding yet. Returns 0 for
1061
 *      success, 1 otherwise.
1062
 */
1063
int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb)
1064
{
1065
        struct llc_sock *llc = llc_sk(sk);
1066
        u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q);
1067
 
1068
        if (llc->k - unacked_pdu < 1)
1069
                llc->k = 1;
1070
        else
1071
                llc->k -= unacked_pdu;
1072
        return 0;
1073
}
1074
 
1075
/**
1076
 *      llc_conn_ac_inc_tx_win_size - tx window size is inc by 1
1077
 *      @sk: current connection structure.
1078
 *      @skb: current event.
1079
 *
1080
 *      After receiving an RR response with f-bit set to one, transmit window
1081
 *      size is increased by one. Returns 0 for success, 1 otherwise.
1082
 */
1083
int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb)
1084
{
1085
        struct llc_sock *llc = llc_sk(sk);
1086
 
1087
        llc->k += 1;
1088
        if (llc->k > (u8) ~LLC_2_SEQ_NBR_MODULO)
1089
                llc->k = (u8) ~LLC_2_SEQ_NBR_MODULO;
1090
        return 0;
1091
}
1092
 
1093
int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
1094
{
1095
        struct llc_sock *llc = llc_sk(sk);
1096
 
1097
        del_timer(&llc->pf_cycle_timer.timer);
1098
        del_timer(&llc->ack_timer.timer);
1099
        del_timer(&llc->rej_sent_timer.timer);
1100
        del_timer(&llc->busy_state_timer.timer);
1101
        llc->ack_must_be_send = 0;
1102
        llc->ack_pf = 0;
1103
        return 0;
1104
}
1105
 
1106
int llc_conn_ac_stop_other_timers(struct sock *sk, struct sk_buff *skb)
1107
{
1108
        struct llc_sock *llc = llc_sk(sk);
1109
 
1110
        del_timer(&llc->rej_sent_timer.timer);
1111
        del_timer(&llc->pf_cycle_timer.timer);
1112
        del_timer(&llc->busy_state_timer.timer);
1113
        llc->ack_must_be_send = 0;
1114
        llc->ack_pf = 0;
1115
        return 0;
1116
}
1117
 
1118
int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb)
1119
{
1120
        struct llc_sock *llc = llc_sk(sk);
1121
 
1122
        mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire);
1123
        return 0;
1124
}
1125
 
1126
int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb)
1127
{
1128
        struct llc_sock *llc = llc_sk(sk);
1129
 
1130
        mod_timer(&llc->rej_sent_timer.timer,
1131
                  jiffies + llc->rej_sent_timer.expire);
1132
        return 0;
1133
}
1134
 
1135
int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
1136
                                             struct sk_buff *skb)
1137
{
1138
        struct llc_sock *llc = llc_sk(sk);
1139
 
1140
        if (!timer_pending(&llc->ack_timer.timer))
1141
                mod_timer(&llc->ack_timer.timer,
1142
                          jiffies + llc->ack_timer.expire);
1143
        return 0;
1144
}
1145
 
1146
int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb)
1147
{
1148
        del_timer(&llc_sk(sk)->ack_timer.timer);
1149
        return 0;
1150
}
1151
 
1152
int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb)
1153
{
1154
        struct llc_sock *llc = llc_sk(sk);
1155
 
1156
        del_timer(&llc->pf_cycle_timer.timer);
1157
        llc_conn_set_p_flag(sk, 0);
1158
        return 0;
1159
}
1160
 
1161
int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb)
1162
{
1163
        del_timer(&llc_sk(sk)->rej_sent_timer.timer);
1164
        return 0;
1165
}
1166
 
1167
int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb)
1168
{
1169
        int acked;
1170
        u16 unacked = 0;
1171
        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1172
        struct llc_sock *llc = llc_sk(sk);
1173
 
1174
        llc->last_nr = PDU_SUPV_GET_Nr(pdu);
1175
        acked = llc_conn_remove_acked_pdus(sk, llc->last_nr, &unacked);
1176
        /* On loopback we don't queue I frames in unack_pdu_q queue. */
1177
        if (acked > 0 || (llc->dev->flags & IFF_LOOPBACK)) {
1178
                llc->retry_count = 0;
1179
                del_timer(&llc->ack_timer.timer);
1180
                if (llc->failed_data_req) {
1181
                        /* already, we did not accept data from upper layer
1182
                         * (tx_window full or unacceptable state). Now, we
1183
                         * can send data and must inform to upper layer.
1184
                         */
1185
                        llc->failed_data_req = 0;
1186
                        llc_conn_ac_data_confirm(sk, skb);
1187
                }
1188
                if (unacked)
1189
                        mod_timer(&llc->ack_timer.timer,
1190
                                  jiffies + llc->ack_timer.expire);
1191
        } else if (llc->failed_data_req) {
1192
                u8 f_bit;
1193
 
1194
                llc_pdu_decode_pf_bit(skb, &f_bit);
1195
                if (f_bit == 1) {
1196
                        llc->failed_data_req = 0;
1197
                        llc_conn_ac_data_confirm(sk, skb);
1198
                }
1199
        }
1200
        return 0;
1201
}
1202
 
1203
int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb)
1204
{
1205
        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1206
 
1207
        if (LLC_PDU_IS_RSP(pdu)) {
1208
                u8 f_bit;
1209
 
1210
                llc_pdu_decode_pf_bit(skb, &f_bit);
1211
                if (f_bit) {
1212
                        llc_conn_set_p_flag(sk, 0);
1213
                        llc_conn_ac_stop_p_timer(sk, skb);
1214
                }
1215
        }
1216
        return 0;
1217
}
1218
 
1219
int llc_conn_ac_set_data_flag_2(struct sock *sk, struct sk_buff *skb)
1220
{
1221
        llc_sk(sk)->data_flag = 2;
1222
        return 0;
1223
}
1224
 
1225
int llc_conn_ac_set_data_flag_0(struct sock *sk, struct sk_buff *skb)
1226
{
1227
        llc_sk(sk)->data_flag = 0;
1228
        return 0;
1229
}
1230
 
1231
int llc_conn_ac_set_data_flag_1(struct sock *sk, struct sk_buff *skb)
1232
{
1233
        llc_sk(sk)->data_flag = 1;
1234
        return 0;
1235
}
1236
 
1237
int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
1238
                                                  struct sk_buff *skb)
1239
{
1240
        if (!llc_sk(sk)->data_flag)
1241
                llc_sk(sk)->data_flag = 1;
1242
        return 0;
1243
}
1244
 
1245
int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb)
1246
{
1247
        llc_conn_set_p_flag(sk, 0);
1248
        return 0;
1249
}
1250
 
1251
static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb)
1252
{
1253
        llc_conn_set_p_flag(sk, 1);
1254
        return 0;
1255
}
1256
 
1257
int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct sk_buff *skb)
1258
{
1259
        llc_sk(sk)->remote_busy_flag = 0;
1260
        return 0;
1261
}
1262
 
1263
int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct sk_buff *skb)
1264
{
1265
        llc_sk(sk)->cause_flag = 0;
1266
        return 0;
1267
}
1268
 
1269
int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct sk_buff *skb)
1270
{
1271
        llc_sk(sk)->cause_flag = 1;
1272
        return 0;
1273
}
1274
 
1275
int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct sk_buff *skb)
1276
{
1277
        llc_sk(sk)->retry_count = 0;
1278
        return 0;
1279
}
1280
 
1281
int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, struct sk_buff *skb)
1282
{
1283
        llc_sk(sk)->retry_count++;
1284
        return 0;
1285
}
1286
 
1287
int llc_conn_ac_set_vr_0(struct sock *sk, struct sk_buff *skb)
1288
{
1289
        llc_sk(sk)->vR = 0;
1290
        return 0;
1291
}
1292
 
1293
int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct sk_buff *skb)
1294
{
1295
        llc_sk(sk)->vR = PDU_GET_NEXT_Vr(llc_sk(sk)->vR);
1296
        return 0;
1297
}
1298
 
1299
int llc_conn_ac_set_vs_0(struct sock *sk, struct sk_buff *skb)
1300
{
1301
        llc_sk(sk)->vS = 0;
1302
        return 0;
1303
}
1304
 
1305
int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb)
1306
{
1307
        llc_sk(sk)->vS = llc_sk(sk)->last_nr;
1308
        return 0;
1309
}
1310
 
1311
static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
1312
{
1313
        llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO;
1314
        return 0;
1315
}
1316
 
1317
static void llc_conn_tmr_common_cb(unsigned long timeout_data, u8 type)
1318
{
1319
        struct sock *sk = (struct sock *)timeout_data;
1320
        struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
1321
 
1322
        bh_lock_sock(sk);
1323
        if (skb) {
1324
                struct llc_conn_state_ev *ev = llc_conn_ev(skb);
1325
 
1326
                skb_set_owner_r(skb, sk);
1327
                ev->type = type;
1328
                llc_process_tmr_ev(sk, skb);
1329
        }
1330
        bh_unlock_sock(sk);
1331
}
1332
 
1333
void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
1334
{
1335
        llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR);
1336
}
1337
 
1338
void llc_conn_busy_tmr_cb(unsigned long timeout_data)
1339
{
1340
        llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR);
1341
}
1342
 
1343
void llc_conn_ack_tmr_cb(unsigned long timeout_data)
1344
{
1345
        llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR);
1346
}
1347
 
1348
void llc_conn_rej_tmr_cb(unsigned long timeout_data)
1349
{
1350
        llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR);
1351
}
1352
 
1353
int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
1354
{
1355
        llc_sk(sk)->X = llc_sk(sk)->vS;
1356
        llc_conn_ac_set_vs_nr(sk, skb);
1357
        return 0;
1358
}
1359
 
1360
int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb)
1361
{
1362
        struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
1363
        u8 nr = PDU_SUPV_GET_Nr(pdu);
1364
 
1365
        if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
1366
                llc_conn_ac_set_vs_nr(sk, skb);
1367
        return 0;
1368
}
1369
 
1370
/*
1371
 * Non-standard actions; these not contained in IEEE specification; for
1372
 * our own usage
1373
 */
1374
/**
1375
 *      llc_conn_disc - removes connection from SAP list and frees it
1376
 *      @sk: closed connection
1377
 *      @skb: occurred event
1378
 */
1379
int llc_conn_disc(struct sock *sk, struct sk_buff *skb)
1380
{
1381
        /* FIXME: this thing seems to want to die */
1382
        return 0;
1383
}
1384
 
1385
/**
1386
 *      llc_conn_reset - resets connection
1387
 *      @sk : reseting connection.
1388
 *      @skb: occurred event.
1389
 *
1390
 *      Stop all timers, empty all queues and reset all flags.
1391
 */
1392
int llc_conn_reset(struct sock *sk, struct sk_buff *skb)
1393
{
1394
        llc_sk_reset(sk);
1395
        return 0;
1396
}
1397
 
1398
/**
1399
 *      llc_circular_between - designates that b is between a and c or not
1400
 *      @a: lower bound
1401
 *      @b: element to see if is between a and b
1402
 *      @c: upper bound
1403
 *
1404
 *      This function designates that b is between a and c or not (for example,
1405
 *      0 is between 127 and 1). Returns 1 if b is between a and c, 0
1406
 *      otherwise.
1407
 */
1408
u8 llc_circular_between(u8 a, u8 b, u8 c)
1409
{
1410
        b = b - a;
1411
        c = c - a;
1412
        return b <= c;
1413
}
1414
 
1415
/**
1416
 *      llc_process_tmr_ev - timer backend
1417
 *      @sk: active connection
1418
 *      @skb: occurred event
1419
 *
1420
 *      This function is called from timer callback functions. When connection
1421
 *      is busy (during sending a data frame) timer expiration event must be
1422
 *      queued. Otherwise this event can be sent to connection state machine.
1423
 *      Queued events will process by llc_backlog_rcv function after sending
1424
 *      data frame.
1425
 */
1426
static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
1427
{
1428
        if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
1429
                printk(KERN_WARNING "%s: timer called on closed connection\n",
1430
                       __FUNCTION__);
1431
                kfree_skb(skb);
1432
        } else {
1433
                if (!sock_owned_by_user(sk))
1434
                        llc_conn_state_process(sk, skb);
1435
                else {
1436
                        llc_set_backlog_type(skb, LLC_EVENT);
1437
                        sk_add_backlog(sk, skb);
1438
                }
1439
        }
1440
}

powered by: WebSVN 2.1.0

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