root/drivers/net/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. plip_header
  6. plip_device_clear
  7. plip_receiver_error
  8. get_byte
  9. plip_interrupt
  10. plip_receive_packet
  11. send_byte
  12. plip_send_start
  13. plip_send_packet
  14. plip_set_physicaladdr
  15. plip_addrcmp
  16. cold_sleep
  17. double_timeoutfactor
  18. plip_get_stats
  19. init_module
  20. cleanup_module

   1 /*
   2  *       Plip.c: A parallel port "network" driver for linux. 
   3  */
   4 
   5 /*
   6  *      Developement History:
   7  *
   8  *      Original version and the name 'PLIP' from Donald Becker  <becker@super.org>
   9  *              inspired by Russ Nelson's parallel port packet driver.
  10  *      Further development by Tommy Thorn <thorn@daimi.aau.dk>
  11  *      Some changes by Tanabe Hiroyasu <hiro@sanpo.t.u-tokyo.ac.jp>
  12  *      Upgraded for PL12 by Donald Becker
  13  *      Minor hacks by Alan Cox <gw4pts@gw4pts.ampr.org> to get it working
  14  *              more reliably (Ha!)
  15  *     Changes even more Peter Bauer (100136.3530@compuserve.com)
  16  *     Protocol changed back to original plip as in crynwr's packet-drivers.
  17  *     Tested this against ncsa-telnet 2.3 and pcip_pkt using plip.com (which
  18  *     contains "version        equ     0" and ";History:562,1" in the firts 2
  19  *    source-lines                                              28-Mar-94
  20  *
  21  *      Modularised it (Alan Cox). Will upgrade to Niibe's PLIP once its settled
  22  *      down better.
  23  *      
  24  *
  25  *  This is parallel port packet pusher.  It's actually more general
  26  *  than the "IP" in its name suggests -- but 'plip' is just such a
  27  *  great name!
  28  * 
  29  *    
  30  *   Bugs: Please read this: The PLIP driver is a nasty hack and like all nasty hacks 
  31  *         has some 'features'.
  32  *
  33  *      Can lock machines solid if one end goes down or crashes, or due to cable faults.
  34  *      Can lock both machines solid on a broadcast collision.
  35  *      Some laptops don't have all the wires we use.
  36  *      Doesn't match the original Russ Nelson protocol so won't talk to Amiga or PC drivers.
  37  *      Waits far too long with interrupts off [X is unbearable, forget action games, xntp is a joke]
  38  *      Doesn't work on some fast 486DX machines
  39  *
  40  *      If it works be thankful, if not fix it!
  41  *
  42  *  Info:
  43  *      I <Alan> got 15K/second NFS throughput (about 20-25K second IP). I also got some ethernet cards
  44  *      so don't ask me for help. This code needs a real major rewrite. Any volunteers ?
  45  *
  46  ***** So we can all compare loads of different PLIP drivers for a bit I've modularised this beastie too.
  47  ***** In addition a seperate bidirectional plip module can be done.
  48  */
  49 
  50 static char *version =
  51     "NET3 "
  52 #ifdef MODULE
  53     "MODULAR "    
  54 #endif    
  55     "PLIP.010 (from plip.c:v0.15 for 0.99pl12+, 8/11/93)\n";
  56 
  57 #include <linux/config.h>
  58 
  59 /*
  60   Sources:
  61         Ideas and protocols came from Russ Nelson's (nelson@crynwr.com)
  62         "parallel.asm" parallel port packet driver.
  63         TANABE Hiroyasu changes the protocol.
  64   The "Crynwr" parallel port standard specifies the following protocol:
  65    send header nibble '8'
  66    type octet '0xfd' or '0xfc'
  67    count-low octet
  68    count-high octet
  69    ... data octets
  70    checksum octet
  71 Each octet is sent as <wait for rx. '0x1?'> <send 0x10+(octet&0x0F)>
  72                         <wait for rx. '0x0?'> <send 0x00+((octet>>4)&0x0F)>
  73 
  74 The cable used is a de facto standard parallel null cable -- sold as
  75 a "LapLink" cable by various places.  You'll need a 10-conductor cable to
  76 make one yourself.  The wiring is:
  77     INIT        16 - 16         SLCTIN  17 - 17
  78     GROUND      25 - 25
  79     D0->ERROR   2 - 15          15 - 2
  80     D1->SLCT    3 - 13          13 - 3
  81     D2->PAPOUT  4 - 12          12 - 4
  82     D3->ACK     5 - 10          10 - 5
  83     D4->BUSY    6 - 11          11 - 6
  84   Do not connect the other pins.  They are
  85     D5,D6,D7 are 7,8,9
  86     STROBE is 1, FEED is 14
  87     extra grounds are 18,19,20,21,22,23,24
  88 */
  89 
  90 #include <linux/kernel.h>
  91 #include <linux/sched.h>
  92 #include <linux/types.h>
  93 #include <linux/fcntl.h>
  94 #include <linux/interrupt.h>
  95 #include <linux/string.h>
  96 #include <linux/ptrace.h>
  97 #include <linux/if_ether.h>
  98 #include <asm/system.h>
  99 #include <asm/io.h>
 100 #include <netinet/in.h>
 101 #include <errno.h>
 102 
 103 #include <linux/netdevice.h>
 104 #include <linux/etherdevice.h>
 105 #include <linux/skbuff.h>
 106 
 107 #ifdef MODULE
 108 #include <linux/module.h>
 109 #include "../../tools/version.h"
 110 #endif
 111 
 112 #ifdef PRINTK
 113 #undef PRINTK
 114 #endif
 115 #ifdef PRINTK2
 116 #undef PRINTK2
 117 #endif
 118 
 119 #define PLIP_DEBUG      /* debugging */
 120 #undef  PLIP_DEBUG2     /* debugging with more varbose report */
 121 
 122 #ifdef PLIP_DEBUG
 123 #define PRINTK(x) printk x
 124 #else
 125 #define PRINTK(x) /**/
 126 #endif
 127 #ifdef PLIP_DEBUG2
 128 #define PRINTK2(x) printk x
 129 #else
 130 #define PRINTK2(x) /**/
 131 #endif
 132 
 133 /* The map from IRQ number (as passed to the interrupt handler) to
 134    'struct device'. */
 135 extern struct device *irq2dev_map[16];
 136 
 137 /* Network statistics, with the same names as 'struct enet_statistics'. */
 138 #define netstats enet_statistics
 139 
 140 /* constants */
 141 #define PAR_DATA        0
 142 #define PAR_STATUS      1
 143 #define PAR_CONTROL     2
 144 #define PLIP_MTU 1600
 145 #define PLIP_HEADER_TYPE1 0xfd
 146 #define PLIP_HEADER_TYPE2 0xfc
 147 
 148 /* Index to functions, as function prototypes. */
 149 extern int plip_probe(int ioaddr, struct device *dev);
 150 static int plip_open(struct device *dev);
 151 static int plip_close(struct device *dev);
 152 static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
 153 static int plip_header (unsigned char *buff, struct device *dev,
 154                  unsigned short type, void *dest,
 155                  void *source, unsigned len, struct sk_buff *skb);
 156 
 157 /* variables used internally. */
 158 #define INITIALTIMEOUTFACTOR 4
 159 #define MAXTIMEOUTFACTOR 20
 160 static int timeoutfactor = INITIALTIMEOUTFACTOR;
 161 
 162 /* Routines used internally. */
 163 static void plip_device_clear(struct device *dev);
 164 static void plip_receiver_error(struct device *dev);
 165 static void plip_set_physicaladdr(struct device *dev, unsigned long ipaddr);
 166 static int plip_addrcmp(struct ethhdr *eth);
 167 static void cold_sleep(int tics);
 168 static void plip_interrupt(int reg_ptr); /* Dispatch from interrupts. */
 169 static int plip_receive_packet(struct device *dev);
 170 static int plip_send_packet(struct device *dev, unsigned char *buf, int length);
 171 static int plip_send_start(struct device *dev, struct ethhdr *eth);
 172 static void double_timeoutfactor(void);
 173 static struct enet_statistics *plip_get_stats(struct device *dev);
 174 
 175 int
 176 plip_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178     int port_base = dev->base_addr;
 179     int i;
 180 
 181     /* Check that there is something at base_addr. */
 182     outb(0x00, port_base + PAR_CONTROL);
 183     outb(0x55, port_base + PAR_DATA);
 184     if (inb(port_base + PAR_DATA) != 0x55)
 185         return -ENODEV;
 186 
 187     /* Alpha testers must have the version number to report bugs. */
 188 #ifdef PLIP_DEBUG
 189     {
 190         static int version_shown = 0;
 191         if (! version_shown)
 192             printk(version), version_shown++;
 193     }
 194 #endif
 195 
 196     /* Initialize the device structure. */
 197     dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);
 198     memset(dev->priv, 0, sizeof(struct netstats));
 199 
 200     for (i = 0; i < DEV_NUMBUFFS; i++)
 201         skb_queue_head_init(&dev->buffs[i]);
 202 
 203     dev->hard_header = &plip_header;
 204     dev->rebuild_header = eth_rebuild_header;
 205     dev->type_trans = eth_type_trans;
 206 
 207     dev->open = &plip_open;
 208     dev->stop = &plip_close;
 209     dev->hard_start_xmit = &plip_tx_packet;
 210     dev->get_stats = &plip_get_stats;
 211 
 212     /* These are ethernet specific. */
 213     dev->type = ARPHRD_ETHER;
 214     dev->hard_header_len = ETH_HLEN;
 215     dev->mtu = PLIP_MTU;        /* PLIP may later negotiate max pkt size */
 216     dev->addr_len = ETH_ALEN;
 217     for (i = 0; i < dev->addr_len; i++) {
 218         dev->broadcast[i]=0xff;
 219         dev->dev_addr[i] = 0;
 220     }
 221     printk("%s: configured for parallel port at %#3x, IRQ %d.\n",
 222            dev->name, dev->base_addr, dev->irq);
 223 
 224     /* initialize internal value */
 225     timeoutfactor = INITIALTIMEOUTFACTOR;
 226     return 0;
 227 }
 228 
 229 /* Open/initialize the board.  This is called (in the current kernel)
 230    sometime after booting when the 'config <dev->name>' program is
 231    run.
 232 
 233    This routine gets exclusive access to the parallel port by allocating
 234    its IRQ line.
 235    */
 236    
 237 static int plip_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 238 {
 239     if (dev->irq == 0)
 240         dev->irq = 7;
 241     cli();
 242     if (request_irq(dev->irq , &plip_interrupt) != 0) {
 243         sti();
 244         PRINTK(("%s: couldn't get IRQ %d.\n", dev->name, dev->irq));
 245         return -EAGAIN;
 246     }
 247 
 248     irq2dev_map[dev->irq] = dev;
 249     sti();
 250     plip_device_clear(dev);
 251     dev->tbusy = 0;
 252     dev->interrupt = 0;
 253     dev->start = 1;
 254 #ifdef MODULE
 255     MOD_INC_USE_COUNT;
 256 #endif        
 257     return 0;
 258 }
 259 
 260 /* The inverse routine to plip_open(). */
 261 static int
 262 plip_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 263 {
 264     dev->tbusy = 1;
 265     dev->start = 0;
 266     cli();
 267     free_irq(dev->irq);
 268     irq2dev_map[dev->irq] = NULL;
 269     sti();
 270     outb(0x00, dev->base_addr);         /* Release the interrupt. */
 271 #ifdef MODULE
 272     MOD_DEC_USE_COUNT;
 273 #endif        
 274     return 0;
 275 }
 276 
 277 static int
 278 plip_tx_packet(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 279 {
 280     int ret_val;
 281 
 282     if (dev->tbusy || dev->interrupt) { /* Do timeouts, to avoid hangs. */
 283         int tickssofar = jiffies - dev->trans_start;
 284         if (tickssofar < 50)
 285             return 1;
 286         printk("%s: transmit timed out\n", dev->name);
 287         /* Try to restart the adaptor. */
 288         plip_device_clear(dev);
 289         return 0;
 290     }
 291 
 292     /* If some higher layer thinks we've missed an tx-done interrupt
 293        we are passed NULL. Caution: dev_tint() handles the cli()/sti()
 294        itself. */
 295     if (skb == NULL) {
 296         dev_tint(dev);
 297         return 0;
 298     }
 299 
 300     dev->trans_start = jiffies;
 301     ret_val = plip_send_packet(dev, skb->data, skb->len);
 302     if (skb->free)
 303         kfree_skb (skb, FREE_WRITE);
 304     dev->tbusy = 0;
 305     mark_bh (NET_BH);
 306     return 0/*ret_val*/;
 307 }
 308 
 309 static int
 310 plip_header (unsigned char *buff, struct device *dev,
     /* [previous][next][first][last][top][bottom][index][help] */
 311              unsigned short type, void *daddr                ,
 312              void *saddr, unsigned len, struct sk_buff *skb)
 313 {
 314     if (dev->dev_addr[0] == 0) {
 315         /* set physical address */
 316         plip_set_physicaladdr(dev, dev->pa_addr);
 317     }
 318     return eth_header(buff, dev, type, daddr, saddr, len, skb);
 319 }
 320 
 321 static void
 322   plip_device_clear(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 323 {
 324     dev->interrupt = 0;
 325     dev->tbusy = 0;
 326     outb(0x00, dev->base_addr + PAR_DATA);
 327     outb(0x10, dev->base_addr + PAR_CONTROL);           /* Enable the rx interrupt. */
 328 }
 329 
 330 static void
 331   plip_receiver_error(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 332 {
 333     dev->interrupt = 0;
 334     dev->tbusy = 0;
 335     outb(0x02, dev->base_addr + PAR_DATA);
 336     outb(0x10, dev->base_addr + PAR_CONTROL);           /* Enable the rx interrupt. */
 337 }
 338 
 339 static int
 340   get_byte(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 341 {
 342     unsigned char val, oldval;
 343     unsigned char low_nibble;
 344     int timeout;
 345     int error = 0;
 346     val = inb(dev->base_addr + PAR_STATUS);
 347     timeout = jiffies + timeoutfactor * 2;
 348     do {
 349         oldval = val;
 350         val = inb(dev->base_addr + PAR_STATUS);
 351         if ( oldval != val ) continue; /* it's unstable */
 352         if ( timeout < jiffies ) {
 353             error++;
 354             break;
 355         }
 356     } while ( (val & 0x80) );
 357     val = inb(dev->base_addr + PAR_STATUS);
 358     low_nibble = (val >> 3) & 0x0f;
 359     outb(0x10, dev->base_addr + PAR_DATA);
 360     timeout = jiffies + timeoutfactor * 2;
 361     do {
 362         oldval = val;
 363         val = inb(dev->base_addr + PAR_STATUS);
 364         if (oldval != val) continue; /* it's unstable */
 365         if ( timeout < jiffies ) {
 366             error++;
 367             break;
 368         }
 369     } while ( !(val & 0x80) );
 370     val = inb(dev->base_addr + PAR_STATUS);
 371     PRINTK2(("%02x %s ", low_nibble | ((val << 1) & 0xf0),
 372                error ? "t":""));
 373     outb(0x00, dev->base_addr + PAR_DATA);
 374     if (error) {
 375         /* timeout error */
 376         double_timeoutfactor();
 377         return -1;
 378     }
 379     return low_nibble | ((val << 1) & 0xf0);
 380 }
 381 
 382 /* The typical workload of the driver:
 383    Handle the parallel port interrupts. */
 384 static void
 385   plip_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 386 {
 387     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 388     struct device *dev = irq2dev_map[irq];
 389     struct netstats *localstats;
 390 
 391     if (dev == NULL) {
 392         PRINTK(("plip_interrupt(): irq %d for unknown device.\n", irq));
 393         return;
 394     }
 395     localstats = (struct netstats*) dev->priv;
 396     if (dev->tbusy || dev->interrupt) return;
 397     dev->interrupt = 1;
 398     outb(0x00, dev->base_addr + PAR_CONTROL);  /* Disable the rx interrupt. */
 399     sti(); /* Allow other interrupts. */
 400     PRINTK2(("%s: interrupt.  ", dev->name));
 401 
 402     {
 403         /* check whether the interrupt is valid or not.*/
 404         int timeout = jiffies + timeoutfactor;
 405         while ((inb(dev->base_addr + PAR_STATUS) & 0xf8) != 0xc0) {
 406             if ( timeout < jiffies ) {
 407                 PRINTK2(("%s: No interrupt (status=%#02x)!\n",
 408                          dev->name, inb(dev->base_addr + PAR_STATUS)));
 409                 plip_device_clear(dev);
 410                 return;
 411             }
 412         }
 413     }
 414     if (plip_receive_packet(dev)) {
 415         /* get some error while receiving data */
 416         localstats->rx_errors++;
 417         plip_receiver_error(dev);
 418     } else {
 419         plip_device_clear(dev);
 420     }
 421 }
 422 
 423 static int
 424 plip_receive_packet(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 425 {
 426     unsigned length;
 427     int checksum = 0;
 428     struct sk_buff *skb;
 429     struct netstats *localstats;
 430     struct ethhdr eth;
 431 
 432     localstats = (struct netstats*) dev->priv;
 433     
 434     outb(1, dev->base_addr + PAR_DATA);         /* Ack: 'Ready' */
 435 
 436     {
 437         /* get header octet and length of packet */
 438         
 439         length = get_byte(dev);
 440         length |= get_byte(dev) << 8;
 441         {
 442          int i;
 443          unsigned char *eth_p = (unsigned char*)&eth;
 444          for ( i = 0; i < sizeof(eth); i++, eth_p++) {
 445              *eth_p = get_byte(dev);
 446          }
 447         }
 448         PRINTK2(("length = %d\n", length));
 449         if (length > dev->mtu || length < 8) {
 450             PRINTK2(("%s: bogus packet size %d.\n", dev->name, length));
 451             return 1;
 452         }
 453     }
 454     {
 455         /* get skb area from kernel and 
 456          * set appropriate values to skb
 457          */
 458         skb = alloc_skb(length, GFP_ATOMIC);
 459         if (skb == NULL) {
 460             PRINTK(("%s: Couldn't allocate a sk_buff of size %d.\n",
 461                     dev->name,length));
 462             return 1;
 463         }
 464         skb->lock = 0;
 465     }
 466     {
 467         /* phase of receiving the data */
 468         /* 'skb->data' points to the start of sk_buff data area. */
 469         unsigned char *buf = skb->data;
 470         unsigned char *eth_p = (unsigned char *)&eth;
 471         int i;
 472         for ( i = 0; i < sizeof(eth); i++) {
 473             checksum += *eth_p;
 474             *buf++ = *eth_p++;
 475         }
 476         for ( i = 0; i < length - sizeof(eth); i++) {
 477             unsigned char new_byte = get_byte(dev);
 478             checksum += new_byte;
 479             *buf++ = new_byte;
 480         }
 481         checksum &= 0xff;
 482         if (checksum != get_byte(dev)) {
 483             localstats->rx_crc_errors++;
 484             PRINTK(("checksum error\n"));
 485             return 1;
 486         } else if(dev_rint((unsigned char *)skb, length, IN_SKBUFF, dev)) {
 487             printk("%s: rcv buff full.\n", dev->name);
 488             localstats->rx_dropped++;
 489             return 1;
 490         }
 491     }
 492     {
 493         /* phase of terminating this connection */
 494         int timeout;
 495 
 496         timeout = jiffies + length * timeoutfactor / 16;
 497         outb(0x00, dev->base_addr + PAR_DATA);
 498         /* Wait for the remote end to reset. */
 499         while ( (inb(dev->base_addr + PAR_STATUS) & 0xf8) != 0x80 ) {
 500             if (timeout < jiffies ) {
 501                 double_timeoutfactor();
 502                 PRINTK(("Remote has not reset.\n"));
 503                 break;
 504             }
 505         }
 506     }
 507     localstats->rx_packets++;
 508     return 0;
 509 }
 510 
 511 
 512 static int send_byte(struct device *dev, unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 513 {
 514     int timeout;
 515     int error = 0;
 516     PRINTK2((" S%02x", val));
 517     outb((val & 0xf), dev->base_addr); /* this makes data bits more stable */
 518                                        /* (especially the &0xf :-> PB )    */
 519     outb(0x10 | (val & 0xf), dev->base_addr);
 520     timeout = jiffies + timeoutfactor;
 521     while( inb(dev->base_addr+PAR_STATUS) & 0x80 )
 522         if ( timeout < jiffies ) {
 523             error++;
 524             break;
 525         }
 526     outb(0x10 | (val >> 4), dev->base_addr);
 527     outb(val >> 4, dev->base_addr);
 528     timeout = jiffies + timeoutfactor;
 529     while( (inb(dev->base_addr+PAR_STATUS) & 0x80) == 0 )
 530         if ( timeout < jiffies ) {
 531             error++;
 532             break;
 533         }
 534     if (error) {
 535         /* timeout error */
 536         double_timeoutfactor();
 537         PRINTK2(("t"));
 538         return -1;
 539     }
 540     return 0;
 541 }
 542 /*
 543  * plip_send_start
 544  * trigger remoto rx interrupt and establish a connection.
 545  * 
 546  * return value
 547  * 0 : establish the connection
 548  * -1 : connection failed.
 549  */
 550 static int
 551 plip_send_start(struct device *dev, struct ethhdr *eth)
     /* [previous][next][first][last][top][bottom][index][help] */
 552 {       
 553     int timeout;
 554     int status;
 555     int lasttrigger;
 556     struct netstats *localstats = (struct netstats*) dev->priv;
 557 
 558     /* This starts the packet protocol by triggering a remote IRQ. */
 559     timeout = jiffies + timeoutfactor * 16;
 560     lasttrigger = jiffies;
 561     while ( ((status = inb(dev->base_addr+PAR_STATUS)) & 0x08) == 0 ) {
 562         dev->tbusy = 1;
 563         outb(0x00, dev->base_addr + PAR_CONTROL); /* Disable my rx intr. */
 564         outb(0x08, dev->base_addr + PAR_DATA);  /* Trigger remote rx intr. */
 565         if (status & 0x40) {
 566             /* The remote end is also trying to send a packet.
 567              * Only one end may go to the receiving phase,
 568              * so we use the "ethernet" address (set from the IP address)
 569              * to determine which end dominates.
 570              */
 571             if ( plip_addrcmp(eth) > 0 ) {
 572                 localstats->collisions++;
 573                 PRINTK2(("both ends are trying to send a packet.\n"));
 574                 if (plip_receive_packet(dev)) {
 575                     /* get some error while receiving data */
 576                     localstats->rx_errors++;
 577                     outb(0x02, dev->base_addr + PAR_DATA);
 578                 } else {
 579                     outb(0x00, dev->base_addr + PAR_DATA);
 580                 }
 581                 cold_sleep(2); /* make sure that remote end is ready */
 582             }
 583             continue; /* restart send sequence */
 584         }
 585         if (lasttrigger != jiffies) {
 586             /* trigger again */
 587             outb(0x00, dev->base_addr + PAR_DATA);
 588             cold_sleep(1);
 589             lasttrigger = jiffies;
 590         }
 591         if (timeout < jiffies) {
 592             double_timeoutfactor();
 593             plip_device_clear(dev);
 594             localstats->tx_errors++;
 595             PRINTK(("%s: Connect failed in send_packet().\n",
 596                     dev->name));
 597             /* We failed to send the packet.  To emulate the ethernet we
 598                should pretent the send worked fine */
 599             return -1;
 600         }
 601     }
 602     return 0;
 603 }
 604 static int
 605 plip_send_packet(struct device *dev, unsigned char *buf, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
 606 {
 607     int error = 0;
 608     struct netstats *localstats;
 609 
 610     PRINTK2(("%s: plip_send_packet(%d) %02x %02x %02x %02x %02x...",
 611            dev->name, length, buf[0], buf[1], buf[2], buf[3], buf[4]));
 612     if (length > dev->mtu) {
 613         printk("%s: packet too big, %d.\n", dev->name, length);
 614         return 0;
 615     }
 616     localstats = (struct netstats*) dev->priv;
 617 
 618     {
 619         /* phase of checking remote status */
 620         int i;
 621         int timeout = jiffies + timeoutfactor * 8;
 622         while ( (i = (inb(dev->base_addr+PAR_STATUS) & 0xe8)) != 0x80 ) {
 623             if (i == 0x78) {
 624                 /* probably cable is not connected */
 625                 /* Implementation Note:
 626                  * This status should result in 'Network unreachable'.
 627                  * but I don't know the way.
 628                  */
 629                 return 0;
 630             }
 631             if (timeout < jiffies) {
 632                 /* remote end is not ready */
 633                 double_timeoutfactor();
 634                 localstats->tx_errors++;
 635                 PRINTK(("remote end is not ready.\n"));
 636                 return 1; /* Failed to send the packet */
 637             }
 638         }
 639     }
 640     /* phase of making a connection */
 641     if (plip_send_start(dev, (struct ethhdr *)buf) < 0)
 642         return 1;
 643 
 644     {
 645         /* send packet's length 
 646            the byte order has changed now and then. Today it's sent as in 
 647            the original crynwr-plip ...
 648            Gruss PB
 649          */
 650         send_byte(dev, length); 
 651         send_byte(dev, length >> 8);
 652     }
 653     {
 654         /* phase of sending data */
 655         int i;
 656         int checksum = 0;
 657 
 658         for ( i = 0; i < sizeof(struct ethhdr); i++ ) {
 659             send_byte(dev, *buf);
 660             checksum += *buf++;
 661         }
 662 
 663         for (i = 0; i < length - sizeof(struct ethhdr); i++) {
 664             checksum += buf[i];
 665             if (send_byte(dev, buf[i]) < 0) {
 666                 error++;
 667                 break;
 668             }
 669         }
 670         send_byte(dev, checksum & 0xff);
 671     }
 672     {
 673         /* phase of terminating this connection */
 674         int timeout;
 675         
 676         outb(0x00, dev->base_addr + PAR_DATA);
 677         /* Wait for the remote end to reset. */
 678         timeout = jiffies + ((length * timeoutfactor) >> 4);
 679         while ((inb(dev->base_addr + PAR_STATUS) & 0xe8) != 0x80) {
 680             if (timeout < jiffies ) {   
 681                 double_timeoutfactor();
 682                 PRINTK(("Remote end has not reset.\n"));
 683                 error++;
 684                 break;
 685             }
 686         }
 687         if (inb(dev->base_addr + PAR_STATUS) & 0x10) {
 688             /* receiver reports error */
 689             error++;
 690         }
 691     }
 692     plip_device_clear(dev);
 693     localstats->tx_packets++;
 694     PRINTK2(("plip_send_packet(%d) done.\n", length));
 695     return error?1:0;
 696 }
 697 
 698 /*
 699  * some trivial functions
 700  */
 701 static void
 702 plip_set_physicaladdr(struct device *dev, unsigned long ipaddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 703 {
 704     /*
 705      * set physical address to
 706      *  0xfd.0xfd.ipaddr
 707      */
 708 
 709     unsigned char *addr = dev->dev_addr;
 710     int i;
 711 
 712     if ((ipaddr >> 24) == 0 || (ipaddr >> 24) == 0xff) return;
 713     PRINTK2(("%s: set physical address to %08x\n", dev->name, ipaddr));
 714     for (i=0; i < ETH_ALEN - sizeof(unsigned long); i++) {
 715         addr[i] = 0xfd;
 716     }
 717     memcpy(&(addr[i]), &ipaddr, sizeof(unsigned long));
 718 }
 719 
 720 static int
 721 plip_addrcmp(struct ethhdr *eth)
     /* [previous][next][first][last][top][bottom][index][help] */
 722 {
 723     int i;
 724     for ( i = ETH_ALEN - 1; i >= 0; i-- ) {
 725         if (eth->h_dest[i] > eth->h_source[i]) return -1;
 726         if (eth->h_dest[i] < eth->h_source[i]) return 1;
 727     }
 728     PRINTK2(("h_dest = %08x%04x h_source = %08x%04x\n",
 729             *(long*)&eth->h_dest[2],*(short*)&eth->h_dest[0],
 730             *(long*)&eth->h_source[2],*(short*)&eth->h_source[0]));
 731     return 0;
 732 }
 733 
 734 /* This function is evil, evil, evil.  This should be a
 735    _kernel_, rescheduling sleep!. */
 736 static void
 737 cold_sleep(int tics)
     /* [previous][next][first][last][top][bottom][index][help] */
 738 {
 739     int start = jiffies;
 740     while(jiffies < start + tics)
 741         ; /* do nothing */
 742     return;
 743 }
 744 
 745 static void
 746   double_timeoutfactor()
     /* [previous][next][first][last][top][bottom][index][help] */
 747 {
 748     timeoutfactor *= 2;
 749     if (timeoutfactor >= MAXTIMEOUTFACTOR) {
 750         timeoutfactor = MAXTIMEOUTFACTOR;
 751     }
 752     return;
 753 }
 754 
 755 static struct enet_statistics *
 756 plip_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 757 {
 758     struct netstats *localstats = (struct netstats*) dev->priv;
 759     return localstats;
 760 }
 761 
 762 /*
 763  * Local variables:
 764  *  compile-command: "gcc -D__KERNEL__ -Wall -O6 -fomit-frame-pointer -x c++ -c plip.c"
 765  *  version-control: t
 766  *  kept-new-versions: 5
 767  * End:
 768  */
 769 
 770 #ifdef MODULE
 771 char kernel_version[] = UTS_RELEASE;
 772 
 773 static struct device dev_plip0 = 
 774 {
 775         "plip0" /*"plip"*/,
 776         0, 0, 0, 0,             /* memory */
 777         0x3BC, 5,               /* base, irq */
 778         0, 0, 0, NULL, plip_init 
 779 };
 780 
 781 static struct device dev_plip1 = 
 782 {
 783         "plip1" /*"plip"*/,
 784         0, 0, 0, 0,             /* memory */
 785         0x378, 7,               /* base, irq */
 786         0, 0, 0, NULL, plip_init 
 787 };
 788 
 789 static struct device dev_plip2 = 
 790 {
 791         "plip2" /*"plip"*/,
 792         0, 0, 0, 0,             /* memory */
 793         0x278, 2,               /* base, irq */
 794         0, 0, 0, NULL, plip_init 
 795 };
 796 
 797 int
 798 init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 799 {
 800         int err;
 801 
 802         if ( ((err=register_netdev(&dev_plip0)) == 0) &&
 803              ((err=register_netdev(&dev_plip1)) == 0) &&
 804              ((err=register_netdev(&dev_plip2)) == 0)
 805            )
 806         {
 807                 if(err==-EEXIST)
 808                         printk("plip devices already present. Module not loaded.\n");
 809                 return err;
 810         }
 811         return 0;
 812 }
 813 
 814 void
 815 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 816 {
 817         if (MOD_IN_USE)
 818                 printk("plip: device busy, remove delayed\n");
 819         else
 820         {
 821                 unregister_netdev(&dev_plip0);
 822                 if(dev_plip0.priv)
 823                 {
 824                         kfree_s(dev_plip0.priv,sizeof(struct netstats));
 825                         dev_plip0.priv=NULL;
 826                 }
 827                 unregister_netdev(&dev_plip1);
 828                 if(dev_plip1.priv)
 829                 {
 830                         kfree_s(dev_plip1.priv,sizeof(struct netstats));
 831                         dev_plip0.priv=NULL;
 832                 }
 833                 unregister_netdev(&dev_plip2);
 834                 if(dev_plip2.priv)
 835                 {
 836                         kfree_s(dev_plip2.priv,sizeof(struct netstats));
 837                         dev_plip2.priv=NULL;
 838                 }
 839         }
 840 }
 841 #endif /* MODULE */

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