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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [plip.c] - Blame information for rev 1777

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

Line No. Rev Author Line
1 1626 jcastillo
/* $Id: plip.c,v 1.1 2005-12-20 10:17:14 jcastillo Exp $ */
2
/* PLIP: A parallel port "network" driver for Linux. */
3
/* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */
4
/*
5
 * Authors:     Donald Becker,  <becker@super.org>
6
 *              Tommy Thorn, <thorn@daimi.aau.dk>
7
 *              Tanabe Hiroyasu, <hiro@sanpo.t.u-tokyo.ac.jp>
8
 *              Alan Cox, <gw4pts@gw4pts.ampr.org>
9
 *              Peter Bauer, <100136.3530@compuserve.com>
10
 *              Niibe Yutaka, <gniibe@mri.co.jp>
11
 *
12
 *              Modularization and ifreq/ifmap support by Alan Cox.
13
 *              Rewritten by Niibe Yutaka.
14
 *
15
 * Fixes:
16
 *              9-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
17
 *                - only claim 3 bytes of I/O space for port at 0x3bc
18
 *                - treat NULL return from register_netdev() as success in
19
 *                  init_module()
20
 *                - added message if driver loaded as a module but no
21
 *                  interfaces present.
22
 *                - release claimed I/O ports if malloc() fails during init.
23
 *
24
 *              Niibe Yutaka
25
 *                - Module initialization.  You can specify I/O addr and IRQ:
26
 *                      # insmod plip.o io=0x3bc irq=7
27
 *                - MTU fix.
28
 *                - Make sure other end is OK, before sending a packet.
29
 *                - Fix immediate timer problem.
30
 *
31
 *              This program is free software; you can redistribute it and/or
32
 *              modify it under the terms of the GNU General Public License
33
 *              as published by the Free Software Foundation; either version
34
 *              2 of the License, or (at your option) any later version.
35
 */
36
 
37
/*
38
 * Original version and the name 'PLIP' from Donald Becker <becker@super.org>
39
 * inspired by Russ Nelson's parallel port packet driver.
40
 *
41
 * NOTE:
42
 *     Tanabe Hiroyasu had changed the protocol, and it was in Linux v1.0.
43
 *     Because of the necessity to communicate to DOS machines with the
44
 *     Crynwr packet driver, Peter Bauer changed the protocol again
45
 *     back to original protocol.
46
 *
47
 *     This version follows original PLIP protocol.
48
 *     So, this PLIP can't communicate the PLIP of Linux v1.0.
49
 */
50
 
51
/*
52
 *     To use with DOS box, please do (Turn on ARP switch):
53
 *      # ifconfig plip[0-2] arp
54
 */
55
static const char *version = "NET3 PLIP version 2.2 gniibe@mri.co.jp\n";
56
 
57
/*
58
  Sources:
59
        Ideas and protocols came from Russ Nelson's <nelson@crynwr.com>
60
        "parallel.asm" parallel port packet driver.
61
 
62
  The "Crynwr" parallel port standard specifies the following protocol:
63
    Trigger by sending '0x08' (this cause interrupt on other end)
64
    count-low octet
65
    count-high octet
66
    ... data octets
67
    checksum octet
68
  Each octet is sent as <wait for rx. '0x1?'> <send 0x10+(octet&0x0F)>
69
                        <wait for rx. '0x0?'> <send 0x00+((octet>>4)&0x0F)>
70
 
71
  The packet is encapsulated as if it were ethernet.
72
 
73
  The cable used is a de facto standard parallel null cable -- sold as
74
  a "LapLink" cable by various places.  You'll need a 12-conductor cable to
75
  make one yourself.  The wiring is:
76
    SLCTIN      17 - 17
77
    GROUND      25 - 25
78
    D0->ERROR   2 - 15          15 - 2
79
    D1->SLCT    3 - 13          13 - 3
80
    D2->PAPOUT  4 - 12          12 - 4
81
    D3->ACK     5 - 10          10 - 5
82
    D4->BUSY    6 - 11          11 - 6
83
  Do not connect the other pins.  They are
84
    D5,D6,D7 are 7,8,9
85
    STROBE is 1, FEED is 14, INIT is 16
86
    extra grounds are 18,19,20,21,22,23,24
87
*/
88
 
89
#include <linux/module.h>
90
 
91
#include <linux/kernel.h>
92
#include <linux/sched.h>
93
#include <linux/types.h>
94
#include <linux/fcntl.h>
95
#include <linux/interrupt.h>
96
#include <linux/string.h>
97
#include <linux/ptrace.h>
98
#include <linux/if_ether.h>
99
#include <asm/system.h>
100
#include <asm/io.h>
101
#include <linux/in.h>
102
#include <linux/errno.h>
103
#include <linux/delay.h>
104
#include <linux/lp.h>
105
 
106
#include <linux/netdevice.h>
107
#include <linux/etherdevice.h>
108
#include <linux/skbuff.h>
109
#include <linux/if_plip.h>
110
 
111
#include <linux/tqueue.h>
112
#include <linux/ioport.h>
113
#include <asm/bitops.h>
114
#include <asm/irq.h>
115
#include <asm/byteorder.h>
116
 
117
/* Use 0 for production, 1 for verification, >2 for debug */
118
#ifndef NET_DEBUG
119
#define NET_DEBUG 1
120
#endif
121
static unsigned int net_debug = NET_DEBUG;
122
 
123
/* In micro second */
124
#define PLIP_DELAY_UNIT            1
125
 
126
/* Connection time out = PLIP_TRIGGER_WAIT * PLIP_DELAY_UNIT usec */
127
#define PLIP_TRIGGER_WAIT        500
128
 
