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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [pcbit/] [layer2.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * Copyright (C) 1996 Universidade de Lisboa
3
 *
4
 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
5
 *
6
 * This software may be used and distributed according to the terms of
7
 * the GNU Public License, incorporated herein by reference.
8
 */
9
 
10
/*
11
 *        PCBIT-D low-layer interface
12
 */
13
 
14
/*
15
 *        Based on documentation provided by Inesc:
16
 *        - "Interface com bus do PC para o PCBIT e PCBIT-D", Inesc, Jan 93
17
 */
18
 
19
/*
20
 *        TODO: better handling of errors
21
 *              re-write/remove debug printks
22
 */
23
 
24
#define __NO_VERSION__
25
 
26
 
27
#ifdef MODULE
28
#define INCLUDE_INLINE_FUNCS
29
#endif
30
 
31
 
32
#include <linux/module.h>
33
 
34
#include <linux/sched.h>
35
#include <linux/string.h>
36
#include <linux/kernel.h>
37
#include <linux/types.h>
38
#include <linux/malloc.h>
39
#include <linux/interrupt.h>
40
#include <linux/tqueue.h>
41
#include <linux/mm.h>
42
#include <linux/skbuff.h>
43
 
44
#include <linux/isdnif.h>
45
 
46
#include <asm/system.h>
47
#include <asm/io.h>
48
 
49
 
50
#include "pcbit.h"
51
#include "layer2.h"
52
#include "edss1.h"
53
 
54
#undef DEBUG_FRAG
55
 
56
 
57
 
58
/*
59
 *  task queue struct
60
 */
61
 
62
 
63
 
64
/*
65
 *  Layer 3 packet demultiplexer
66
 *  drv.c
67
 */
68
 
69
extern void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg,
70
                             struct sk_buff *skb,
71
                             ushort hdr_len, ushort refnum);
72
 
73
/*
74
 *  Prototypes
75
 */
76
 
77
void pcbit_deliver(void *data);
78
static void pcbit_transmit(struct pcbit_dev *dev);
79
 
80
static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack);
81
 
82
static void pcbit_l2_error(struct pcbit_dev *dev);
83
static void pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info);
84
static void pcbit_l2_err_recover(unsigned long data);
85
 
86
static void pcbit_firmware_bug(struct pcbit_dev *dev);
87
 
88
static __inline__ void
89
pcbit_sched_delivery(struct pcbit_dev *dev)
90
{
91
        queue_task(&dev->qdelivery, &tq_immediate);
92
        mark_bh(IMMEDIATE_BH);
93
}
94
 
95
 
96
/*
97
 *  Called from layer3
98
 */
99
 
100
int
101
pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
102
               struct sk_buff *skb, unsigned short hdr_len)
103
{
104
        struct frame_buf *frame,
105
        *ptr;
106
        unsigned long flags;
107
 
108
        if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
109
                dev_kfree_skb(skb, FREE_WRITE);
110
                return -1;
111
        }
112
        if ((frame = (struct frame_buf *) kmalloc(sizeof(struct frame_buf),
113
                                                  GFP_ATOMIC)) == NULL) {
114
                printk(KERN_WARNING "pcbit_2_write: kmalloc failed\n");
115
                dev_kfree_skb(skb, FREE_WRITE);
116
                return -1;
117
        }
118
        frame->msg = msg;
119
        frame->refnum = refnum;
120
        frame->copied = 0;
121
        frame->hdr_len = hdr_len;
122
 
123
        if (skb)
124
                frame->dt_len = skb->len - hdr_len;
125
        else
126
                frame->dt_len = 0;
127
 
128
        frame->skb = skb;
129
 
130
        frame->next = NULL;
131
 
132
        save_flags(flags);
133
        cli();
134
 
135
        if (dev->write_queue == NULL) {
136
                dev->write_queue = frame;
137
                restore_flags(flags);
138
                pcbit_transmit(dev);
139
        } else {
140
                for (ptr = dev->write_queue; ptr->next; ptr = ptr->next);
141
                ptr->next = frame;
142
 
143
                restore_flags(flags);
144
        }
