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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [irda/] [irlap_frame.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*********************************************************************
2
 *
3
 * Filename:      irlap_frame.c
4
 * Version:       1.0
5
 * Description:   Build and transmit IrLAP frames
6
 * Status:        Stable
7
 * Author:        Dag Brattli <dagb@cs.uit.no>
8
 * Created at:    Tue Aug 19 10:27:26 1997
9
 * Modified at:   Wed Jan  5 08:59:04 2000
10
 * Modified by:   Dag Brattli <dagb@cs.uit.no>
11
 *
12
 *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
13
 *     All Rights Reserved.
14
 *     Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15
 *
16
 *     This program is free software; you can redistribute it and/or
17
 *     modify it under the terms of the GNU General Public License as
18
 *     published by the Free Software Foundation; either version 2 of
19
 *     the License, or (at your option) any later version.
20
 *
21
 *     Neither Dag Brattli nor University of Tromsø admit liability nor
22
 *     provide warranty for any of this software. This material is
23
 *     provided "AS-IS" and at no charge.
24
 *
25
 ********************************************************************/
26
 
27
#include <linux/skbuff.h>
28
#include <linux/if.h>
29
#include <linux/if_ether.h>
30
#include <linux/netdevice.h>
31
#include <linux/irda.h>
32
 
33
#include <net/pkt_sched.h>
34
#include <net/sock.h>
35
 
36
#include <asm/byteorder.h>
37
 
38
#include <net/irda/irda.h>
39
#include <net/irda/irda_device.h>
40
#include <net/irda/irlap.h>
41
#include <net/irda/wrapper.h>
42
#include <net/irda/timer.h>
43
#include <net/irda/irlap_frame.h>
44
#include <net/irda/qos.h>
45
 
46
static void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
47
                               int command);
48
 
49
/*
50
 * Function irlap_insert_info (self, skb)
51
 *
52
 *    Insert minimum turnaround time and speed information into the skb. We
53
 *    need to do this since it's per packet relevant information. Safe to
54
 *    have this function inlined since it's only called from one place
55
 */
56
static inline void irlap_insert_info(struct irlap_cb *self,
57
                                     struct sk_buff *skb)
58
{
59
        struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
60
 
61
        /*
62
         * Insert MTT (min. turn time) and speed into skb, so that the
63
         * device driver knows which settings to use
64
         */
65
        cb->magic = LAP_MAGIC;
66
        cb->mtt = self->mtt_required;
67
        cb->next_speed = self->speed;
68
 
69
        /* Reset */
70
        self->mtt_required = 0;
71
 
72
        /*
73
         * Delay equals negotiated BOFs count, plus the number of BOFs to
74
         * force the negotiated minimum turnaround time
75
         */
76
        cb->xbofs = self->bofs_count;
77
        cb->next_xbofs = self->next_bofs;
78
        cb->xbofs_delay = self->xbofs_delay;
79
 
80
        /* Reset XBOF's delay (used only for getting min turn time) */
81
        self->xbofs_delay = 0;
82
        /* Put the correct xbofs value for the next packet */
83
        self->bofs_count = self->next_bofs;
84
}
85
 
86
/*
87
 * Function irlap_queue_xmit (self, skb)
88
 *
89
 *    A little wrapper for dev_queue_xmit, so we can insert some common
90
 *    code into it.
91
 */
92
void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb)
93
{
94
        /* Some common init stuff */
95
        skb->dev = self->netdev;
96
        skb_reset_mac_header(skb);
97
        skb_reset_network_header(skb);
98
        skb_reset_transport_header(skb);
99
        skb->protocol = htons(ETH_P_IRDA);
100
        skb->priority = TC_PRIO_BESTEFFORT;
101
 
102
        irlap_insert_info(self, skb);
103
 
104
        if (unlikely(self->mode & IRDA_MODE_MONITOR)) {
105
                IRDA_DEBUG(3, "%s(): %s is in monitor mode\n", __FUNCTION__,
106
                           self->netdev->name);
107
                dev_kfree_skb(skb);
108
                return;
109
        }
110
 
111
        dev_queue_xmit(skb);
112
}
113
 
114
/*
115
 * Function irlap_send_snrm_cmd (void)
116
 *
117
 *    Transmits a connect SNRM command frame
118
 */
119
void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
120
{
121
        struct sk_buff *tx_skb;
122
        struct snrm_frame *frame;
123
        int ret;
124
 
125
        IRDA_ASSERT(self != NULL, return;);
126
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
127
 
128
        /* Allocate frame */
129
        tx_skb = alloc_skb(sizeof(struct snrm_frame) +
130
                           IRLAP_NEGOCIATION_PARAMS_LEN,
131
                           GFP_ATOMIC);
132
        if (!tx_skb)
133
                return;
134
 
135
        frame = (struct snrm_frame *) skb_put(tx_skb, 2);
136
 
137
        /* Insert connection address field */
138
        if (qos)
139
                frame->caddr = CMD_FRAME | CBROADCAST;
140
        else
141
                frame->caddr = CMD_FRAME | self->caddr;
142
 
143
        /* Insert control field */
144
        frame->control = SNRM_CMD | PF_BIT;
145
 
146
        /*
147
         *  If we are establishing a connection then insert QoS parameters
148
         */
149
        if (qos) {
150
                skb_put(tx_skb, 9); /* 25 left */
151
                frame->saddr = cpu_to_le32(self->saddr);
152
                frame->daddr = cpu_to_le32(self->daddr);
153
 
154
                frame->ncaddr = self->caddr;
155
 
156
                ret = irlap_insert_qos_negotiation_params(self, tx_skb);
157
                if (ret < 0) {
158
                        dev_kfree_skb(tx_skb);
159
                        return;
160
                }
161
        }
162
        irlap_queue_xmit(self, tx_skb);
163
}
164
 
165
/*
166
 * Function irlap_recv_snrm_cmd (skb, info)
167
 *
168
 *    Received SNRM (Set Normal Response Mode) command frame
169
 *
170
 */
171
static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb,
172
                                struct irlap_info *info)