129
/* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */
130
#define PLIP_NIBBLE_WAIT        3000
131
 
132
#define PAR_INTR_ON             (LP_PINITP|LP_PSELECP|LP_PINTEN)
133
#define PAR_INTR_OFF            (LP_PINITP|LP_PSELECP)
134
#define PAR_DATA(dev)           ((dev)->base_addr+0)
135
#define PAR_STATUS(dev)         ((dev)->base_addr+1)
136
#define PAR_CONTROL(dev)        ((dev)->base_addr+2)
137
 
138
/* Bottom halfs */
139
static void plip_kick_bh(struct device *dev);
140
static void plip_bh(struct device *dev);
141
 
142
/* Interrupt handler */
143
static void plip_interrupt(int irq, void *dev_id, struct pt_regs *regs);
144
 
145
/* Functions for DEV methods */
146
static int plip_rebuild_header(void *buff, struct device *dev,
147
                               unsigned long raddr, struct sk_buff *skb);
148
static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
149
static int plip_open(struct device *dev);
150
static int plip_close(struct device *dev);
151
static struct enet_statistics *plip_get_stats(struct device *dev);
152
static int plip_config(struct device *dev, struct ifmap *map);
153
static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
154
 
155
enum plip_connection_state {
156
        PLIP_CN_NONE=0,
157
        PLIP_CN_RECEIVE,
158
        PLIP_CN_SEND,
159
        PLIP_CN_CLOSING,
160
        PLIP_CN_ERROR
161
};
162
 
163
enum plip_packet_state {
164
        PLIP_PK_DONE=0,
165
        PLIP_PK_TRIGGER,
166
        PLIP_PK_LENGTH_LSB,
167
        PLIP_PK_LENGTH_MSB,
168
        PLIP_PK_DATA,
169
        PLIP_PK_CHECKSUM
170
};
171
 
172
enum plip_nibble_state {
173
        PLIP_NB_BEGIN,
174
        PLIP_NB_1,
175
        PLIP_NB_2,
176
};
177
 
178
struct plip_local {
179
        enum plip_packet_state state;
180
        enum plip_nibble_state nibble;
181
        union {
182
                struct {
183
#if defined(__LITTLE_ENDIAN)
184
                        unsigned char lsb;
185
                        unsigned char msb;
186
#elif defined(__BIG_ENDIAN)
187
                        unsigned char msb;
188
                        unsigned char lsb;
189
#else
190
#error  "Please fix the endianness defines in <asm/byteorder.h>"
191
#endif                                          
192
                } b;
193
                unsigned short h;
194
        } length;
195
        unsigned short byte;
196
        unsigned char  checksum;
197
        unsigned char  data;
198
        struct sk_buff *skb;
199
};
200
 
201
struct net_local {
202
        struct enet_statistics enet_stats;
203
        struct tq_struct immediate;
204
        struct tq_struct deferred;
205
        struct plip_local snd_data;
206
        struct plip_local rcv_data;
207
        unsigned long  trigger;
208
        unsigned long  nibble;
209
        enum plip_connection_state connection;
210
        unsigned short timeout_count;
211
        char is_deferred;
212
        int (*orig_rebuild_header)(void *eth, struct device *dev,
213
                                   unsigned long raddr, struct sk_buff *skb);
214
};
215
 
216
/* Entry point of PLIP driver.
217
   Probe the hardware, and register/initialize the driver. */
218
int
219
plip_init(struct device *dev)
220
{
221
        struct net_local *nl;
222
        int iosize = (PAR_DATA(dev) == 0x3bc) ? 3 : 8;
223
 
224
        /* Check region before the probe */
225
        if (check_region(PAR_DATA(dev), iosize) < 0)
226
                return -ENODEV;
227
 
228
        /* Check that there is something at base_addr. */
229
        outb(0, PAR_DATA(dev));
230
        udelay(1000);
231
        if (inb(PAR_DATA(dev)) != 0)
232
                return -ENODEV;
233
 
234
        printk(version);
235
        printk("%s: Parallel port at %#3lx, ", dev->name, dev->base_addr);
236
        if (dev->irq) {
237
                printk("using assigned IRQ %d.\n", dev->irq);
238
        } else {
239
                int irq = 0;
240
#ifdef MODULE
241
                /* dev->irq==0 means autoprobe, but we don't try to do so
242
                   with module.  We can change it by ifconfig */
243
#else
244
                unsigned int irqs = probe_irq_on();
245
 
246
                outb(0x00, PAR_CONTROL(dev));
247
                udelay(1000);
248
                outb(PAR_INTR_OFF, PAR_CONTROL(dev));
249
                outb(PAR_INTR_ON, PAR_CONTROL(dev));
250
                outb(PAR_INTR_OFF, PAR_CONTROL(dev));
251
                udelay(1000);
252
                irq = probe_irq_off(irqs);
253
#endif
254
                if (irq > 0) {
255
                        dev->irq = irq;
256
                        printk("using probed IRQ %d.\n", dev->irq);
257
                } else
258
                        printk("failed to detect IRQ(%d) --"
259
                               " Please set IRQ by ifconfig.\n", irq);
260
        }
261
 
262
        request_region(PAR_DATA(dev), iosize, dev->name);
263
 
264
        /* Fill in the generic fields of the device structure. */
265
        ether_setup(dev);
266
 
267
        /* Then, override parts of it */
268
        dev->hard_start_xmit    = plip_tx_packet;
269
        dev->open               = plip_open;
270
        dev->stop               = plip_close;
271
        dev->get_stats          = plip_get_stats;
272
        dev->set_config         = plip_config;
273
        dev->do_ioctl           = plip_ioctl;
274
        dev->tx_queue_len       = 10;
275
        dev->flags              = IFF_POINTOPOINT|IFF_NOARP;
276
 
277
        /* Set the private structure */
278
        dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL);