145
        return 0;
146
}
147
 
148
static __inline__ void
149
pcbit_tx_update(struct pcbit_dev *dev, ushort len)
150
{
151
        u_char info;
152
 
153
        dev->send_seq = (dev->send_seq + 1) % 8;
154
 
155
        dev->fsize[dev->send_seq] = len;
156
        info = 0;
157
        info |= dev->rcv_seq << 3;
158
        info |= dev->send_seq;
159
 
160
        writeb(info, dev->sh_mem + BANK4);
161
 
162
}
163
 
164
/*
165
 * called by interrupt service routine or by write_2
166
 */
167
 
168
static void
169
pcbit_transmit(struct pcbit_dev *dev)
170
{
171
        struct frame_buf *frame = NULL;
172
        unsigned char unacked;
173
        int flen;               /* fragment frame length including all headers */
174
        int totlen;             /* non-fragmented frame length */
175
        int free;
176
        int count,
177
         cp_len;
178
        unsigned long flags;
179
        unsigned short tt;
180
 
181
        if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
182
                return;
183
 
184
        unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;
185
 
186
        save_flags(flags);
187
        cli();
188
 
189
        if (dev->free > 16 && dev->write_queue && unacked < 7) {
190
 
191
                if (!dev->w_busy)
192
                        dev->w_busy = 1;
193
                else {
194
                        restore_flags(flags);
195
                        return;
196
                }
197
 
198
 
199
                frame = dev->write_queue;
200
                free = dev->free;
201
 
202
                restore_flags(flags);
203
 
204
                if (frame->copied == 0) {
205
 
206
                        /* Type 0 frame */
207
 
208
                        struct msg_fmt *msg;
209
 
210
                        if (frame->skb)
211
                                totlen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
212
                        else
213
                                totlen = FRAME_HDR_LEN + PREHDR_LEN;
214
 
215
                        flen = MIN(totlen, free);
216
 
217
                        msg = (struct msg_fmt *) &(frame->msg);
218
 
219
                        /*
220
                         *  Board level 2 header
221
                         */
222
 
223
                        pcbit_writew(dev, flen - FRAME_HDR_LEN);
224
 
225
                        pcbit_writeb(dev, msg->cpu);
226
 
227
                        pcbit_writeb(dev, msg->proc);
228
 
229
                        /* TH */
230
                        pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);
231
 
232
                        /* TD */
233
                        pcbit_writew(dev, frame->dt_len);
234
 
235
 
236
                        /*
237
                         *  Board level 3 fixed-header
238
                         */
239
 
240
                        /* LEN = TH */
241
                        pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);
242
 
243
                        /* XX */
244
                        pcbit_writew(dev, 0);
245
 
246
                        /* C + S */
247
                        pcbit_writeb(dev, msg->cmd);
248
                        pcbit_writeb(dev, msg->scmd);
249
 
250
                        /* NUM */
251
                        pcbit_writew(dev, frame->refnum);
252
 
253
                        count = FRAME_HDR_LEN + PREHDR_LEN;
254
                } else {
255
                        /* Type 1 frame */
256
 
257
                        totlen = 2 + (frame->skb->len - frame->copied);
258
 
259
                        flen = MIN(totlen, free);
260
 
261
                        /* TT */
262
                        tt = ((ushort) (flen - 2)) | 0x8000U;   /* Type 1 */
263
                        pcbit_writew(dev, tt);
264
 
265
                        count = 2;
266
                }
267
 
268
                if (frame->skb) {
269
                        cp_len = MIN(frame->skb->len - frame->copied,
270
                                     flen - count);
271
 
272
                        memcpy_topcbit(dev, frame->skb->data + frame->copied,
273
                                       cp_len);
274
                        frame->copied += cp_len;
275
                }
276
                /* bookkeeping */