173
{
174
        struct snrm_frame *frame;
175
 
176
        if (pskb_may_pull(skb,sizeof(struct snrm_frame))) {
177
                frame = (struct snrm_frame *) skb->data;
178
 
179
                /* Copy the new connection address ignoring the C/R bit */
180
                info->caddr = frame->ncaddr & 0xFE;
181
 
182
                /* Check if the new connection address is valid */
183
                if ((info->caddr == 0x00) || (info->caddr == 0xfe)) {
184
                        IRDA_DEBUG(3, "%s(), invalid connection address!\n",
185
                                   __FUNCTION__);
186
                        return;
187
                }
188
 
189
                /* Copy peer device address */
190
                info->daddr = le32_to_cpu(frame->saddr);
191
                info->saddr = le32_to_cpu(frame->daddr);
192
 
193
                /* Only accept if addressed directly to us */
194
                if (info->saddr != self->saddr) {
195
                        IRDA_DEBUG(2, "%s(), not addressed to us!\n",
196
                                   __FUNCTION__);
197
                        return;
198
                }
199
                irlap_do_event(self, RECV_SNRM_CMD, skb, info);
200
        } else {
201
                /* Signal that this SNRM frame does not contain and I-field */
202
                irlap_do_event(self, RECV_SNRM_CMD, skb, NULL);
203
        }
204
}
205
 
206
/*
207
 * Function irlap_send_ua_response_frame (qos)
208
 *
209
 *    Send UA (Unnumbered Acknowledgement) frame
210
 *
211
 */
212
void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos)
213
{
214
        struct sk_buff *tx_skb;
215
        struct ua_frame *frame;
216
        int ret;
217
 
218
        IRDA_DEBUG(2, "%s() <%ld>\n", __FUNCTION__, jiffies);
219
 
220
        IRDA_ASSERT(self != NULL, return;);
221
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
222
 
223
        /* Allocate frame */
224
        tx_skb = alloc_skb(sizeof(struct ua_frame) +
225
                           IRLAP_NEGOCIATION_PARAMS_LEN,
226
                           GFP_ATOMIC);
227
        if (!tx_skb)
228
                return;
229
 
230
        frame = (struct ua_frame *) skb_put(tx_skb, 10);
231
 
232
        /* Build UA response */
233
        frame->caddr = self->caddr;
234
        frame->control = UA_RSP | PF_BIT;
235
 
236
        frame->saddr = cpu_to_le32(self->saddr);
237
        frame->daddr = cpu_to_le32(self->daddr);
238
 
239
        /* Should we send QoS negotiation parameters? */
240
        if (qos) {
241
                ret = irlap_insert_qos_negotiation_params(self, tx_skb);
242
                if (ret < 0) {
243
                        dev_kfree_skb(tx_skb);
244
                        return;
245
                }
246
        }
247
 
248
        irlap_queue_xmit(self, tx_skb);
249
}
250
 
251
 
252
/*
253
 * Function irlap_send_dm_frame (void)
254
 *
255
 *    Send disconnected mode (DM) frame
256
 *
257
 */
258
void irlap_send_dm_frame( struct irlap_cb *self)
259
{
260
        struct sk_buff *tx_skb = NULL;
261
        struct dm_frame *frame;
262
 
263
        IRDA_ASSERT(self != NULL, return;);
264
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
265
 
266
        tx_skb = alloc_skb(sizeof(struct dm_frame), GFP_ATOMIC);
267
        if (!tx_skb)
268
                return;
269
 
270
        frame = (struct dm_frame *)skb_put(tx_skb, 2);
271
 
272
        if (self->state == LAP_NDM)
273
                frame->caddr = CBROADCAST;
274
        else
275
                frame->caddr = self->caddr;
276
 
277
        frame->control = DM_RSP | PF_BIT;
278
 
279
        irlap_queue_xmit(self, tx_skb);
280
}
281
 
282
/*
283
 * Function irlap_send_disc_frame (void)
284
 *
285
 *    Send disconnect (DISC) frame
286
 *
287
 */
288
void irlap_send_disc_frame(struct irlap_cb *self)
289
{
290
        struct sk_buff *tx_skb = NULL;
291
        struct disc_frame *frame;
292
 
293
        IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
294
 
295
        IRDA_ASSERT(self != NULL, return;);
296
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
297
 
298
        tx_skb = alloc_skb(sizeof(struct disc_frame), GFP_ATOMIC);
299
        if (!tx_skb)
300
                return;
301
 
302
        frame = (struct disc_frame *)skb_put(tx_skb, 2);
303
 
304
        frame->caddr = self->caddr | CMD_FRAME;
305
        frame->control = DISC_CMD | PF_BIT;
306
 
307
        irlap_queue_xmit(self, tx_skb);
308
}
309
 
310
/*
311
 * Function irlap_send_discovery_xid_frame (S, s, command)
312
 *
313
 *    Build and transmit a XID (eXchange station IDentifier) discovery
314
 *    frame.
315
 */
316
void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
317
                                    __u8 command, discovery_t *discovery)
318
{
319
        struct sk_buff *tx_skb = NULL;
320
        struct xid_frame *frame;
321
        __u32 bcast = BROADCAST;
322
        __u8 *info;
323
 
324
        IRDA_DEBUG(4, "%s(), s=%d, S=%d, command=%d\n", __FUNCTION__,
325
                   s, S, command);
326
 
327
        IRDA_ASSERT(self != NULL, return;);
328
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
329
        IRDA_ASSERT(discovery != NULL, return;);
330
 
331
        tx_skb = alloc_skb(sizeof(struct xid_frame) + IRLAP_DISCOVERY_INFO_LEN,
332
                           GFP_ATOMIC);
333
        if (!tx_skb)
334
                return;
335
 
336
        skb_put(tx_skb, 14);
337
        frame = (struct xid_frame *) tx_skb->data;
338
 
339
        if (command) {
340
                frame->caddr = CBROADCAST | CMD_FRAME;
341
                frame->control =  XID_CMD | PF_BIT;
342
        } else {
343
                frame->caddr = CBROADCAST;
344
                frame->control =  XID_RSP | PF_BIT;
345
        }
346
        frame->ident = XID_FORMAT;
347
 
348
        frame->saddr = cpu_to_le32(self->saddr);
349
 
350
        if (command)
351
                frame->daddr = cpu_to_le32(bcast);
352
        else
353
                frame->daddr = cpu_to_le32(discovery->data.daddr);
354
 
355
        switch (S) {
356
        case 1:
357
                frame->flags = 0x00;
358
                break;
359
        case 6:
360
                frame->flags = 0x01;
361
                break;
362
        case 8:
363
                frame->flags = 0x02;
364
                break;
365
        case 16:
366
                frame->flags = 0x03;
367
                break;
368
        default:
369
                frame->flags = 0x02;
370
                break;
371
        }
372
 
373
        frame->slotnr = s;
374
        frame->version = 0x00;
375
 
376
        /*
377
         *  Provide info for final slot only in commands, and for all
378
         *  responses. Send the second byte of the hint only if the
379
         *  EXTENSION bit is set in the first byte.
380
         */
381
        if (!command || (frame->slotnr == 0xff)) {
382
                int len;
383
 
384
                if (discovery->data.hints[0] & HINT_EXTENSION) {
385
                        info = skb_put(tx_skb, 2);
386
                        info[0] = discovery->data.hints[0];
387
                        info[1] = discovery->data.hints[1];
388
                } else {
389
                        info = skb_put(tx_skb, 1);
390
                        info[0] = discovery->data.hints[0];
391
                }
392
                info = skb_put(tx_skb, 1);
393
                info[0] = discovery->data.charset;
394
 
395
                len = IRDA_MIN(discovery->name_len, skb_tailroom(tx_skb));
396
                info = skb_put(tx_skb, len);
397
                memcpy(info, discovery->data.info, len);
398
        }
399
        irlap_queue_xmit(self, tx_skb);
400
}
401
 