279
        if (dev->priv == NULL) {
280
                printk(KERN_ERR "%s: out of memory\n", dev->name);
281
                release_region(PAR_DATA(dev), iosize);
282
                return -ENOMEM;
283
        }
284
        memset(dev->priv, 0, sizeof(struct net_local));
285
        nl = (struct net_local *) dev->priv;
286
 
287
        nl->orig_rebuild_header = dev->rebuild_header;
288
        dev->rebuild_header     = plip_rebuild_header;
289
 
290
        /* Initialize constants */
291
        nl->trigger     = PLIP_TRIGGER_WAIT;
292
        nl->nibble      = PLIP_NIBBLE_WAIT;
293
 
294
        /* Initialize task queue structures */
295
        nl->immediate.next = NULL;
296
        nl->immediate.sync = 0;
297
        nl->immediate.routine = (void *)(void *)plip_bh;
298
        nl->immediate.data = dev;
299
 
300
        nl->deferred.next = NULL;
301
        nl->deferred.sync = 0;
302
        nl->deferred.routine = (void *)(void *)plip_kick_bh;
303
        nl->deferred.data = dev;
304
 
305
        return 0;
306
}
307
 
308
/* Bottom half handler for the delayed request.
309
   This routine is kicked by do_timer().
310
   Request `plip_bh' to be invoked. */
311
static void
312
plip_kick_bh(struct device *dev)
313
{
314
        struct net_local *nl = (struct net_local *)dev->priv;
315
 
316
        if (nl->is_deferred) {
317
                queue_task(&nl->immediate, &tq_immediate);
318
                mark_bh(IMMEDIATE_BH);
319
        }
320
}
321
 
322
/* Forward declarations of internal routines */
323
static int plip_none(struct device *, struct net_local *,
324
                     struct plip_local *, struct plip_local *);
325
static int plip_receive_packet(struct device *, struct net_local *,
326
                               struct plip_local *, struct plip_local *);
327
static int plip_send_packet(struct device *, struct net_local *,
328
                            struct plip_local *, struct plip_local *);
329
static int plip_connection_close(struct device *, struct net_local *,
330
                                 struct plip_local *, struct plip_local *);
331
static int plip_error(struct device *, struct net_local *,
332
                      struct plip_local *, struct plip_local *);
333
static int plip_bh_timeout_error(struct device *dev, struct net_local *nl,
334
                                 struct plip_local *snd,
335
                                 struct plip_local *rcv,
336
                                 int error);
337
 
338
#define OK        0
339
#define TIMEOUT   1
340
#define ERROR     2
341
 
342
typedef int (*plip_func)(struct device *dev, struct net_local *nl,
343
                         struct plip_local *snd, struct plip_local *rcv);
344
 
345
static plip_func connection_state_table[] =
346
{
347
        plip_none,
348
        plip_receive_packet,
349
        plip_send_packet,
350
        plip_connection_close,
351
        plip_error
352
};
353
 
354
/* Bottom half handler of PLIP. */
355
static void
356
plip_bh(struct device *dev)
357
{
358
        struct net_local *nl = (struct net_local *)dev->priv;
359
        struct plip_local *snd = &nl->snd_data;
360
        struct plip_local *rcv = &nl->rcv_data;
361
        plip_func f;
362
        int r;
363
 
364
        nl->is_deferred = 0;
365
        f = connection_state_table[nl->connection];
366
        if ((r = (*f)(dev, nl, snd, rcv)) != OK
367
            && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) {
368
                nl->is_deferred = 1;
369
                queue_task(&nl->deferred, &tq_timer);
370
        }
371
}
372
 
373
static int
374
plip_bh_timeout_error(struct device *dev, struct net_local *nl,
375
                      struct plip_local *snd, struct plip_local *rcv,
376
                      int error)
377
{
378
        unsigned char c0;
379
 
380
        cli();
381
        if (nl->connection == PLIP_CN_SEND) {
382
 
383
                if (error != ERROR) { /* Timeout */
384
                        nl->timeout_count++;
385
                        if ((snd->state == PLIP_PK_TRIGGER
386
                             && nl->timeout_count <= 10)
387
                            || nl->timeout_count <= 3) {
388
                                sti();
389
                                /* Try again later */
390
                                return TIMEOUT;
391
                        }
392
                        c0 = inb(PAR_STATUS(dev));
393
                        printk(KERN_WARNING "%s: transmit timeout(%d,%02x)\n",
394
                               dev->name, snd->state, c0);
395
                }
396
                nl->enet_stats.tx_errors++;
397
                nl->enet_stats.tx_aborted_errors++;
398
        } else if (nl->connection == PLIP_CN_RECEIVE) {
399
                if (rcv->state == PLIP_PK_TRIGGER) {
400
                        /* Transmission was interrupted. */
401
                        sti();
402
                        return OK;
403
                }
404
                if (error != ERROR) { /* Timeout */
405
                        if (++nl->timeout_count <= 3) {
406
                                sti();
407
                                /* Try again later */
408
                                return TIMEOUT;
409
                        }
410
                        c0 = inb(PAR_STATUS(dev));
411
                        printk(KERN_WARNING "%s: receive timeout(%d,%02x)\n",
412
                               dev->name, rcv->state, c0);
413
                }
414
                nl->enet_stats.rx_dropped++;
415
        }
416
        rcv->state = PLIP_PK_DONE;
417
        if (rcv->skb) {
418
                rcv->skb->free = 1;
419
                kfree_skb(rcv->skb, FREE_READ);
420
                rcv->skb = NULL;
421
        }
422
        snd->state = PLIP_PK_DONE;
423
        if (snd->skb) {
424
                dev_kfree_skb(snd->skb, FREE_WRITE);
425
                snd->skb = NULL;
426
        }
427
        disable_irq(dev->irq);
428
        outb(PAR_INTR_OFF, PAR_CONTROL(dev));
429
        dev->tbusy = 1;
430
        nl->connection = PLIP_CN_ERROR;
431
        outb(0x00, PAR_DATA(dev));
432
        sti();
433
 
434
        return TIMEOUT;
435
}
436
 