277
                dev->free -= flen;
278
                pcbit_tx_update(dev, flen);
279
 
280
                save_flags(flags);
281
                cli();
282
 
283
 
284
                if (frame->skb == NULL || frame->copied == frame->skb->len) {
285
 
286
                        dev->write_queue = frame->next;
287
 
288
                        if (frame->skb != NULL) {
289
                                /* free frame */
290
                                dev_kfree_skb(frame->skb, FREE_WRITE);
291
                        }
292
                        kfree(frame);
293
                }
294
                dev->w_busy = 0;
295
                restore_flags(flags);
296
        } else {
297
                restore_flags(flags);
298
#ifdef DEBUG
299
                printk(KERN_DEBUG "unacked %d free %d write_queue %s\n",
300
                     unacked, dev->free, dev->write_queue ? "not empty" :
301
                       "empty");
302
#endif
303
        }
304
}
305
 
306
 
307
/*
308
 *  deliver a queued frame to the upper layer
309
 */
310
 
311
void
312
pcbit_deliver(void *data)
313
{
314
        struct frame_buf *frame;
315
        unsigned long flags;
316
        struct msg_fmt msg;
317
        struct pcbit_dev *dev = (struct pcbit_dev *) data;
318
 
319
        save_flags(flags);
320
        cli();
321
 
322
        while ((frame = dev->read_queue)) {
323
                dev->read_queue = frame->next;
324
                restore_flags(flags);
325
 
326
                msg.cpu = 0;
327
                msg.proc = 0;
328
                msg.cmd = frame->skb->data[2];
329
                msg.scmd = frame->skb->data[3];
330
 
331
                frame->refnum = *((ushort *) frame->skb->data + 4);
332
                frame->msg = *((ulong *) & msg);
333
 
334
                skb_pull(frame->skb, 6);
335
 
336
                pcbit_l3_receive(dev, frame->msg, frame->skb, frame->hdr_len,
337
                                 frame->refnum);
338
 
339
                kfree(frame);
340
 
341
                save_flags(flags);
342
                cli();
343
        }
344
 
345
        restore_flags(flags);
346
}
347
 
348
/*
349
 * Reads BANK 2 & Reassembles
350
 */
351
 