402
/*
403
 * Function irlap_recv_discovery_xid_rsp (skb, info)
404
 *
405
 *    Received a XID discovery response
406
 *
407
 */
408
static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
409
                                         struct sk_buff *skb,
410
                                         struct irlap_info *info)
411
{
412
        struct xid_frame *xid;
413
        discovery_t *discovery = NULL;
414
        __u8 *discovery_info;
415
        char *text;
416
 
417
        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
418
 
419
        IRDA_ASSERT(self != NULL, return;);
420
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
421
 
422
        if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
423
                IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
424
                return;
425
        }
426
 
427
        xid = (struct xid_frame *) skb->data;
428
 
429
        info->daddr = le32_to_cpu(xid->saddr);
430
        info->saddr = le32_to_cpu(xid->daddr);
431
 
432
        /* Make sure frame is addressed to us */
433
        if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
434
                IRDA_DEBUG(0, "%s(), frame is not addressed to us!\n",
435
                           __FUNCTION__);
436
                return;
437
        }
438
 
439
        if ((discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) {
440
                IRDA_WARNING("%s: kmalloc failed!\n", __FUNCTION__);
441
                return;
442
        }
443
 
444
        discovery->data.daddr = info->daddr;
445
        discovery->data.saddr = self->saddr;
446
        discovery->timestamp = jiffies;
447
 
448
        IRDA_DEBUG(4, "%s(), daddr=%08x\n", __FUNCTION__,
449
                   discovery->data.daddr);
450
 
451
        discovery_info = skb_pull(skb, sizeof(struct xid_frame));
452
 
453
        /* Get info returned from peer */
454
        discovery->data.hints[0] = discovery_info[0];
455
        if (discovery_info[0] & HINT_EXTENSION) {
456
                IRDA_DEBUG(4, "EXTENSION\n");
457
                discovery->data.hints[1] = discovery_info[1];
458
                discovery->data.charset = discovery_info[2];
459
                text = (char *) &discovery_info[3];
460
        } else {
461
                discovery->data.hints[1] = 0;
462
                discovery->data.charset = discovery_info[1];
463
                text = (char *) &discovery_info[2];
464
        }
465
        /*
466
         *  Terminate info string, should be safe since this is where the
467
         *  FCS bytes resides.
468
         */
469
        skb->data[skb->len] = '\0';
470
        strncpy(discovery->data.info, text, NICKNAME_MAX_LEN);
471
        discovery->name_len = strlen(discovery->data.info);
472
 
473
        info->discovery = discovery;
474
 
475
        irlap_do_event(self, RECV_DISCOVERY_XID_RSP, skb, info);
476
}
477
 
478
/*
479
 * Function irlap_recv_discovery_xid_cmd (skb, info)
480
 *
481
 *    Received a XID discovery command
482
 *
483
 */
484
static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
485
                                         struct sk_buff *skb,
486
                                         struct irlap_info *info)
487
{
488
        struct xid_frame *xid;
489
        discovery_t *discovery = NULL;
490
        __u8 *discovery_info;
491
        char *text;
492
 
493
        if (!pskb_may_pull(skb, sizeof(struct xid_frame))) {
494
                IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
495
                return;
496
        }
497
 
498
        xid = (struct xid_frame *) skb->data;
499
 
500
        info->daddr = le32_to_cpu(xid->saddr);
501
        info->saddr = le32_to_cpu(xid->daddr);
502
 
503
        /* Make sure frame is addressed to us */
504
        if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
505
                IRDA_DEBUG(0, "%s(), frame is not addressed to us!\n",
506
                           __FUNCTION__);
507
                return;
508
        }
509
 
510
        switch (xid->flags & 0x03) {
511
        case 0x00:
512
                info->S = 1;
513
                break;
514
        case 0x01:
515
                info->S = 6;
516
                break;
517
        case 0x02:
518
                info->S = 8;
519
                break;
520
        case 0x03:
521
                info->S = 16;
522
                break;
523
        default:
524
                /* Error!! */
525
                return;
526
        }
527
        info->s = xid->slotnr;
528
 
529
        discovery_info = skb_pull(skb, sizeof(struct xid_frame));
530
 
531
        /*
532
         *  Check if last frame
533
         */
534
        if (info->s == 0xff) {
535
                /* Check if things are sane at this point... */
536
                if((discovery_info == NULL) ||
537
                   !pskb_may_pull(skb, 3)) {
538
                        IRDA_ERROR("%s: discovery frame too short!\n",
539
                                   __FUNCTION__);
540
                        return;
541
                }
542
 
543
                /*
544
                 *  We now have some discovery info to deliver!
545
                 */
546
                discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC);
547
                if (!discovery) {
548
                        IRDA_WARNING("%s: unable to malloc!\n", __FUNCTION__);
549
                        return;
550
                }
551
 
552
                discovery->data.daddr = info->daddr;
553
                discovery->data.saddr = self->saddr;
554
                discovery->timestamp = jiffies;
555
 
556
                discovery->data.hints[0] = discovery_info[0];
557
                if (discovery_info[0] & HINT_EXTENSION) {
558
                        discovery->data.hints[1] = discovery_info[1];
559
                        discovery->data.charset = discovery_info[2];
560
                        text = (char *) &discovery_info[3];
561
                } else {
562
                        discovery->data.hints[1] = 0;
563
                        discovery->data.charset = discovery_info[1];
564
                        text = (char *) &discovery_info[2];
565
                }