437
static int
438
plip_none(struct device *dev, struct net_local *nl,
439
          struct plip_local *snd, struct plip_local *rcv)
440
{
441
        return OK;
442
}
443
 
444
/* PLIP_RECEIVE --- receive a byte(two nibbles)
445
   Returns OK on success, TIMEOUT on timeout */
446
inline static int
447
plip_receive(unsigned short nibble_timeout, unsigned short status_addr,
448
             enum plip_nibble_state *ns_p, unsigned char *data_p)
449
{
450
        unsigned char c0, c1;
451
        unsigned int cx;
452
 
453
        switch (*ns_p) {
454
        case PLIP_NB_BEGIN:
455
                cx = nibble_timeout;
456
                while (1) {
457
                        c0 = inb(status_addr);
458
                        udelay(PLIP_DELAY_UNIT);
459
                        if ((c0 & 0x80) == 0) {
460
                                c1 = inb(status_addr);
461
                                if (c0 == c1)
462
                                        break;
463
                        }
464
                        if (--cx == 0)
465
                                return TIMEOUT;
466
                }
467
                *data_p = (c0 >> 3) & 0x0f;
468
                outb(0x10, --status_addr); /* send ACK */
469
                status_addr++;
470
                *ns_p = PLIP_NB_1;
471
 
472
        case PLIP_NB_1:
473
                cx = nibble_timeout;
474
                while (1) {
475
                        c0 = inb(status_addr);
476
                        udelay(PLIP_DELAY_UNIT);
477
                        if (c0 & 0x80) {
478
                                c1 = inb(status_addr);
479
                                if (c0 == c1)
480
                                        break;
481
                        }
482
                        if (--cx == 0)
483
                                return TIMEOUT;
484
                }
485
                *data_p |= (c0 << 1) & 0xf0;
486
                outb(0x00, --status_addr); /* send ACK */
487
                status_addr++;
488
                *ns_p = PLIP_NB_BEGIN;
489
        case PLIP_NB_2:
490
                break;
491
        }
492
        return OK;
493
}
494
 
495
/* PLIP_RECEIVE_PACKET --- receive a packet */
496
static int
497
plip_receive_packet(struct device *dev, struct net_local *nl,
498
                    struct plip_local *snd, struct plip_local *rcv)
499
{
500
        unsigned short status_addr = PAR_STATUS(dev);
501
        unsigned short nibble_timeout = nl->nibble;
502
        unsigned char *lbuf;
503
 
504
        switch (rcv->state) {
505
        case PLIP_PK_TRIGGER:
506
                disable_irq(dev->irq);
507
                outb(PAR_INTR_OFF, PAR_CONTROL(dev));
508
                dev->interrupt = 0;
509
                outb(0x01, PAR_DATA(dev)); /* send ACK */
510
                if (net_debug > 2)
511
                        printk("%s: receive start\n", dev->name);
512
                rcv->state = PLIP_PK_LENGTH_LSB;
513
                rcv->nibble = PLIP_NB_BEGIN;
514
 
515
        case PLIP_PK_LENGTH_LSB:
516
                if (snd->state != PLIP_PK_DONE) {
517
                        if (plip_receive(nl->trigger, status_addr,
518
                                         &rcv->nibble, &rcv->length.b.lsb)) {
519
                                /* collision, here dev->tbusy == 1 */
520
                                rcv->state = PLIP_PK_DONE;
521
                                nl->is_deferred = 1;
522
                                nl->connection = PLIP_CN_SEND;
523
                                queue_task(&nl->deferred, &tq_timer);
524
                                outb(PAR_INTR_ON, PAR_CONTROL(dev));
525
                                enable_irq(dev->irq);
526
                                return OK;
527
                        }
528
                } else {
529
                        if (plip_receive(nibble_timeout, status_addr,
530
                                         &rcv->nibble, &rcv->length.b.lsb))
531
                                return TIMEOUT;
532
                }
533
                rcv->state = PLIP_PK_LENGTH_MSB;
534
 
535
        case PLIP_PK_LENGTH_MSB:
536
                if (plip_receive(nibble_timeout, status_addr,
537
                                 &rcv->nibble, &rcv->length.b.msb))
538
                        return TIMEOUT;
539
                if (rcv->length.h > dev->mtu + dev->hard_header_len
540
                    || rcv->length.h < 8) {
541
                        printk(KERN_WARNING "%s: bogus packet size %d.\n", dev->name, rcv->length.h);
542
                        return ERROR;
543
                }
544
                /* Malloc up new buffer. */
545
                rcv->skb = dev_alloc_skb(rcv->length.h);
546
                if (rcv->skb == NULL) {
547
                        printk(KERN_WARNING "%s: Memory squeeze.\n", dev->name);
548
                        return ERROR;
549
                }
550
                skb_put(rcv->skb,rcv->length.h);
551
                rcv->skb->dev = dev;
552
                rcv->state = PLIP_PK_DATA;
553
                rcv->byte = 0;
554
                rcv->checksum = 0;
555
 
556
        case PLIP_PK_DATA:
557
                lbuf = rcv->skb->data;
558
                do
559
                        if (plip_receive(nibble_timeout, status_addr,
560
                                         &rcv->nibble, &lbuf[rcv->byte]))
561
                                return TIMEOUT;
562
                while (++rcv->byte < rcv->length.h);
563
                do
564
                        rcv->checksum += lbuf[--rcv->byte];
565
                while (rcv->byte);
566
                rcv->state = PLIP_PK_CHECKSUM;
567
 
568
        case PLIP_PK_CHECKSUM:
569
                if (plip_receive(nibble_timeout, status_addr,
570
                                 &rcv->nibble, &rcv->data))
571
                        return TIMEOUT;
572
                if (rcv->data != rcv->checksum) {
573
                        nl->enet_stats.rx_crc_errors++;
574
                        if (net_debug)
575
                                printk("%s: checksum error\n", dev->name);
576
                        return ERROR;
577
                }
578
                rcv->state = PLIP_PK_DONE;
579
 
580
        case PLIP_PK_DONE:
581
                /* Inform the upper layer for the arrival of a packet. */
582
                rcv->skb->protocol=eth_type_trans(rcv->skb, dev);
583
                netif_rx(rcv->skb);
584
                nl->enet_stats.rx_packets++;
585
                rcv->skb = NULL;
586
                if (net_debug > 2)
587
                        printk("%s: receive end\n", dev->name);
588
 
589
                /* Close the connection. */
590
                outb (0x00, PAR_DATA(dev));
591
                cli();
592
                if (snd->state != PLIP_PK_DONE) {
593
                        nl->connection = PLIP_CN_SEND;
594
                        sti();
595
                        queue_task(&nl->immediate, &tq_immediate);
596
                        mark_bh(IMMEDIATE_BH);
597
                        outb(PAR_INTR_ON, PAR_CONTROL(dev));
598
                        enable_irq(dev->irq);
599
                        return OK;
600
                } else {
601
                        nl->connection = PLIP_CN_NONE;
602
                        sti();
603
                        outb(PAR_INTR_ON, PAR_CONTROL(dev));
604
                        enable_irq(dev->irq);
605
                        return OK;
606
                }
607
        }
608
        return OK;
609
}
610
 
