root/net/inet/plip.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. plip_init
  2. plip_open
  3. plip_close
  4. plip_tx_packet
  5. get_byte
  6. plip_interrupt
  7. send_byte
  8. plip_write

   1 /* plip.c: A parallel port "network" driver for linux. */
   2 /*
   3     Written 1993 by Donald Becker.  This is unreleased software.
   4     
   5     This is parallel port packet pusher.  It's actually more general
   6     than the "IP" in its name suggests -- but 'plip' is just such a
   7     great name!
   8 
   9     The Author may be reached as becker@super.org or
  10     C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
  11 */
  12 
  13 static char *version =
  14     "plip.c:v0.04 Mar 19 1993 Donald Becker (becker@super.org)\n";
  15 
  16 #include <linux/config.h>
  17 
  18 /*
  19   Sources:
  20         Ideas and protocols came from Russ Nelson's (nelson@crynwr.com)
  21         "parallel.asm" parallel port packet driver.
  22   The "Crynwr" parallel port standard specifies the following protocol:
  23    send header nibble '8'
  24    count-low octet
  25    count-high octet
  26    ... data octets
  27    checksum octet
  28 Each octet is sent as <wait for rx. '1'> <send 0x10+(octet&0x0F)>
  29                         <wait for rx. '0'> <send 0x00+((octet>>4)&0x0F)>
  30 The cable used is a de facto standard parallel null cable -- sold as
  31 a "LapLink" cable by various places.  You'll need a 10-conductor cable to
  32 make one yourself.  The wiring is:
  33     INIT        16 - 16         SLCTIN  17 - 17
  34     GROUND      25 - 25
  35     D0->ERROR   2 - 15          15 - 2
  36     D1->SLCT    3 - 13          13 - 3
  37     D2->PAPOUT  4 - 12          12 - 4
  38     D3->ACK     5 - 10          10 - 5
  39     D4->BUSY    6 - 11          11 - 6
  40   Do not connect the other pins.  They are
  41     D5,D6,D7 are 7,8,9
  42     STROBE is 1, FEED is 14
  43     extra grounds are 18,19,20,21,22,23,24
  44 */
  45 
  46 #include <linux/kernel.h>
  47 #include <linux/sched.h>
  48 #include <linux/types.h>
  49 #include <linux/fcntl.h>
  50 #include <linux/interrupt.h>
  51 #include <linux/string.h>
  52 #include <linux/ptrace.h>
  53 #include <asm/system.h>
  54 #include <asm/io.h>
  55 #include <linux/in.h>
  56 #include <errno.h>
  57 
  58 #include "dev.h"
  59 #include "eth.h"
  60 #include "timer.h"
  61 #include "ip.h"
  62 #include "protocol.h"
  63 #include "tcp.h"
  64 #include "skbuff.h"
  65 #include "sock.h"
  66 #include "arp.h"
  67 
  68 /* use 0 for production, 1 for verification, >2 for debug */
  69 #ifndef PLIP_DEBUG
  70 #define PLIP_DEBUG 9
  71 #endif
  72 static unsigned int plip_debug = PLIP_DEBUG;
  73 
  74 /* The map from IRQ number (as passed to the interrupt handler) to
  75    'struct device'. */
  76 extern struct device *irq2dev_map[16];
  77 
  78 #define PAR_DATA        0
  79 #define PAR_STATUS      1
  80 #define PAR_CONTROL     2
  81 /* Common network statistics -- these will be in *.h someday. */
  82 struct netstats {
  83     int tx_packets;
  84     int rx_packets;
  85     int tx_errors;
  86     int rx_errors;
  87     int missed_packets;
  88     int soft_tx_errors;
  89     int soft_rx_errors;
  90     int soft_trx_err_bits;
  91 };
  92 static struct netstats *localstats;
  93 
  94 /* Index to functions, as function prototypes. */
  95 extern int plip_probe(int ioaddr, struct device *dev);
  96 /* Put in the device structure. */
  97 static int plip_open(struct device *dev);
  98 static int plip_close(struct device *dev);
  99 static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
 100 
 101 /* Routines used internally. */
 102 /* Dispatch from interrupts. */
 103 static void plip_interrupt(int reg_ptr);
 104 static int plip_write(struct device *dev, unsigned char *buf, int length);
 105 
 106 int
 107 plip_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109     int i;
 110 
 111     /* Alpha testers must have the version number to report bugs. */
 112     if (plip_debug > 1) {
 113         static int version_shown = 0;
 114         if (! version_shown)
 115             printk(version), version_shown++;
 116     }
 117 
 118     /* We don't actually probe for anything here, although we might
 119        someday check to see if there's bi-directional port at
 120        dev->base_addr. */
 121 
 122     /* Initialize the device structure. */
 123     dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);
 124     memset(dev->priv, 0, sizeof(struct netstats));
 125     localstats = (struct netstats*) dev->priv;
 126 
 127     for (i = 0; i < DEV_NUMBUFFS; i++)
 128         dev->buffs[i] = NULL;
 129     dev->hard_header    = eth_header;
 130     dev->add_arp        = eth_add_arp;
 131     dev->queue_xmit     = dev_queue_xmit;
 132     dev->rebuild_header = eth_rebuild_header;
 133     dev->type_trans     = eth_type_trans;
 134 
 135     dev->open           = &plip_open;
 136     dev->stop           = &plip_close;
 137     dev->hard_start_xmit = &plip_tx_packet;
 138 
 139     /* These are ethernet specific. */
 140     dev->type = ARPHRD_ETHER;
 141     dev->hard_header_len = ETH_HLEN;
 142     dev->mtu            = 1500; /* eth_mtu */
 143     dev->addr_len       = ETH_ALEN;
 144     for (i = 0; i < dev->addr_len; i++) {
 145         dev->broadcast[i]=0xff;
 146         dev->dev_addr[i] = i;   /* The physical address is 0:1:2:3:4:5! */
 147     }
 148 
 149     /* New-style flags. */
 150     dev->flags          = IFF_BROADCAST;
 151     dev->family         = AF_INET;
 152     dev->pa_addr        = 0;
 153     dev->pa_brdaddr     = 0;
 154     dev->pa_mask        = 0;
 155     dev->pa_alen        = sizeof(unsigned long);
 156 
 157     printk("%s: using parallel port at %#3x, IRQ %d.\n", dev->name,
 158            dev->base_addr, dev->irq);
 159 
 160     return 0;
 161 }
 162 
 163 /* Open/initialize the board.  This is called (in the current kernel)
 164    sometime after booting when the 'config <dev->name>' program is
 165    run.
 166 
 167    This routine gets exclusive access to the parallel port by allocating
 168    its IRQ line.
 169    */
 170 static int
 171 plip_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 172 {
 173     if (dev->irq == 0)
 174         dev->irq = 7;
 175     if (request_irq(dev->irq , &plip_interrupt) != 0) {
 176         if (plip_debug > 2)
 177             printk("%s: couldn't get the IRQ.\n", dev->name);
 178         return EAGAIN;
 179     }
 180 
 181     irq2dev_map[dev->irq] = dev;
 182     outb(0x10, dev->base_addr + PAR_CONTROL);           /* Enable the rx interrupt. */
 183     dev->tbusy = 0;             /* Transmit busy...  */
 184     dev->interrupt = 0;
 185     dev->start = 1;
 186     return 0;
 187 }
 188 
 189 /* The inverse routine to plip_open(). */
 190 static int
 191 plip_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 192 {
 193     dev->start = 0;
 194     free_irq(dev->irq);
 195     irq2dev_map[dev->irq] = NULL;
 196     outb(0x00, dev->base_addr);         /* Release the interrupt. */
 197     return 0;
 198 }
 199 
 200 static int
 201 plip_tx_packet(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 202 {
 203     int ret_val;
 204     /* If some higher layer thinks we've missed an tx-done interrupt
 205        we are passed NULL. Caution: dev_tint() handles the cli()/sti()
 206        itself. */
 207     if (skb == NULL) {
 208         dev_tint(dev);
 209         return 0;
 210     }
 211 
 212     /* Pretend we are an ethernet and fill in the header.  This could use
 213        a simplified routine someday. */
 214     if (!skb->arp  &&  dev->rebuild_header(skb+1, dev)) {
 215         skb->dev = dev;
 216         arp_queue (skb);
 217         return 0;
 218     }
 219 
 220     dev->trans_start = jiffies;
 221     ret_val = plip_write(dev, (unsigned char *)(skb+1), skb->len);
 222     if (skb->free)
 223         kfree_skb (skb, FREE_WRITE);
 224     dev->tbusy = 0;
 225     mark_bh (INET_BH);
 226     return ret_val;
 227 }
 228 
 229 
 230 static inline int get_byte(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 231 {
 232     unsigned char val;
 233     unsigned char low_nibble;
 234     int boguscount = 1500;
 235     do {
 236         val = inb(dev->base_addr + PAR_STATUS);
 237     } while ( ! (val & 0x80) && --boguscount > 0);
 238     low_nibble = (val >> 3) & 0x0f;
 239     if (plip_debug > 8)
 240         printk("%1x", low_nibble);
 241     outb(0x10, dev->base_addr + PAR_DATA);
 242     do {
 243         val = inb(dev->base_addr + PAR_STATUS);
 244     } while ((val & 0x80)  &&  --boguscount > 0);
 245     if (plip_debug > 8)
 246         printk("%1x %s", low_nibble,
 247                boguscount <= 0 ? "timeout":"");
 248     outb(0x00, dev->base_addr + PAR_DATA);
 249     return low_nibble | ((val << 1) & 0xf0);
 250 }
 251 
 252 /* The typical workload of the driver:
 253    Handle the parallel port interrupts. */
 254 static void
 255 plip_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 256 {
 257     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 258     struct device *dev = irq2dev_map[irq];
 259     int boguscount = 1500;
 260     unsigned length;
 261     int sksize;
 262     struct sk_buff *skb;
 263 
 264     if (dev == NULL) {
 265         printk ("plip_interrupt(): irq %d for unknown device.\n", irq);
 266         return;
 267     }
 268     dev->interrupt = 1;
 269     outb(0x00, dev->base_addr + PAR_CONTROL);           /* Disable the rx interrupt. */
 270     sti(); /* Allow other interrupts. */
 271     
 272     if (plip_debug >= 4)
 273         printk("%s: interrupt.\n", dev->name);
 274     
 275     localstats = (struct netstats*) dev->priv;
 276     
 277     /* Receive the packet here. */
 278     if (inb(dev->base_addr + PAR_STATUS) != 0xc7) {
 279         localstats->rx_errors++;                        /* No interrupt! */
 280         if (plip_debug > 4)
 281             printk("%s: No interrupt (status=%#02x)!\n",
 282                    dev->name, inb(dev->base_addr + PAR_STATUS));
 283         return;
 284     }
 285     outb(1, dev->base_addr + PAR_DATA);         /* Ack: 'Ready' */
 286     length = get_byte(dev);
 287     length |= (get_byte(dev) << 8);
 288     if (length > dev->mtu) {
 289         printk("%s: Bogus packet size %d, dropping it.\n", dev->name, length);
 290         return;
 291     }
 292     boguscount = length << 5;
 293     sksize = sizeof(struct sk_buff) + length;
 294     skb = (struct sk_buff *) kmalloc(sksize, GFP_ATOMIC);
 295     if (skb == NULL) {
 296         if (plip_debug)
 297             printk("%s: Couldn't allocate a sk_buff of size %d.\n",
 298                    dev->name, sksize);
 299         localstats->rx_errors++;
 300         return;
 301     }
 302     skb->lock = 0;
 303     skb->mem_len = sksize;
 304     skb->mem_addr = skb;
 305     {
 306         /* 'skb+1' points to the start of sk_buff data area. */
 307         unsigned char *buf = (unsigned char *) (skb+1);
 308         int checksum = 0;
 309 
 310         while (length--) {
 311             unsigned char new_byte = get_byte(dev);
 312             checksum += new_byte, *buf++ = new_byte;
 313         }
 314         if (checksum != get_byte(dev))
 315             localstats->soft_rx_errors++;
 316         else if(dev_rint((unsigned char *)skb, length, IN_SKBUFF, dev)) {
 317             printk("%s: receive buffers full.\n", dev->name);
 318             localstats->rx_errors++;
 319             return;
 320         }
 321     }
 322     /* Wait for the remote end to reset. */
 323     while (inb(dev->base_addr + PAR_STATUS) != 0x87)
 324         if (boguscount-- <= 0 )
 325             break;
 326     outb(0x00, dev->base_addr + PAR_DATA);
 327     outb(0x10, dev->base_addr + PAR_CONTROL);           /* Enable the rx interrupt. */
 328     localstats->rx_packets++;
 329     return;
 330 }
 331 
 332     
 333 static inline int send_byte(struct device *dev, unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 334 {
 335     int boguscount = 1500;
 336     if (plip_debug > 8)
 337         printk("send(%02x) ", val);
 338     outb(0x10 | val, dev->base_addr);
 339     while(inb(dev->base_addr+PAR_STATUS) & 0x80)
 340         if (--boguscount <= 0) break;
 341     outb(val >> 4, dev->base_addr);
 342     while((inb(dev->base_addr+PAR_STATUS) & 0x80) == 0)
 343         if (--boguscount <= 0) break;
 344     if (plip_debug > 4 && boguscount <= 0)
 345         printk("timeout");
 346 }
 347 static int
 348 plip_write(struct device *dev, unsigned char *buf, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
 349 {
 350     int timeout = 1000;                 /* Approx 1 ms. */
 351     char checksum = 0;
 352     int i;
 353     if (plip_debug > 5)
 354         printk("%s: plip_write(%d) %02x %02x %02x %02x %02x...",
 355                dev->name, length, buf[0], buf[1], buf[2], buf[3], buf[4]);
 356     if (length > dev->mtu) {
 357         printk("%s: packet too big, %d.\n", dev->name, length);
 358         return 1;
 359     }
 360     /* This starts the packet protocol by triggering a remote IRQ. */
 361     outb(0x00, dev->base_addr + PAR_CONTROL);   /* Disable my rx interrupt. */
 362     outb(0x08, dev->base_addr + PAR_DATA);      /* Trigger remote rx interrupt. */
 363     while((inb(dev->base_addr+PAR_STATUS) & 0x08) == 0 )
 364         if (--timeout < 0) {
 365             outb(0x00, dev->base_addr);
 366             localstats->tx_errors++;
 367             if (plip_debug > 3)
 368                 printk("%s: Connect failed during send_packet() (length=%d).\n",
 369                        dev->name, length);
 370             /* We failed to send the packet.  To emulate the ethernet we
 371                should pretent the send worked fine, but we don't right now. */
 372             return 1;                   /* Failed to send the packet! */
 373         }
 374     send_byte(dev, length); send_byte(dev, length >> 8);
 375     for (i = 0; i < length; i++)
 376         checksum += buf[i], send_byte(dev, buf[i]);
 377     send_byte(dev, checksum);
 378     outb(0x00, dev->base_addr);
 379     outb(0x10, dev->base_addr + PAR_CONTROL);   /* Enable the rx interrupt. */
 380     localstats->tx_packets++;
 381     if (plip_debug > 5)
 382         printk("plip_write(%d) done.\n", length);
 383     return 0;
 384 }
 385 
 386 /*
 387  * Local variables:
 388  *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c plip.c"
 389  *  version-control: t
 390  *  kept-new-versions: 5
 391  * End:
 392  */

/* [previous][next][first][last][top][bottom][index][help] */