566
                /*
567
                 *  Terminate string, should be safe since this is where the
568
                 *  FCS bytes resides.
569
                 */
570
                skb->data[skb->len] = '\0';
571
                strncpy(discovery->data.info, text, NICKNAME_MAX_LEN);
572
                discovery->name_len = strlen(discovery->data.info);
573
 
574
                info->discovery = discovery;
575
        } else
576
                info->discovery = NULL;
577
 
578
        irlap_do_event(self, RECV_DISCOVERY_XID_CMD, skb, info);
579
}
580
 
581
/*
582
 * Function irlap_send_rr_frame (self, command)
583
 *
584
 *    Build and transmit RR (Receive Ready) frame. Notice that it is currently
585
 *    only possible to send RR frames with the poll bit set.
586
 */
587
void irlap_send_rr_frame(struct irlap_cb *self, int command)
588
{
589
        struct sk_buff *tx_skb;
590
        struct rr_frame *frame;
591
 
592
        tx_skb = alloc_skb(sizeof(struct rr_frame), GFP_ATOMIC);
593
        if (!tx_skb)
594
                return;
595
 
596
        frame = (struct rr_frame *)skb_put(tx_skb, 2);
597
 
598
        frame->caddr = self->caddr;
599
        frame->caddr |= (command) ? CMD_FRAME : 0;
600
 
601
        frame->control = RR | PF_BIT | (self->vr << 5);
602
 
603
        irlap_queue_xmit(self, tx_skb);
604
}
605
 
606
/*
607
 * Function irlap_send_rd_frame (self)
608
 *
609
 *    Request disconnect. Used by a secondary station to request the
610
 *    disconnection of the link.
611
 */
612
void irlap_send_rd_frame(struct irlap_cb *self)
613
{
614
        struct sk_buff *tx_skb;
615
        struct rd_frame *frame;
616
 
617
        tx_skb = alloc_skb(sizeof(struct rd_frame), GFP_ATOMIC);
618
        if (!tx_skb)
619
                return;
620
 
621
        frame = (struct rd_frame *)skb_put(tx_skb, 2);
622
 
623
        frame->caddr = self->caddr;
624
        frame->caddr = RD_RSP | PF_BIT;
625
 
626
        irlap_queue_xmit(self, tx_skb);
627
}
628
 
629
/*
630
 * Function irlap_recv_rr_frame (skb, info)
631
 *
632
 *    Received RR (Receive Ready) frame from peer station, no harm in
633
 *    making it inline since its called only from one single place
634
 *    (irlap_driver_rcv).
635
 */
636
static inline void irlap_recv_rr_frame(struct irlap_cb *self,
637
                                       struct sk_buff *skb,
638
                                       struct irlap_info *info, int command)
639
{
640
        info->nr = skb->data[1] >> 5;
641
 
642
        /* Check if this is a command or a response frame */
643
        if (command)
644
                irlap_do_event(self, RECV_RR_CMD, skb, info);
645
        else
646
                irlap_do_event(self, RECV_RR_RSP, skb, info);
647
}
648
 
649
/*
650
 * Function irlap_recv_rnr_frame (self, skb, info)
651
 *
652
 *    Received RNR (Receive Not Ready) frame from peer station
653
 *
654
 */
655
static void irlap_recv_rnr_frame(struct irlap_cb *self, struct sk_buff *skb,
656
                                 struct irlap_info *info, int command)
657
{
658
        info->nr = skb->data[1] >> 5;
659
 
660
        IRDA_DEBUG(4, "%s(), nr=%d, %ld\n", __FUNCTION__, info->nr, jiffies);
661
 
662
        if (command)
663
                irlap_do_event(self, RECV_RNR_CMD, skb, info);
664
        else
665
                irlap_do_event(self, RECV_RNR_RSP, skb, info);
666
}
667
 
668
static void irlap_recv_rej_frame(struct irlap_cb *self, struct sk_buff *skb,
669
                                 struct irlap_info *info, int command)
670
{
671
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
672
 
673
        info->nr = skb->data[1] >> 5;
674
 
675
        /* Check if this is a command or a response frame */
676
        if (command)
677
                irlap_do_event(self, RECV_REJ_CMD, skb, info);
678
        else
679
                irlap_do_event(self, RECV_REJ_RSP, skb, info);
680
}
681
 
682
static void irlap_recv_srej_frame(struct irlap_cb *self, struct sk_buff *skb,
683
                                  struct irlap_info *info, int command)
684
{
685
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
686
 
687
        info->nr = skb->data[1] >> 5;
688
 
689
        /* Check if this is a command or a response frame */
690
        if (command)
691
                irlap_do_event(self, RECV_SREJ_CMD, skb, info);
692
        else
693
                irlap_do_event(self, RECV_SREJ_RSP, skb, info);
694
}
695
 
696
static void irlap_recv_disc_frame(struct irlap_cb *self, struct sk_buff *skb,
697
                                  struct irlap_info *info, int command)
698
{
699
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
700
 
701
        /* Check if this is a command or a response frame */
702
        if (command)
703
                irlap_do_event(self, RECV_DISC_CMD, skb, info);
704
        else
705
                irlap_do_event(self, RECV_RD_RSP, skb, info);
706
}
707
 
708
/*
709
 * Function irlap_recv_ua_frame (skb, frame)
710
 *
711
 *    Received UA (Unnumbered Acknowledgement) frame
712
 *
713
 */
714
static inline void irlap_recv_ua_frame(struct irlap_cb *self,
715
                                       struct sk_buff *skb,
716
                                       struct irlap_info *info)
717
{
718
        irlap_do_event(self, RECV_UA_RSP, skb, info);
719
}
720
 
721
/*
722
 * Function irlap_send_data_primary(self, skb)
723
 *
724
 *    Send I-frames as the primary station but without the poll bit set
725
 *
726
 */