611
/* PLIP_SEND --- send a byte (two nibbles)
612
   Returns OK on success, TIMEOUT when timeout    */
613
inline static int
614
plip_send(unsigned short nibble_timeout, unsigned short data_addr,
615
          enum plip_nibble_state *ns_p, unsigned char data)
616
{
617
        unsigned char c0;
618
        unsigned int cx;
619
 
620
        switch (*ns_p) {
621
        case PLIP_NB_BEGIN:
622
                outb((data & 0x0f), data_addr);
623
                *ns_p = PLIP_NB_1;
624
 
625
        case PLIP_NB_1:
626
                outb(0x10 | (data & 0x0f), data_addr);
627
                cx = nibble_timeout;
628
                data_addr++;
629
                while (1) {
630
                        c0 = inb(data_addr);
631
                        if ((c0 & 0x80) == 0)
632
                                break;
633
                        if (--cx == 0)
634
                                return TIMEOUT;
635
                        udelay(PLIP_DELAY_UNIT);
636
                }
637
                outb(0x10 | (data >> 4), --data_addr);
638
                *ns_p = PLIP_NB_2;
639
 
640
        case PLIP_NB_2:
641
                outb((data >> 4), data_addr);
642
                data_addr++;
643
                cx = nibble_timeout;
644
                while (1) {
645
                        c0 = inb(data_addr);
646
                        if (c0 & 0x80)
647
                                break;
648
                        if (--cx == 0)
649
                                return TIMEOUT;
650
                        udelay(PLIP_DELAY_UNIT);
651
                }
652
                data_addr--;
653
                *ns_p = PLIP_NB_BEGIN;
654
                return OK;
655
        }
656
        return OK;
657
}
658
 
659
/* PLIP_SEND_PACKET --- send a packet */
660
static int
661
plip_send_packet(struct device *dev, struct net_local *nl,
662
                 struct plip_local *snd, struct plip_local *rcv)
663
{
664
        unsigned short data_addr = PAR_DATA(dev);
665
        unsigned short nibble_timeout = nl->nibble;
666
        unsigned char *lbuf;
667
        unsigned char c0;
668
        unsigned int cx;
669
 
670
        if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) {
671
                printk(KERN_ERR "%s: send skb lost\n", dev->name);
672
                snd->state = PLIP_PK_DONE;
673
                snd->skb = NULL;
674
                return ERROR;
675
        }
676
 