352
static void
353
pcbit_receive(struct pcbit_dev *dev)
354
{
355
        unsigned short tt;
356
        u_char cpu,
357
         proc;
358
        struct frame_buf *frame = NULL;
359
        unsigned long flags;
360
        u_char type1;
361
 
362
        if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
363
                return;
364
 
365
        tt = pcbit_readw(dev);
366
 
367
        if ((tt & 0x7fffU) > 511) {
368
                printk(KERN_INFO "pcbit: invalid frame length -> TT=%04x\n",
369
                       tt);
370
                pcbit_l2_error(dev);
371
                return;
372
        }
373
        if (!(tt & 0x8000U)) {  /* Type 0 */
374
                type1 = 0;
375
 
376
                if (dev->read_frame) {
377
                        printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
378
#if 0
379
                        pcbit_l2_error(dev);
380
                        return;
381
#else
382
                        /* discard previous queued frame */
383
                        if (dev->read_frame->skb) {
384
                                SET_SKB_FREE(dev->read_frame->skb);
385
                                kfree_skb(dev->read_frame->skb, FREE_READ);
386
                        }
387
                        kfree(dev->read_frame);
388
                        dev->read_frame = NULL;
389
#endif
390
                }
391
                frame = kmalloc(sizeof(struct frame_buf), GFP_ATOMIC);
392
 
393
                if (frame == NULL) {
394
                        printk(KERN_WARNING "kmalloc failed\n");
395
                        return;
396
                }
397
                memset(frame, 0, sizeof(struct frame_buf));
398
 
399
                cpu = pcbit_readb(dev);
400
                proc = pcbit_readb(dev);
401
 
402
 
403
                if (cpu != 0x06 && cpu != 0x02) {
404
                        printk(KERN_DEBUG "pcbit: invalid cpu value\n");
405
                        kfree(frame);
406
                        pcbit_l2_error(dev);
407
                        return;
408
                }
409
                /*
410
                 * we discard cpu & proc on receiving
411
                 * but we read it to update the pointer
412
                 */
413
 
414
                frame->hdr_len = pcbit_readw(dev);
415
                frame->dt_len = pcbit_readw(dev);
416
 
417
                /*
418
                   * 0 sized packet
419
                   * I don't know if they are an error or not...
420
                   * But they are very frequent
421
                   * Not documented
422
                 */
423
 
424
                if (frame->hdr_len == 0) {
425
                        kfree(frame);
426
#ifdef DEBUG
427
                        printk(KERN_DEBUG "0 sized frame\n");
428
#endif
429
                        pcbit_firmware_bug(dev);
430
                        return;
431
                }
432
                /* sanity check the length values */
433
                if (frame->hdr_len > 1024 || frame->dt_len > 2048) {
434
#ifdef DEBUG
435
                        printk(KERN_DEBUG "length problem: ");
436
                        printk(KERN_DEBUG "TH=%04x TD=%04x\n",
437
                               frame->hdr_len,
438
                               frame->dt_len);
439
#endif
440
                        pcbit_l2_error(dev);
441
                        kfree(frame);
442
                        return;
443
                }
444
                /* minimum frame read */
445
 
446
                frame->skb = dev_alloc_skb(frame->hdr_len + frame->dt_len +
447
                                           ((frame->hdr_len + 15) & ~15));
448
 
449
                if (!frame->skb) {
450
                        printk(KERN_DEBUG "pcbit_receive: out of memory\n");
451
                        kfree(frame);
452
                        return;
453
                }
454
                /* 16 byte alignment for IP */
455
                if (frame->dt_len)
456
                        skb_reserve(frame->skb, (frame->hdr_len + 15) & ~15);
457
 
458
        } else {
459
                /* Type 1 */
460
                type1 = 1;
461
                tt &= 0x7fffU;
462
 
463
                if (!(frame = dev->read_frame)) {
464
                        printk("Type 1 frame and no frame queued\n");
465
#if 1
466
                        /* usually after an error: toss frame */
467
                        dev->readptr += tt;
468
                        if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN)
469
                                dev->readptr -= BANKLEN;
470
#else
471
                        pcbit_l2_error(dev);
472
#endif
473
                        return;
474
 
475
                }
476
        }
477
 
478
        memcpy_frompcbit(dev, skb_put(frame->skb, tt), tt);
479
 
480
        frame->copied += tt;
481
 
482
        if (frame->copied == frame->hdr_len + frame->dt_len) {
483
 
484
                save_flags(flags);
485
                cli();
486
 
487
                if (type1) {
488
                        dev->read_frame = NULL;
489
                }
490
                if (dev->read_queue) {
491
                        struct frame_buf *ptr;
492
                        for (ptr = dev->read_queue; ptr->next; ptr = ptr->next);
493
                        ptr->next = frame;
494
                } else
495
                        dev->read_queue = frame;
496
 
497
                restore_flags(flags);
498
 
499
        } else {
500
                save_flags(flags);
501
                cli();
502
                dev->read_frame = frame;
503
                restore_flags(flags);
504
        }
505
}
506
 
507
/*
508
 *  The board sends 0 sized frames
509
 *  They are TDATA_CONFs that get messed up somehow
510
 *  gotta send a fake acknowledgment to the upper layer somehow
511
 */
512
 
513
static __inline__ void
514
pcbit_fake_conf(struct pcbit_dev *dev, struct pcbit_chan *chan)
515
{
516
        isdn_ctrl ictl;
517
 
518
        if (chan->queued) {
519
                chan->queued--;
520
 
521
                ictl.driver = dev->id;
522
                ictl.command = ISDN_STAT_BSENT;
523
                ictl.arg = chan->id;
524
                dev->dev_if->statcallb(&ictl);
525
        }
526
}
527
 