727
void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb)
728
{
729
        struct sk_buff *tx_skb;
730
 
731
        if (skb->data[1] == I_FRAME) {
732
 
733
                /*
734
                 *  Insert frame sequence number (Vs) in control field before
735
                 *  inserting into transmit window queue.
736
                 */
737
                skb->data[1] = I_FRAME | (self->vs << 1);
738
 
739
                /*
740
                 *  Insert frame in store, in case of retransmissions
741
                 *  Increase skb reference count, see irlap_do_event()
742
                 */
743
                skb_get(skb);
744
                skb_queue_tail(&self->wx_list, skb);
745
 
746
                /* Copy buffer */
747
                tx_skb = skb_clone(skb, GFP_ATOMIC);
748
                if (tx_skb == NULL) {
749
                        return;
750
                }
751
 
752
                self->vs = (self->vs + 1) % 8;
753
                self->ack_required = FALSE;
754
                self->window -= 1;
755
 
756
                irlap_send_i_frame( self, tx_skb, CMD_FRAME);
757
        } else {
758
                IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
759
                irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
760
                self->window -= 1;
761
        }
762
}
763
/*
764
 * Function irlap_send_data_primary_poll (self, skb)
765
 *
766
 *    Send I(nformation) frame as primary with poll bit set
767
 */
768
void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb)
769
{
770
        struct sk_buff *tx_skb;
771
        int transmission_time;
772
 
773
        /* Stop P timer */
774
        del_timer(&self->poll_timer);
775
 
776
        /* Is this reliable or unreliable data? */
777
        if (skb->data[1] == I_FRAME) {
778
 
779
                /*
780
                 *  Insert frame sequence number (Vs) in control field before
781
                 *  inserting into transmit window queue.
782
                 */
783
                skb->data[1] = I_FRAME | (self->vs << 1);
784
 
785
                /*
786
                 *  Insert frame in store, in case of retransmissions
787
                 *  Increase skb reference count, see irlap_do_event()
788
                 */
789
                skb_get(skb);
790
                skb_queue_tail(&self->wx_list, skb);
791
 
792
                /* Copy buffer */
793
                tx_skb = skb_clone(skb, GFP_ATOMIC);
794
                if (tx_skb == NULL) {
795
                        return;
796
                }
797
 
798
                /*
799
                 *  Set poll bit if necessary. We do this to the copied
800
                 *  skb, since retransmitted need to set or clear the poll
801
                 *  bit depending on when they are sent.
802
                 */
803
                tx_skb->data[1] |= PF_BIT;
804
 
805
                self->vs = (self->vs + 1) % 8;
806
                self->ack_required = FALSE;
807
 
808
                irlap_next_state(self, LAP_NRM_P);
809
                irlap_send_i_frame(self, tx_skb, CMD_FRAME);
810
        } else {
811
                IRDA_DEBUG(4, "%s(), sending unreliable frame\n", __FUNCTION__);
812
 
813
                if (self->ack_required) {
814
                        irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
815
                        irlap_next_state(self, LAP_NRM_P);
816
                        irlap_send_rr_frame(self, CMD_FRAME);
817
                        self->ack_required = FALSE;
818
                } else {
819
                        skb->data[1] |= PF_BIT;
820
                        irlap_next_state(self, LAP_NRM_P);
821
                        irlap_send_ui_frame(self, skb_get(skb), self->caddr, CMD_FRAME);
822
                }
823
        }
824
 
825
        /* How much time we took for transmission of all frames.
826
         * We don't know, so let assume we used the full window. Jean II */
827
        transmission_time = self->final_timeout;
828
 
829
        /* Reset parameter so that we can fill next window */
830
        self->window = self->window_size;
831
 
832
#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
833
        /* Remove what we have not used. Just do a prorata of the
834
         * bytes left in window to window capacity.
835
         * See max_line_capacities[][] in qos.c for details. Jean II */
836
        transmission_time -= (self->final_timeout * self->bytes_left
837
                              / self->line_capacity);
838
        IRDA_DEBUG(4, "%s() adjusting transmission_time : ft=%d, bl=%d, lc=%d -> tt=%d\n", __FUNCTION__, self->final_timeout, self->bytes_left, self->line_capacity, transmission_time);
839
 
840
        /* We are allowed to transmit a maximum number of bytes again. */
841
        self->bytes_left = self->line_capacity;
842
#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
843
 
844
        /*
845
         * The network layer has a intermediate buffer between IrLAP
846
         * and the IrDA driver which can contain 8 frames. So, even
847
         * though IrLAP is currently sending the *last* frame of the
848
         * tx-window, the driver most likely has only just started
849
         * sending the *first* frame of the same tx-window.
850
         * I.e. we are always at the very begining of or Tx window.
851
         * Now, we are supposed to set the final timer from the end
852
         * of our tx-window to let the other peer reply. So, we need
853
         * to add extra time to compensate for the fact that we
854
         * are really at the start of tx-window, otherwise the final timer
855
         * might expire before he can answer...
856
         * Jean II
857
         */
858
        irlap_start_final_timer(self, self->final_timeout + transmission_time);
859
 
860
        /*
861
         * The clever amongst you might ask why we do this adjustement
862
         * only here, and not in all the other cases in irlap_event.c.
863
         * In all those other case, we only send a very short management
864
         * frame (few bytes), so the adjustement would be lost in the
865
         * noise...
866
         * The exception of course is irlap_resend_rejected_frame().
867
         * Jean II */
868
}
869
 
870
/*
871
 * Function irlap_send_data_secondary_final (self, skb)
872
 *
873
 *    Send I(nformation) frame as secondary with final bit set
874
 *
875
 */
876
void irlap_send_data_secondary_final(struct irlap_cb *self,
877
                                     struct sk_buff *skb)
878
{
879
        struct sk_buff *tx_skb = NULL;
880
 
881
        IRDA_ASSERT(self != NULL, return;);
882
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
883
        IRDA_ASSERT(skb != NULL, return;);
884
 
885
        /* Is this reliable or unreliable data? */
886
        if (skb->data[1] == I_FRAME) {
887
 
888
                /*
889
                 *  Insert frame sequence number (Vs) in control field before
890
                 *  inserting into transmit window queue.
891
                 */
892
                skb->data[1] = I_FRAME | (self->vs << 1);
893
 
894
                /*
895
                 *  Insert frame in store, in case of retransmissions
896
                 *  Increase skb reference count, see irlap_do_event()
897
                 */
898
                skb_get(skb);
899
                skb_queue_tail(&self->wx_list, skb);
900
 
901
                tx_skb = skb_clone(skb, GFP_ATOMIC);
902
                if (tx_skb == NULL) {
903
                        return;
904
                }
905
 
906
                tx_skb->data[1] |= PF_BIT;
907
 
908
                self->vs = (self->vs + 1) % 8;
909
                self->ack_required = FALSE;
910
 
911
                irlap_send_i_frame(self, tx_skb, RSP_FRAME);
912
        } else {
913
                if (self->ack_required) {
914
                        irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
915
                        irlap_send_rr_frame(self, RSP_FRAME);
916
                        self->ack_required = FALSE;
917
                } else {
918
                        skb->data[1] |= PF_BIT;
919
                        irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
920
                }
921
        }
922
 
923
        self->window = self->window_size;
924
#ifdef CONFIG_IRDA_DYNAMIC_WINDOW
925
        /* We are allowed to transmit a maximum number of bytes again. */
926
        self->bytes_left = self->line_capacity;
927
#endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
928
 
929
        irlap_start_wd_timer(self, self->wd_timeout);
930
}
931
 