677
        switch (snd->state) {
678
        case PLIP_PK_TRIGGER:
679
                if ((inb(PAR_STATUS(dev)) & 0xf8) != 0x80)
680
                        return TIMEOUT;
681
 
682
                /* Trigger remote rx interrupt. */
683
                outb(0x08, data_addr);
684
                cx = nl->trigger;
685
                while (1) {
686
                        udelay(PLIP_DELAY_UNIT);
687
                        cli();
688
                        if (nl->connection == PLIP_CN_RECEIVE) {
689
                                sti();
690
                                /* interrupted */
691
                                nl->enet_stats.collisions++;
692
                                if (net_debug > 1)
693
                                        printk("%s: collision.\n", dev->name);
694
                                return OK;
695
                        }
696
                        c0 = inb(PAR_STATUS(dev));
697
                        if (c0 & 0x08) {
698
                                disable_irq(dev->irq);
699
                                outb(PAR_INTR_OFF, PAR_CONTROL(dev));
700
                                if (net_debug > 2)
701
                                        printk("%s: send start\n", dev->name);
702
                                snd->state = PLIP_PK_LENGTH_LSB;
703
                                snd->nibble = PLIP_NB_BEGIN;
704
                                nl->timeout_count = 0;
705
                                sti();
706
                                break;
707
                        }
708
                        sti();
709
                        if (--cx == 0) {
710
                                outb(0x00, data_addr);
711
                                return TIMEOUT;
712
                        }
713
                }
714
 
715
        case PLIP_PK_LENGTH_LSB:
716
                if (plip_send(nibble_timeout, data_addr,
717
                              &snd->nibble, snd->length.b.lsb))
718
                        return TIMEOUT;
719
                snd->state = PLIP_PK_LENGTH_MSB;
720
 
721
        case PLIP_PK_LENGTH_MSB:
722
                if (plip_send(nibble_timeout, data_addr,
723
                              &snd->nibble, snd->length.b.msb))
724
                        return TIMEOUT;
725
                snd->state = PLIP_PK_DATA;
726
                snd->byte = 0;
727
                snd->checksum = 0;
728
 
729
        case PLIP_PK_DATA:
730
                do
731
                        if (plip_send(nibble_timeout, data_addr,
732
                                      &snd->nibble, lbuf[snd->byte]))
733
                                return TIMEOUT;
734
                while (++snd->byte < snd->length.h);
735
                do
736
                        snd->checksum += lbuf[--snd->byte];
737
                while (snd->byte);
738
                snd->state = PLIP_PK_CHECKSUM;
739
 
740
        case PLIP_PK_CHECKSUM:
741
                if (plip_send(nibble_timeout, data_addr,
742
                              &snd->nibble, snd->checksum))
743
                        return TIMEOUT;
744
 
745
                dev_kfree_skb(snd->skb, FREE_WRITE);
746
                nl->enet_stats.tx_packets++;
747
                snd->state = PLIP_PK_DONE;
748
 
749
        case PLIP_PK_DONE:
750
                /* Close the connection */
751
                outb (0x00, data_addr);
752
                snd->skb = NULL;
753
                if (net_debug > 2)
754
                        printk("%s: send end\n", dev->name);
755
                nl->connection = PLIP_CN_CLOSING;
756
                nl->is_deferred = 1;
757
                queue_task(&nl->deferred, &tq_timer);
758
                outb(PAR_INTR_ON, PAR_CONTROL(dev));
759
                enable_irq(dev->irq);
760
                return OK;
761
        }
762
        return OK;
763
}
764
 
765
static int
766
plip_connection_close(struct device *dev, struct net_local *nl,
767
                      struct plip_local *snd, struct plip_local *rcv)
768
{
769
        cli();
770
        if (nl->connection == PLIP_CN_CLOSING) {
771
                nl->connection = PLIP_CN_NONE;
772
                dev->tbusy = 0;
773
                mark_bh(NET_BH);
774
        }
775
        sti();
776
        return OK;
777
}
778
 
779
/* PLIP_ERROR --- wait till other end settled */
780
static int
781
plip_error(struct device *dev, struct net_local *nl,
782
           struct plip_local *snd, struct plip_local *rcv)
783
{
784
        unsigned char status;
785
 
786
        status = inb(PAR_STATUS(dev));
787
        if ((status & 0xf8) == 0x80) {
788
                if (net_debug > 2)
789
                        printk("%s: reset interface.\n", dev->name);
790
                nl->connection = PLIP_CN_NONE;
791
                dev->tbusy = 0;
792
                dev->interrupt = 0;
793
                outb(PAR_INTR_ON, PAR_CONTROL(dev));
794
                enable_irq(dev->irq);
795
                mark_bh(NET_BH);
796
        } else {
797
                nl->is_deferred = 1;
798
                queue_task(&nl->deferred, &tq_timer);
799
        }
800
 
801
        return OK;
802
}
803
 
804
/* Handle the parallel port interrupts. */
805
static void
806
plip_interrupt(int irq, void *dev_id, struct pt_regs * regs)
807
{
808
        struct device *dev = (struct device *) irq2dev_map[irq];
809
        struct net_local *nl = (struct net_local *)dev->priv;
810
        struct plip_local *rcv = &nl->rcv_data;
811
        unsigned char c0;
812
 
813
        if (dev == NULL) {
814
                printk (KERN_ERR "plip_interrupt: irq %d for unknown device.\n", irq);
815
                return;
816
        }
817
 
818
        if (dev->interrupt)
819
                return;
820
 
821
        c0 = inb(PAR_STATUS(dev));
822
        if ((c0 & 0xf8) != 0xc0) {
823
                if (net_debug > 1)
824
                        printk("%s: spurious interrupt\n", dev->name);
825
                return;
826
        }
827
        dev->interrupt = 1;
828
        if (net_debug > 3)
829
                printk("%s: interrupt.\n", dev->name);
830
 
831
        cli();
832
        switch (nl->connection) {
833
        case PLIP_CN_CLOSING:
834
                dev->tbusy = 0;
835
        case PLIP_CN_NONE:
836
        case PLIP_CN_SEND:
837
                dev->last_rx = jiffies;
838
                rcv->state = PLIP_PK_TRIGGER;
839
                nl->connection = PLIP_CN_RECEIVE;
840
                nl->timeout_count = 0;
841
                queue_task(&nl->immediate, &tq_immediate);
842
                mark_bh(IMMEDIATE_BH);
843
                sti();
844
                break;
845
 
846
        case PLIP_CN_RECEIVE:
847
                sti();
848
                printk(KERN_WARNING "%s: receive interrupt when receiving packet\n", dev->name);
849
                break;
850
 
851
        case PLIP_CN_ERROR:
852
                sti();
853
                printk(KERN_WARNING "%s: receive interrupt in error state\n", dev->name);
854
                break;
855
        }
856
}
857
 