528
static void
529
pcbit_firmware_bug(struct pcbit_dev *dev)
530
{
531
        struct pcbit_chan *chan;
532
 
533
        chan = dev->b1;
534
 
535
        if (chan->fsm_state == ST_ACTIVE) {
536
                pcbit_fake_conf(dev, chan);
537
        }
538
        chan = dev->b2;
539
 
540
        if (chan->fsm_state == ST_ACTIVE) {
541
                pcbit_fake_conf(dev, chan);
542
        }
543
}
544
 
545
void
546
pcbit_irq_handler(int interrupt, void *devptr, struct pt_regs *regs)
547
{
548
        struct pcbit_dev *dev;
549
        u_char info,
550
         ack_seq,
551
         read_seq;
552
 
553
        dev = (struct pcbit_dev *) devptr;
554
 
555
        if (!dev) {
556
                printk(KERN_WARNING "pcbit_irq_handler: wrong device\n");
557
                return;
558
        }
559
        if (dev->interrupt) {
560
                printk(KERN_DEBUG "pcbit: reentering interrupt hander\n");
561
                return;
562
        }
563
        dev->interrupt = 1;
564
 
565
        info = readb(dev->sh_mem + BANK3);
566
 
567
        if (dev->l2_state == L2_STARTING || dev->l2_state == L2_ERROR) {
568
                pcbit_l2_active_conf(dev, info);
569
                dev->interrupt = 0;
570
                return;
571
        }
572
        if (info & 0x40U) {     /* E bit set */
573
#ifdef DEBUG
574
                printk(KERN_DEBUG "pcbit_irq_handler: E bit on\n");
575
#endif
576
                pcbit_l2_error(dev);
577
                dev->interrupt = 0;
578
                return;
579
        }
580
        if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
581
                dev->interrupt = 0;
582
                return;
583
        }
584
        ack_seq = (info >> 3) & 0x07U;
585
        read_seq = (info & 0x07U);
586
 
587
        dev->interrupt = 0;
588
 
589
        if (read_seq != dev->rcv_seq) {
590
                while (read_seq != dev->rcv_seq) {
591
                        pcbit_receive(dev);
592
                        dev->rcv_seq = (dev->rcv_seq + 1) % 8;
593
                }
594
                pcbit_sched_delivery(dev);
595
        }
596
        if (ack_seq != dev->unack_seq) {
597
                pcbit_recv_ack(dev, ack_seq);
598
        }
599
        info = dev->rcv_seq << 3;
600
        info |= dev->send_seq;
601
 
602
        writeb(info, dev->sh_mem + BANK4);
603
}
604
 
605
 
606
static void
607
pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info)
608
{
609
        u_char state;
610
 
611
        state = dev->l2_state;
612
 
613
#ifdef DEBUG
614
        printk(KERN_DEBUG "layer2_active_confirm\n");
615
#endif
616
 
617
 
618
        if (info & 0x80U) {
619
                dev->rcv_seq = info & 0x07U;
620
                dev->l2_state = L2_RUNNING;
621
        } else
622
                dev->l2_state = L2_DOWN;
623
 
624
        if (state == L2_STARTING)
625
                wake_up_interruptible(&dev->set_running_wq);
626
 
627
        if (state == L2_ERROR && dev->l2_state == L2_RUNNING) {
628
                pcbit_transmit(dev);
629
        }
630
}
631
 