932
/*
933
 * Function irlap_send_data_secondary (self, skb)
934
 *
935
 *    Send I(nformation) frame as secondary without final bit set
936
 *
937
 */
938
void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb)
939
{
940
        struct sk_buff *tx_skb = NULL;
941
 
942
        /* Is this reliable or unreliable data? */
943
        if (skb->data[1] == I_FRAME) {
944
 
945
                /*
946
                 *  Insert frame sequence number (Vs) in control field before
947
                 *  inserting into transmit window queue.
948
                 */
949
                skb->data[1] = I_FRAME | (self->vs << 1);
950
 
951
                /*
952
                 *  Insert frame in store, in case of retransmissions
953
                 *  Increase skb reference count, see irlap_do_event()
954
                 */
955
                skb_get(skb);
956
                skb_queue_tail(&self->wx_list, skb);
957
 
958
                tx_skb = skb_clone(skb, GFP_ATOMIC);
959
                if (tx_skb == NULL) {
960
                        return;
961
                }
962
 
963
                self->vs = (self->vs + 1) % 8;
964
                self->ack_required = FALSE;
965
                self->window -= 1;
966
 
967
                irlap_send_i_frame(self, tx_skb, RSP_FRAME);
968
        } else {
969
                irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
970
                self->window -= 1;
971
        }
972
}
973
 
974
/*
975
 * Function irlap_resend_rejected_frames (nr)
976
 *
977
 *    Resend frames which has not been acknowledged. Should be safe to
978
 *    traverse the list without locking it since this function will only be
979
 *    called from interrupt context (BH)
980
 */
981
void irlap_resend_rejected_frames(struct irlap_cb *self, int command)
982
{
983
        struct sk_buff *tx_skb;
984
        struct sk_buff *skb;
985
        int count;
986
 
987
        IRDA_ASSERT(self != NULL, return;);
988
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
989
 
990
        /* Initialize variables */
991
        count = skb_queue_len(&self->wx_list);
992
 
993
        /*  Resend unacknowledged frame(s) */
994
        skb = skb_peek(&self->wx_list);
995
        while (skb != NULL) {
996
                irlap_wait_min_turn_around(self, &self->qos_tx);
997
 
998
                /* We copy the skb to be retransmitted since we will have to
999
                 * modify it. Cloning will confuse packet sniffers
1000
                 */
1001
                /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
1002
                tx_skb = skb_copy(skb, GFP_ATOMIC);
1003
                if (!tx_skb) {
1004
                        IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
1005
                        return;
1006
                }
1007
 
1008
                /* Clear old Nr field + poll bit */
1009
                tx_skb->data[1] &= 0x0f;
1010
 
1011
                /*
1012
                 *  Set poll bit on the last frame retransmitted
1013
                 */
1014
                if (count-- == 1)
1015
                        tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
1016
                else
1017
                        tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */
1018
 
1019
                irlap_send_i_frame(self, tx_skb, command);
1020
 
1021
                /*
1022
                 *  If our skb is the last buffer in the list, then
1023
                 *  we are finished, if not, move to the next sk-buffer
1024
                 */
1025
                if (skb == skb_peek_tail(&self->wx_list))
1026
                        skb = NULL;
1027
                else
1028
                        skb = skb->next;
1029
        }
1030
#if 0 /* Not yet */
1031
        /*
1032
         *  We can now fill the window with additional data frames
1033
         */
1034
        while (!skb_queue_empty(&self->txq)) {
1035
 
1036
                IRDA_DEBUG(0, "%s(), sending additional frames!\n", __FUNCTION__);
1037
                if (self->window > 0) {
1038
                        skb = skb_dequeue( &self->txq);
1039
                        IRDA_ASSERT(skb != NULL, return;);
1040
 
1041
                        /*
1042
                         *  If send window > 1 then send frame with pf
1043
                         *  bit cleared
1044
                         */
1045
                        if ((self->window > 1) &&
1046
                            !skb_queue_empty(&self->txq)) {
1047
                                irlap_send_data_primary(self, skb);
1048
                        } else {
1049
                                irlap_send_data_primary_poll(self, skb);
1050
                        }
1051
                        kfree_skb(skb);
1052
                }
1053
        }
1054
#endif
1055
}
1056
 
1057
void irlap_resend_rejected_frame(struct irlap_cb *self, int command)
1058
{
1059
        struct sk_buff *tx_skb;
1060
        struct sk_buff *skb;
1061
 
1062
        IRDA_ASSERT(self != NULL, return;);
1063
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
1064
 
1065
        /*  Resend unacknowledged frame(s) */
1066
        skb = skb_peek(&self->wx_list);
1067
        if (skb != NULL) {
1068
                irlap_wait_min_turn_around(self, &self->qos_tx);
1069
 
1070
                /* We copy the skb to be retransmitted since we will have to
1071
                 * modify it. Cloning will confuse packet sniffers
1072
                 */
1073
                /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
1074
                tx_skb = skb_copy(skb, GFP_ATOMIC);
1075
                if (!tx_skb) {
1076
                        IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
1077
                        return;
1078
                }
1079
 
1080
                /* Clear old Nr field + poll bit */
1081
                tx_skb->data[1] &= 0x0f;
1082
 
1083
                /*  Set poll/final bit */
1084
                tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
1085
 
1086
                irlap_send_i_frame(self, tx_skb, command);
1087
        }
1088
}
1089
 
1090
/*
1091
 * Function irlap_send_ui_frame (self, skb, command)
1092
 *
1093
 *    Contruct and transmit an Unnumbered Information (UI) frame
1094
 *
1095
 */
1096
void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
1097
                         __u8 caddr, int command)
1098
{
1099
        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
1100
 
1101
        IRDA_ASSERT(self != NULL, return;);
1102
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
1103
        IRDA_ASSERT(skb != NULL, return;);
1104
 
1105
        /* Insert connection address */
1106
        skb->data[0] = caddr | ((command) ? CMD_FRAME : 0);
1107
 
1108
        irlap_queue_xmit(self, skb);
1109
}
1110
 