858
/* We don't need to send arp, for plip is point-to-point. */
859
static int
860
plip_rebuild_header(void *buff, struct device *dev, unsigned long dst,
861
                    struct sk_buff *skb)
862
{
863
        struct net_local *nl = (struct net_local *)dev->priv;
864
        struct ethhdr *eth = (struct ethhdr *)buff;
865
        int i;
866
 
867
        if ((dev->flags & IFF_NOARP)==0)
868
                return nl->orig_rebuild_header(buff, dev, dst, skb);
869
 
870
        if (eth->h_proto != htons(ETH_P_IP)) {
871
                printk(KERN_WARNING "plip_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto);
872
                memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
873
                return 0;
874
        }
875
 
876
        for (i=0; i < ETH_ALEN - sizeof(u32); i++)
877
                eth->h_dest[i] = 0xfc;
878
        *(u32 *)(eth->h_dest+i) = dst;
879
        return 0;
880
}
881
 
882
static int
883
plip_tx_packet(struct sk_buff *skb, struct device *dev)
884
{
885
        struct net_local *nl = (struct net_local *)dev->priv;
886
        struct plip_local *snd = &nl->snd_data;
887
 
888
        if (dev->tbusy)
889
                return 1;
890
 
891
        /* If some higher layer thinks we've missed an tx-done interrupt
892
           we are passed NULL. Caution: dev_tint() handles the cli()/sti()
893
           itself. */
894
        if (skb == NULL) {
895
                dev_tint(dev);
896
                return 0;
897
        }
898
 
899
        if (set_bit(0, (void*)&dev->tbusy) != 0) {
900
                printk(KERN_ERR "%s: Transmitter access conflict.\n", dev->name);
901
                return 1;
902
        }
903
 
904
        if (skb->len > dev->mtu + dev->hard_header_len) {
905
                printk(KERN_WARNING "%s: packet too big, %d.\n", dev->name, (int)skb->len);
906
                dev->tbusy = 0;
907
                dev_kfree_skb(skb, FREE_WRITE);
908
                return 0;
909
        }
910
 
911
        if (net_debug > 2)
912
                printk("%s: send request\n", dev->name);
913
 
914
        cli();
915
        dev->trans_start = jiffies;
916
        snd->skb = skb;
917
        snd->length.h = skb->len;
918
        snd->state = PLIP_PK_TRIGGER;
919
        if (nl->connection == PLIP_CN_NONE) {
920
                nl->connection = PLIP_CN_SEND;
921
                nl->timeout_count = 0;
922
        }
923
        queue_task(&nl->immediate, &tq_immediate);
924
        mark_bh(IMMEDIATE_BH);
925
        sti();
926
 
927
        return 0;
928
}
929
 
930
/* Open/initialize the board.  This is called (in the current kernel)
931
   sometime after booting when the 'ifconfig' program is run.
932
 
933
   This routine gets exclusive access to the parallel port by allocating
934
   its IRQ line.
935
 */
936
static int
937
plip_open(struct device *dev)
938
{
939
        struct net_local *nl = (struct net_local *)dev->priv;
940
        int i;
941
 
942
        if (dev->irq == 0) {
943
                printk(KERN_INFO "%s: IRQ is not set.  Please set it by ifconfig.\n", dev->name);
944
                return -EAGAIN;
945
        }
946
        cli();
947
        if (request_irq(dev->irq , plip_interrupt, 0, dev->name, NULL) != 0) {
948
                sti();
949
                printk(KERN_WARNING "%s: couldn't get IRQ %d.\n", dev->name, dev->irq);
950
                return -EAGAIN;
951
        }
952
        irq2dev_map[dev->irq] = dev;
953
        sti();
954
 
955
        /* Clear the data port. */
956
        outb (0x00, PAR_DATA(dev));
957
 
958
        /* Enable rx interrupt. */
959
        outb(PAR_INTR_ON, PAR_CONTROL(dev));
960
 
961
        /* Initialize the state machine. */
962
        nl->rcv_data.state = nl->snd_data.state = PLIP_PK_DONE;
963
        nl->rcv_data.skb = nl->snd_data.skb = NULL;
964
        nl->connection = PLIP_CN_NONE;
965
        nl->is_deferred = 0;
966
 
967
        /* Fill in the MAC-level header. */
968
        for (i=0; i < ETH_ALEN - sizeof(u32); i++)
969
                dev->dev_addr[i] = 0xfc;
970
        *(u32 *)(dev->dev_addr+i) = dev->pa_addr;
971
 
972
        dev->interrupt = 0;
973
        dev->start = 1;
974
        dev->tbusy = 0;
975
        MOD_INC_USE_COUNT;
976
        return 0;
977
}
978
 
979
/* The inverse routine to plip_open (). */
980
static int
981
plip_close(struct device *dev)
982
{
983
        struct net_local *nl = (struct net_local *)dev->priv;
984
        struct plip_local *snd = &nl->snd_data;
985
        struct plip_local *rcv = &nl->rcv_data;
986
 
987
        dev->tbusy = 1;
988
        dev->start = 0;
989
        cli();
990
        free_irq(dev->irq, NULL);
991
        irq2dev_map[dev->irq] = NULL;
992
        nl->is_deferred = 0;
993
        nl->connection = PLIP_CN_NONE;
994
        sti();
995
        outb(0x00, PAR_DATA(dev));
996
 
997
        snd->state = PLIP_PK_DONE;
998
        if (snd->skb) {
999
                dev_kfree_skb(snd->skb, FREE_WRITE);
1000
                snd->skb = NULL;
1001
        }
1002
        rcv->state = PLIP_PK_DONE;
1003
        if (rcv->skb) {
1004
                rcv->skb->free = 1;
1005
                kfree_skb(rcv->skb, FREE_READ);
1006
                rcv->skb = NULL;
1007
        }
1008
 
1009
        /* Reset. */
1010
        outb(0x00, PAR_CONTROL(dev));
1011
        MOD_DEC_USE_COUNT;
1012
        return 0;
1013
}
1014
 
1015
static struct enet_statistics *
1016
plip_get_stats(struct device *dev)
1017
{
1018
        struct net_local *nl = (struct net_local *)dev->priv;
1019
        struct enet_statistics *r = &nl->enet_stats;
1020
 
1021
        return r;
1022
}
1023
 
1024
static int
1025
plip_config(struct device *dev, struct ifmap *map)
1026
{
1027
        if (dev->flags & IFF_UP)
1028
                return -EBUSY;
1029
 
1030
        if (map->base_addr != (unsigned long)-1
1031
            && map->base_addr != dev->base_addr)
1032
                printk(KERN_WARNING "%s: You cannot change base_addr of this interface (ignored).\n", dev->name);
1033
 
1034
        if (map->irq != (unsigned char)-1)
1035
                dev->irq = map->irq;
1036
        return 0;
1037
}
1038
 
1039
static int
1040
plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
1041
{
1042
        struct net_local *nl = (struct net_local *) dev->priv;
1043
        struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
1044
 
1045
        switch(pc->pcmd) {
1046
        case PLIP_GET_TIMEOUT:
1047
                pc->trigger = nl->trigger;
1048
                pc->nibble  = nl->nibble;
1049
                break;
1050
        case PLIP_SET_TIMEOUT:
1051
                nl->trigger = pc->trigger;
1052
                nl->nibble  = pc->nibble;
1053
                break;
1054
        default:
1055
                return -EOPNOTSUPP;
1056
        }
1057
        return 0;
1058
}
1059
 
1060
#ifdef MODULE
1061
static int io[] = {0, 0, 0};
1062
static int irq[] = {0, 0, 0};
1063
 
1064
static struct device dev_plip[] = {
1065
        {
1066
                "plip0",
1067
                0, 0, 0, 0,         /* memory */
1068
                0x3BC, 5,               /* base, irq */
1069
                0, 0, 0, NULL, plip_init
1070
        },
1071
        {
1072
                "plip1",
1073
                0, 0, 0, 0,         /* memory */
1074
                0x378, 7,               /* base, irq */
1075
                0, 0, 0, NULL, plip_init
1076
        },
1077
        {
1078
                "plip2",
1079
                0, 0, 0, 0,         /* memory */
1080
                0x278, 2,               /* base, irq */
1081
                0, 0, 0, NULL, plip_init
1082
        }
1083
};
1084
 
1085
int
1086
init_module(void)
1087
{
1088
        int no_parameters=1;
1089
        int devices=0;
1090
        int i;
1091
 
1092
        /* When user feeds parameters, use them */
1093
        for (i=0; i < 3; i++) {
1094
                int specified=0;
1095
 
1096
                if (io[i] != 0) {
1097
                        dev_plip[i].base_addr = io[i];
1098
                        specified++;
1099
                }
1100
                if (irq[i] != 0) {
1101
                        dev_plip[i].irq = irq[i];
1102
                        specified++;
1103
                }
1104
                if (specified) {
1105
                        if (register_netdev(&dev_plip[i]) != 0) {
1106
                                printk(KERN_INFO "plip%d: Not found\n", i);
1107
                                return -EIO;
1108
                        }
1109
                        no_parameters = 0;
1110
                }
1111
        }
1112
        if (!no_parameters)
1113
                return 0;
1114
 
1115
        /* No parameters.  Default action is probing all interfaces. */
1116
        for (i=0; i < 3; i++) {
1117
                if (register_netdev(&dev_plip[i]) == 0)
1118
                        devices++;
1119
        }
1120
        if (devices == 0) {
1121
                printk(KERN_INFO "plip: no interfaces found\n");
1122
                return -EIO;
1123
        }
1124
        return 0;
1125
}
1126
 
1127
void
1128
cleanup_module(void)
1129
{
1130
        int i;
1131
 
1132
        for (i=0; i < 3; i++) {
1133
                if (dev_plip[i].priv) {
1134
                        unregister_netdev(&dev_plip[i]);
1135
                        release_region(PAR_DATA(&dev_plip[i]), (PAR_DATA(&dev_plip[i]) == 0x3bc)? 3 : 8);
1136
                        kfree_s(dev_plip[i].priv, sizeof(struct net_local));
1137
                        dev_plip[i].priv = NULL;
1138
                }
1139
        }
1140
}
1141
#endif /* MODULE */
1142
 
1143
/*
1144
 * Local variables:
1145
 * compile-command: "gcc -DMODULE -DMODVERSIONS -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -g -fomit-frame-pointer -pipe -m486 -c plip.c"
1146
 * End:
1147
 */

powered by: WebSVN 2.1.0

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