632
static void
633
pcbit_l2_err_recover(unsigned long data)
634
{
635
 
636
        struct pcbit_dev *dev;
637
        struct frame_buf *frame;
638
 
639
        dev = (struct pcbit_dev *) data;
640
 
641
        del_timer(&dev->error_recover_timer);
642
        if (dev->w_busy || dev->r_busy) {
643
                init_timer(&dev->error_recover_timer);
644
                dev->error_recover_timer.expires = jiffies + ERRTIME;
645
                add_timer(&dev->error_recover_timer);
646
                return;
647
        }
648
        dev->w_busy = dev->r_busy = 1;
649
 
650
        if (dev->read_frame) {
651
                if (dev->read_frame->skb) {
652
                        SET_SKB_FREE(dev->read_frame->skb);
653
                        kfree_skb(dev->read_frame->skb, FREE_READ);
654
                }
655
                kfree(dev->read_frame);
656
                dev->read_frame = NULL;
657
        }
658
        if (dev->write_queue) {
659
                frame = dev->write_queue;
660
#ifdef FREE_ON_ERROR
661
                dev->write_queue = dev->write_queue->next;
662
 
663
                if (frame->skb) {
664
                        dev_kfree_skb(frame->skb, FREE_WRITE);
665
                }
666
                kfree(frame);
667
#else
668
                frame->copied = 0;
669
#endif
670
        }
671
        dev->rcv_seq = dev->send_seq = dev->unack_seq = 0;
672
        dev->free = 511;
673
        dev->l2_state = L2_ERROR;
674
 
675
        /* this is an hack... */
676
        pcbit_firmware_bug(dev);
677
 
678
        dev->writeptr = dev->sh_mem;
679
        dev->readptr = dev->sh_mem + BANK2;
680
 
681
        writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)),
682
               dev->sh_mem + BANK4);
683
        dev->w_busy = dev->r_busy = 0;
684
 
685
}
686
 
687
static void
688
pcbit_l2_error(struct pcbit_dev *dev)
689
{
690
        if (dev->l2_state == L2_RUNNING) {
691
 
692
                printk(KERN_INFO "pcbit: layer 2 error\n");
693
 
694
#ifdef DEBUG
695
                log_state(dev);
696
#endif
697
 
698
                dev->l2_state = L2_DOWN;
699
 
700
                init_timer(&dev->error_recover_timer);
701
                dev->error_recover_timer.function = &pcbit_l2_err_recover;
702
                dev->error_recover_timer.data = (ulong) dev;
703
                dev->error_recover_timer.expires = jiffies + ERRTIME;
704
                add_timer(&dev->error_recover_timer);
705
        }
706
}
707
 
708
/*
709
 * Description:
710
 * if board acks frames
711
 *   update dev->free
712
 *   call pcbit_transmit to write possible queued frames
713
 */
714
 
715
static void
716
pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack)
717
{
718
        int i,
719
         count;
720
        int unacked;
721
 
722
        unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;
723
 
724
        /* dev->unack_seq < ack <= dev->send_seq; */
725
 
726
        if (unacked) {
727
 
728
                if (dev->send_seq > dev->unack_seq)
729
                        if (ack <= dev->unack_seq || ack > dev->send_seq) {
730
                                printk(KERN_DEBUG
731
                                     "layer 2 ack unacceptable - dev %d",
732
                                       dev->id);
733
 
734
                                pcbit_l2_error(dev);
735
                        } else if (ack > dev->send_seq && ack <= dev->unack_seq) {
736
                                printk(KERN_DEBUG
737
                                     "layer 2 ack unacceptable - dev %d",
738
                                       dev->id);
739
                                pcbit_l2_error(dev);
740
                        }
741
                /* ack is acceptable */
742
 
743
 
744
                i = dev->unack_seq;
745
 
746
                do {
747
                        dev->unack_seq = i = (i + 1) % 8;
748
                        dev->free += dev->fsize[i];
749
                } while (i != ack);
750
 
751
                count = 0;
752
                while (count < 7 && dev->write_queue) {
753
                        u8 lsend_seq = dev->send_seq;
754
 
755
                        pcbit_transmit(dev);
756
 
757
                        if (dev->send_seq == lsend_seq)
758
                                break;
759
                        count++;
760
                }
761
        } else
762
                printk(KERN_DEBUG "recv_ack: unacked = 0\n");
763
}

powered by: WebSVN 2.1.0

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