1111
/*
1112
 * Function irlap_send_i_frame (skb)
1113
 *
1114
 *    Contruct and transmit Information (I) frame
1115
 */
1116
static void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
1117
                               int command)
1118
{
1119
        /* Insert connection address */
1120
        skb->data[0] = self->caddr;
1121
        skb->data[0] |= (command) ? CMD_FRAME : 0;
1122
 
1123
        /* Insert next to receive (Vr) */
1124
        skb->data[1] |= (self->vr << 5);  /* insert nr */
1125
 
1126
        irlap_queue_xmit(self, skb);
1127
}
1128
 
1129
/*
1130
 * Function irlap_recv_i_frame (skb, frame)
1131
 *
1132
 *    Receive and parse an I (Information) frame, no harm in making it inline
1133
 *    since it's called only from one single place (irlap_driver_rcv).
1134
 */
1135
static inline void irlap_recv_i_frame(struct irlap_cb *self,
1136
                                      struct sk_buff *skb,
1137
                                      struct irlap_info *info, int command)
1138
{
1139
        info->nr = skb->data[1] >> 5;          /* Next to receive */
1140
        info->pf = skb->data[1] & PF_BIT;      /* Final bit */
1141
        info->ns = (skb->data[1] >> 1) & 0x07; /* Next to send */
1142
 
1143
        /* Check if this is a command or a response frame */
1144
        if (command)
1145
                irlap_do_event(self, RECV_I_CMD, skb, info);
1146
        else
1147
                irlap_do_event(self, RECV_I_RSP, skb, info);
1148
}
1149
 
1150
/*
1151
 * Function irlap_recv_ui_frame (self, skb, info)
1152
 *
1153
 *    Receive and parse an Unnumbered Information (UI) frame
1154
 *
1155
 */
1156
static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
1157
                                struct irlap_info *info)
1158
{
1159
        IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
1160
 
1161
        info->pf = skb->data[1] & PF_BIT;      /* Final bit */
1162
 
1163
        irlap_do_event(self, RECV_UI_FRAME, skb, info);
1164
}
1165
 
1166
/*
1167
 * Function irlap_recv_frmr_frame (skb, frame)
1168
 *
1169
 *    Received Frame Reject response.
1170
 *
1171
 */
1172
static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb,
1173
                                  struct irlap_info *info)
1174
{
1175
        __u8 *frame;
1176
        int w, x, y, z;
1177
 
1178
        IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
1179
 
1180
        IRDA_ASSERT(self != NULL, return;);
1181
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
1182
        IRDA_ASSERT(skb != NULL, return;);
1183
        IRDA_ASSERT(info != NULL, return;);
1184
 
1185
        if (!pskb_may_pull(skb, 4)) {
1186
                IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
1187
                return;
1188
        }
1189
 
1190
        frame = skb->data;
1191
 
1192
        info->nr = frame[2] >> 5;          /* Next to receive */
1193
        info->pf = frame[2] & PF_BIT;      /* Final bit */
1194
        info->ns = (frame[2] >> 1) & 0x07; /* Next to send */
1195
 
1196
        w = frame[3] & 0x01;
1197
        x = frame[3] & 0x02;
1198
        y = frame[3] & 0x04;
1199
        z = frame[3] & 0x08;
1200
 
1201
        if (w) {
1202
                IRDA_DEBUG(0, "Rejected control field is undefined or not "
1203
                      "implemented.\n");
1204
        }
1205
        if (x) {
1206
                IRDA_DEBUG(0, "Rejected control field was invalid because it "
1207
                      "contained a non permitted I field.\n");
1208
        }
1209
        if (y) {
1210
                IRDA_DEBUG(0, "Received I field exceeded the maximum negotiated "
1211
                      "for the existing connection or exceeded the maximum "
1212
                      "this station supports if no connection exists.\n");
1213
        }
1214
        if (z) {
1215
                IRDA_DEBUG(0, "Rejected control field control field contained an "
1216
                      "invalid Nr count.\n");
1217
        }
1218
        irlap_do_event(self, RECV_FRMR_RSP, skb, info);
1219
}
1220
 
1221
/*
1222
 * Function irlap_send_test_frame (self, daddr)
1223
 *
1224
 *    Send a test frame response
1225
 *
1226
 */
1227
void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
1228
                           struct sk_buff *cmd)
1229
{
1230
        struct sk_buff *tx_skb;
1231
        struct test_frame *frame;
1232
        __u8 *info;
1233
 
1234
        tx_skb = alloc_skb(cmd->len + sizeof(struct test_frame), GFP_ATOMIC);
1235
        if (!tx_skb)
1236
                return;
1237
 
1238
        /* Broadcast frames must include saddr and daddr fields */
1239
        if (caddr == CBROADCAST) {
1240
                frame = (struct test_frame *)
1241
                        skb_put(tx_skb, sizeof(struct test_frame));
1242
 
1243
                /* Insert the swapped addresses */
1244
                frame->saddr = cpu_to_le32(self->saddr);
1245
                frame->daddr = cpu_to_le32(daddr);
1246
        } else
1247
                frame = (struct test_frame *) skb_put(tx_skb, LAP_ADDR_HEADER + LAP_CTRL_HEADER);
1248
 
1249
        frame->caddr = caddr;
1250
        frame->control = TEST_RSP | PF_BIT;
1251
 
1252
        /* Copy info */
1253
        info = skb_put(tx_skb, cmd->len);
1254
        memcpy(info, cmd->data, cmd->len);
1255
 
1256
        /* Return to sender */
1257
        irlap_wait_min_turn_around(self, &self->qos_tx);
1258
        irlap_queue_xmit(self, tx_skb);
1259
}
1260
 
1261
/*
1262
 * Function irlap_recv_test_frame (self, skb)
1263
 *
1264
 *    Receive a test frame
1265
 *
1266
 */
1267
static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb,
1268
                                  struct irlap_info *info, int command)
1269
{
1270
        struct test_frame *frame;
1271
 
1272
        IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
1273
 
1274
        if (!pskb_may_pull(skb, sizeof(*frame))) {
1275
                IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
1276
                return;
1277
        }
1278
        frame = (struct test_frame *) skb->data;
1279
 
1280
        /* Broadcast frames must carry saddr and daddr fields */
1281
        if (info->caddr == CBROADCAST) {
1282
                if (skb->len < sizeof(struct test_frame)) {
1283
                        IRDA_DEBUG(0, "%s() test frame too short!\n",
1284
                                   __FUNCTION__);
1285
                        return;
1286
                }
1287
 
1288
                /* Read and swap addresses */
1289
                info->daddr = le32_to_cpu(frame->saddr);
1290
                info->saddr = le32_to_cpu(frame->daddr);
1291
 
1292
                /* Make sure frame is addressed to us */
1293
                if ((info->saddr != self->saddr) &&
1294
                    (info->saddr != BROADCAST)) {
1295
                        return;
1296
                }
1297
        }
1298
 
1299
        if (command)
1300
                irlap_do_event(self, RECV_TEST_CMD, skb, info);
1301
        else
1302
                irlap_do_event(self, RECV_TEST_RSP, skb, info);
1303
}
1304
 
1305
/*
1306
 * Function irlap_driver_rcv (skb, netdev, ptype)
1307
 *
1308
 *    Called when a frame is received. Dispatches the right receive function
1309
 *    for processing of the frame.
1310
 *
1311
 * Note on skb management :
1312
 * After calling the higher layers of the IrDA stack, we always
1313
 * kfree() the skb, which drop the reference count (and potentially
1314
 * destroy it).
1315
 * If a higher layer of the stack want to keep the skb around (to put
1316
 * in a queue or pass it to the higher layer), it will need to use
1317
 * skb_get() to keep a reference on it. This is usually done at the
1318
 * LMP level in irlmp.c.
1319
 * Jean II
1320
 */
1321
int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
1322
                     struct packet_type *ptype, struct net_device *orig_dev)
1323
{
1324
        struct irlap_info info;
1325
        struct irlap_cb *self;
1326
        int command;
1327
        __u8 control;
1328
 
1329
        if (dev->nd_net != &init_net)
1330
                goto out;
1331
 
1332
        /* FIXME: should we get our own field? */
1333
        self = (struct irlap_cb *) dev->atalk_ptr;
1334
 
1335
        /* If the net device is down, then IrLAP is gone! */
1336
        if (!self || self->magic != LAP_MAGIC) {
1337
                dev_kfree_skb(skb);
1338
                return -1;
1339
        }
1340
 
1341
        /* We are no longer an "old" protocol, so we need to handle
1342
         * share and non linear skbs. This should never happen, so
1343
         * we don't need to be clever about it. Jean II */
1344
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
1345
                IRDA_ERROR("%s: can't clone shared skb!\n", __FUNCTION__);
1346
                dev_kfree_skb(skb);
1347
                return -1;
1348
        }
1349
 
1350
        /* Check if frame is large enough for parsing */
1351
        if (!pskb_may_pull(skb, 2)) {
1352
                IRDA_ERROR("%s: frame too short!\n", __FUNCTION__);
1353
                dev_kfree_skb(skb);
1354
                return -1;
1355
        }
1356
 
1357
        command    = skb->data[0] & CMD_FRAME;
1358
        info.caddr = skb->data[0] & CBROADCAST;
1359
 
1360
        info.pf      = skb->data[1] &  PF_BIT;
1361
        info.control = skb->data[1] & ~PF_BIT; /* Mask away poll/final bit */
1362
 
1363
        control = info.control;
1364
 
1365
        /*  First we check if this frame has a valid connection address */
1366
        if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) {
1367
                IRDA_DEBUG(0, "%s(), wrong connection address!\n",
1368
                           __FUNCTION__);
1369
                goto out;
1370
        }
1371
        /*
1372
         *  Optimize for the common case and check if the frame is an
1373
         *  I(nformation) frame. Only I-frames have bit 0 set to 0
1374
         */
1375
        if (~control & 0x01) {
1376
                irlap_recv_i_frame(self, skb, &info, command);
1377
                goto out;
1378
        }
1379
        /*
1380
         *  We now check is the frame is an S(upervisory) frame. Only
1381
         *  S-frames have bit 0 set to 1 and bit 1 set to 0
1382
         */
1383
        if (~control & 0x02) {
1384
                /*
1385
                 *  Received S(upervisory) frame, check which frame type it is
1386
                 *  only the first nibble is of interest
1387
                 */
1388
                switch (control & 0x0f) {
1389
                case RR:
1390
                        irlap_recv_rr_frame(self, skb, &info, command);
1391
                        break;
1392
                case RNR:
1393
                        irlap_recv_rnr_frame(self, skb, &info, command);
1394
                        break;
1395
                case REJ:
1396
                        irlap_recv_rej_frame(self, skb, &info, command);
1397
                        break;
1398
                case SREJ:
1399
                        irlap_recv_srej_frame(self, skb, &info, command);
1400
                        break;
1401
                default:
1402
                        IRDA_WARNING("%s: Unknown S-frame %02x received!\n",
1403
                                __FUNCTION__, info.control);
1404
                        break;
1405
                }
1406
                goto out;
1407
        }
1408
        /*
1409
         *  This must be a C(ontrol) frame
1410
         */
1411
        switch (control) {
1412
        case XID_RSP:
1413
                irlap_recv_discovery_xid_rsp(self, skb, &info);
1414
                break;
1415
        case XID_CMD:
1416
                irlap_recv_discovery_xid_cmd(self, skb, &info);
1417
                break;
1418
        case SNRM_CMD:
1419
                irlap_recv_snrm_cmd(self, skb, &info);
1420
                break;
1421
        case DM_RSP:
1422
                irlap_do_event(self, RECV_DM_RSP, skb, &info);
1423
                break;
1424
        case DISC_CMD: /* And RD_RSP since they have the same value */
1425
                irlap_recv_disc_frame(self, skb, &info, command);
1426
                break;
1427
        case TEST_CMD:
1428
                irlap_recv_test_frame(self, skb, &info, command);
1429
                break;
1430
        case UA_RSP:
1431
                irlap_recv_ua_frame(self, skb, &info);
1432
                break;
1433
        case FRMR_RSP:
1434
                irlap_recv_frmr_frame(self, skb, &info);
1435
                break;
1436
        case UI_FRAME:
1437
                irlap_recv_ui_frame(self, skb, &info);
1438
                break;
1439
        default:
1440
                IRDA_WARNING("%s: Unknown frame %02x received!\n",
1441
                                __FUNCTION__, info.control);
1442
                break;
1443
        }
1444
out:
1445
        /* Always drop our reference on the skb */
1446
        dev_kfree_skb(skb);
1447
        return 0;
1448
}

powered by: WebSVN 2.1.0

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