root/drivers/net/znet.c

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

DEFINITIONS

This source file includes following definitions.
  1. znet_probe
  2. znet_open
  3. znet_send_packet
  4. znet_interrupt
  5. znet_rx
  6. znet_close
  7. net_get_stats
  8. set_multicast_list
  9. show_dma
  10. hardware_init
  11. update_stop_hit

   1 /* znet.c: An Zenith Z-Note ethernet driver for linux. */
   2 
   3 static const char *version = "znet.c:v1.02 9/23/94 becker@cesdis.gsfc.nasa.gov\n";
   4 
   5 /*
   6         Written by Donald Becker.
   7 
   8         The author may be reached as becker@cesdis.gsfc.nasa.gov.
   9         This driver is based on the Linux skeleton driver.  The copyright of the
  10         skeleton driver is held by the United States Government, as represented
  11         by DIRNSA, and it is released under the GPL.
  12 
  13         Thanks to Mike Hollick for alpha testing and suggestions.
  14 
  15   References:
  16            The Crynwr packet driver.
  17 
  18           "82593 CSMA/CD Core LAN Controller" Intel datasheet, 1992
  19           Intel Microcommunications Databook, Vol. 1, 1990.
  20     As usual with Intel, the documentation is incomplete and inaccurate.
  21         I had to read the Crynwr packet driver to figure out how to actually
  22         use the i82593, and guess at what register bits matched the loosely
  23         related i82586.
  24 
  25                                         Theory of Operation
  26 
  27         The i82593 used in the Zenith Z-Note series operates using two(!) slave
  28         DMA     channels, one interrupt, and one 8-bit I/O port.
  29 
  30         While there     several ways to configure '593 DMA system, I chose the one
  31         that seemed commensurate with the highest system performance in the face
  32         of moderate interrupt latency: Both DMA channels are configured as
  33         recirculating ring buffers, with one channel (#0) dedicated to Rx and
  34         the other channel (#1) to Tx and configuration.  (Note that this is
  35         different than the Crynwr driver, where the Tx DMA channel is initialized
  36         before each operation.  That approach simplifies operation and Tx error
  37         recovery, but requires additional I/O in normal operation and precludes
  38         transmit buffer chaining.)
  39 
  40         Both rings are set to 8192 bytes using {TX,RX}_RING_SIZE.  This provides
  41         a reasonable ring size for Rx, while simplifying DMA buffer allocation --
  42         DMA buffers must not cross a 128K boundary.  (In truth the size selection
  43         was influenced by my lack of '593 documentation.  I thus was constrained
  44         to use the Crynwr '593 initialization table, which sets the Rx ring size
  45         to 8K.)
  46 
  47         Despite my usual low opinion about Intel-designed parts, I must admit
  48         that the bulk data handling of the i82593 is a good design for
  49         an integrated system, like a laptop, where using two slave DMA channels
  50         doesn't pose a problem.  I still take issue with using only a single I/O
  51         port.  In the same controlled environment there are essentially no
  52         limitations on I/O space, and using multiple locations would eliminate
  53         the     need for multiple operations when looking at status registers,
  54         setting the Rx ring boundary, or switching to promiscuous mode.
  55 
  56         I also question Zenith's selection of the '593: one of the advertised
  57         advantages of earlier Intel parts was that if you figured out the magic
  58         initialization incantation you could use the same part on many different
  59         network types.  Zenith's use of the "FriendlyNet" (sic) connector rather
  60         than an on-board transceiver leads me to believe that they were planning
  61         to take advantage of this.  But, uhmmm, the '593 omits all but ethernet
  62         functionality from the serial subsystem.
  63  */
  64 
  65 #include <linux/kernel.h>
  66 #include <linux/sched.h>
  67 #include <linux/string.h>
  68 #include <linux/ptrace.h>
  69 #include <linux/errno.h>
  70 #include <linux/interrupt.h>
  71 #include <linux/ioport.h>
  72 #include <asm/system.h>
  73 #include <asm/bitops.h>
  74 #include <asm/io.h>
  75 #include <asm/dma.h>
  76 
  77 #include <linux/netdevice.h>
  78 #include <linux/etherdevice.h>
  79 #include <linux/skbuff.h>
  80 #include <linux/if_arp.h>
  81 
  82 #ifndef ZNET_DEBUG
  83 #define ZNET_DEBUG 1
  84 #endif
  85 static unsigned int znet_debug = ZNET_DEBUG;
  86 
  87 /* The DMA modes we need aren't in <dma.h>. */
  88 #define DMA_RX_MODE             0x14    /* Auto init, I/O to mem, ++, demand. */
  89 #define DMA_TX_MODE             0x18    /* Auto init, Mem to I/O, ++, demand. */
  90 #define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17)
  91 #define DMA_BUF_SIZE 8192
  92 #define RX_BUF_SIZE 8192
  93 #define TX_BUF_SIZE 8192
  94 
  95 /* Commands to the i82593 channel 0. */
  96 #define CMD0_CHNL_0                     0x00
  97 #define CMD0_CHNL_1                     0x10            /* Switch to channel 1. */
  98 #define CMD0_NOP (CMD0_CHNL_0)
  99 #define CMD0_PORT_1     CMD0_CHNL_1
 100 #define CMD1_PORT_0     1
 101 #define CMD0_IA_SETUP           1
 102 #define CMD0_CONFIGURE          2
 103 #define CMD0_MULTICAST_LIST 3
 104 #define CMD0_TRANSMIT           4
 105 #define CMD0_DUMP                       6
 106 #define CMD0_DIAGNOSE           7
 107 #define CMD0_Rx_ENABLE          8
 108 #define CMD0_Rx_DISABLE         10
 109 #define CMD0_Rx_STOP            11
 110 #define CMD0_RETRANSMIT         12
 111 #define CMD0_ABORT                      13
 112 #define CMD0_RESET                      14
 113 
 114 #define CMD0_ACK 0x80
 115 
 116 #define CMD0_STAT0 (0 << 5)
 117 #define CMD0_STAT1 (1 << 5)
 118 #define CMD0_STAT2 (2 << 5)
 119 #define CMD0_STAT3 (3 << 5)
 120 
 121 #define net_local znet_private
 122 struct znet_private {
 123         int rx_dma, tx_dma;
 124         struct enet_statistics stats;
 125         /* The starting, current, and end pointers for the packet buffers. */
 126         ushort *rx_start, *rx_cur, *rx_end;
 127         ushort *tx_start, *tx_cur, *tx_end;
 128         ushort tx_buf_len;                      /* Tx buffer length, in words. */
 129 };
 130 
 131 /* Only one can be built-in;-> */
 132 static struct znet_private zn;
 133 static ushort dma_buffer1[DMA_BUF_SIZE/2];
 134 static ushort dma_buffer2[DMA_BUF_SIZE/2];
 135 static ushort dma_buffer3[DMA_BUF_SIZE/2 + 8];
 136 
 137 /* The configuration block.  What an undocumented nightmare.  The first
 138    set of values are those suggested (without explanation) for ethernet
 139    in the Intel 82586 databook.  The rest appear to be completely undocumented,
 140    except for cryptic notes in the Crynwr packet driver.  This driver uses
 141    the Crynwr values verbatim. */
 142 
 143 static unsigned char i593_init[] = {
 144   0xAA,                                 /* 0: 16-byte input & 80-byte output FIFO. */
 145                                                 /*        threshold, 96-byte FIFO, 82593 mode. */
 146   0x88,                                 /* 1: Continuous w/interrupts, 128-clock DMA.*/
 147   0x2E,                                 /* 2: 8-byte preamble, NO address insertion, */
 148                                                 /*        6-byte Ethernet address, loopback off.*/
 149   0x00,                                 /* 3: Default priorities & backoff methods. */
 150   0x60,                                 /* 4: 96-bit interframe spacing. */
 151   0x00,                                 /* 5: 512-bit slot time (low-order). */
 152   0xF2,                                 /* 6: Slot time (high-order), 15 COLL retries. */
 153   0x00,                                 /* 7: Promisc-off, broadcast-on, default CRC. */
 154   0x00,                                 /* 8: Default carrier-sense, collision-detect. */
 155   0x40,                                 /* 9: 64-byte minimum frame length. */
 156   0x5F,                                 /* A: Type/length checks OFF, no CRC input,
 157                                                    "jabber" termination, etc. */
 158   0x00,                                 /* B: Full-duplex disabled. */
 159   0x3F,                                 /* C: Default multicast addresses & backoff. */
 160   0x07,                                 /* D: Default IFS retriggering. */
 161   0x31,                                 /* E: Internal retransmit, drop "runt" packets,
 162                                                    synchr. DRQ deassertion, 6 status bytes. */
 163   0x22,                                 /* F: Receive ring-buffer size (8K), 
 164                                                    receive-stop register enable. */
 165 };
 166 
 167 struct netidblk {
 168         char magic[8];          /* The magic number (string) "NETIDBLK" */
 169         unsigned char netid[8]; /* The physical station address */
 170         char nettype, globalopt;
 171         char vendor[8];         /* The machine vendor and product name. */
 172         char product[8];
 173         char irq1, irq2;                /* Interrupts, only one is currently used.      */
 174         char dma1, dma2;
 175         short dma_mem_misc[8];          /* DMA buffer locations (unused in Linux). */
 176         short iobase1, iosize1;
 177         short iobase2, iosize2;         /* Second iobase unused. */
 178         char driver_options;                    /* Misc. bits */
 179         char pad;
 180 };
 181 
 182 int znet_probe(struct device *dev);
 183 static int      znet_open(struct device *dev);
 184 static int      znet_send_packet(struct sk_buff *skb, struct device *dev);
 185 static void     znet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 186 static void     znet_rx(struct device *dev);
 187 static int      znet_close(struct device *dev);
 188 static struct enet_statistics *net_get_stats(struct device *dev);
 189 static void set_multicast_list(struct device *dev);
 190 static void hardware_init(struct device *dev);
 191 static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset);
 192 
 193 #ifdef notdef
 194 static struct sigaction znet_sigaction = { &znet_interrupt, 0, 0, NULL, };
 195 #endif
 196 
 197 
 198 /* The Z-Note probe is pretty easy.  The NETIDBLK exists in the safe-to-probe
 199    BIOS area.  We just scan for the signature, and pull the vital parameters
 200    out of the structure. */
 201 
 202 int znet_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 203 {
 204         int i;
 205         struct netidblk *netinfo;
 206         char *p;
 207 
 208         /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
 209         for(p = (char *)0xf0000; p < (char *)0x100000; p++)
 210                 if (*p == 'N'  &&  strncmp(p, "NETIDBLK", 8) == 0)
 211                         break;
 212 
 213         if (p >= (char *)0x100000) {
 214                 if (znet_debug > 1)
 215                         printk(KERN_INFO "No Z-Note ethernet adaptor found.\n");
 216                 return ENODEV;
 217         }
 218         netinfo = (struct netidblk *)p;
 219         dev->base_addr = netinfo->iobase1;
 220         dev->irq = netinfo->irq1;
 221 
 222         printk(KERN_INFO "%s: ZNET at %#3lx,", dev->name, dev->base_addr);
 223 
 224         /* The station address is in the "netidblk" at 0x0f0000. */
 225         for (i = 0; i < 6; i++)
 226                 printk(" %2.2x", dev->dev_addr[i] = netinfo->netid[i]);
 227 
 228         printk(", using IRQ %d DMA %d and %d.\n", dev->irq, netinfo->dma1,
 229                 netinfo->dma2);
 230 
 231         if (znet_debug > 1) {
 232                 printk(KERN_INFO "%s: vendor '%16.16s' IRQ1 %d IRQ2 %d DMA1 %d DMA2 %d.\n",
 233                            dev->name, netinfo->vendor,
 234                            netinfo->irq1, netinfo->irq2,
 235                            netinfo->dma1, netinfo->dma2);
 236                 printk(KERN_INFO "%s: iobase1 %#x size %d iobase2 %#x size %d net type %2.2x.\n",
 237                            dev->name, netinfo->iobase1, netinfo->iosize1,
 238                            netinfo->iobase2, netinfo->iosize2, netinfo->nettype);
 239         }
 240 
 241         if (znet_debug > 0)
 242                 printk("%s%s", KERN_INFO, version);
 243 
 244         dev->priv = (void *) &zn;
 245         zn.rx_dma = netinfo->dma1;
 246         zn.tx_dma = netinfo->dma2;
 247 
 248         /* These should never fail.  You can't add devices to a sealed box! */
 249         if (request_irq(dev->irq, &znet_interrupt, 0, "ZNet", NULL)
 250                 || request_dma(zn.rx_dma,"ZNet rx")
 251                 || request_dma(zn.tx_dma,"ZNet tx")) {
 252                 printk(KERN_WARNING "%s: Not opened -- resource busy?!?\n", dev->name);
 253                 return EBUSY;
 254         }
 255         irq2dev_map[dev->irq] = dev;
 256 
 257         /* Allocate buffer memory.      We can cross a 128K boundary, so we
 258            must be careful about the allocation.  It's easiest to waste 8K. */
 259         if (dma_page_eq(dma_buffer1, &dma_buffer1[RX_BUF_SIZE/2-1]))
 260           zn.rx_start = dma_buffer1;
 261         else 
 262           zn.rx_start = dma_buffer2;
 263 
 264         if (dma_page_eq(dma_buffer3, &dma_buffer3[RX_BUF_SIZE/2-1]))
 265           zn.tx_start = dma_buffer3;
 266         else
 267           zn.tx_start = dma_buffer2;
 268         zn.rx_end = zn.rx_start + RX_BUF_SIZE/2;
 269         zn.tx_buf_len = TX_BUF_SIZE/2;
 270         zn.tx_end = zn.tx_start + zn.tx_buf_len;
 271 
 272         /* The ZNET-specific entries in the device structure. */
 273         dev->open = &znet_open;
 274         dev->hard_start_xmit = &znet_send_packet;
 275         dev->stop = &znet_close;
 276         dev->get_stats  = net_get_stats;
 277         dev->set_multicast_list = &set_multicast_list;
 278 
 279         /* Fill in the 'dev' with ethernet-generic values. */
 280         ether_setup(dev);
 281 
 282         return 0;
 283 }
 284 
 285 
 286 static int znet_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 287 {
 288         int ioaddr = dev->base_addr;
 289 
 290         if (znet_debug > 2)
 291                 printk(KERN_DEBUG "%s: znet_open() called.\n", dev->name);
 292 
 293         /* Turn on the 82501 SIA, using zenith-specific magic. */
 294         outb(0x10, 0xe6);                                       /* Select LAN control register */
 295         outb(inb(0xe7) | 0x84, 0xe7);           /* Turn on LAN power (bit 2). */
 296         /* According to the Crynwr driver we should wait 50 msec. for the
 297            LAN clock to stabilize.  My experiments indicates that the '593 can
 298            be initialized immediately.  The delay is probably needed for the
 299            DC-to-DC converter to come up to full voltage, and for the oscillator
 300            to be spot-on at 20Mhz before transmitting.
 301            Until this proves to be a problem we rely on the higher layers for the
 302            delay and save allocating a timer entry. */
 303 
 304         /* This follows the packet driver's lead, and checks for success. */
 305         if (inb(ioaddr) != 0x10 && inb(ioaddr) != 0x00)
 306                 printk(KERN_WARNING "%s: Problem turning on the transceiver power.\n",
 307                            dev->name);
 308 
 309         dev->tbusy = 0;
 310         dev->interrupt = 0;
 311         hardware_init(dev);
 312         dev->start = 1;
 313 
 314         return 0;
 315 }
 316 
 317 static int znet_send_packet(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 318 {
 319         int ioaddr = dev->base_addr;
 320 
 321         if (znet_debug > 4)
 322                 printk(KERN_DEBUG "%s: ZNet_send_packet(%ld).\n", dev->name, dev->tbusy);
 323 
 324         /* Transmitter timeout, likely just recovery after suspending the machine. */
 325         if (dev->tbusy) {
 326                 ushort event, tx_status, rx_offset, state;
 327                 int tickssofar = jiffies - dev->trans_start;
 328                 if (tickssofar < 10)
 329                         return 1;
 330                 outb(CMD0_STAT0, ioaddr); event = inb(ioaddr);
 331                 outb(CMD0_STAT1, ioaddr); tx_status = inw(ioaddr);
 332                 outb(CMD0_STAT2, ioaddr); rx_offset = inw(ioaddr);
 333                 outb(CMD0_STAT3, ioaddr); state = inb(ioaddr);
 334                 printk(KERN_WARNING "%s: transmit timed out, status %02x %04x %04x %02x,"
 335                            " resetting.\n", dev->name, event, tx_status, rx_offset, state);
 336                 if (tx_status == 0x0400)
 337                   printk(KERN_WARNING "%s: Tx carrier error, check transceiver cable.\n",
 338                                  dev->name);
 339                 outb(CMD0_RESET, ioaddr);
 340                 hardware_init(dev);
 341         }
 342 
 343         if (skb == NULL) {
 344                 dev_tint(dev);
 345                 return 0;
 346         }
 347 
 348         /* Check that the part hasn't reset itself, probably from suspend. */
 349         outb(CMD0_STAT0, ioaddr);
 350         if (inw(ioaddr) == 0x0010
 351                 && inw(ioaddr) == 0x0000
 352                 && inw(ioaddr) == 0x0010)
 353           hardware_init(dev);
 354 
 355         /* Block a timer-based transmit from overlapping.  This could better be
 356            done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 357         if (set_bit(0, (void*)&dev->tbusy) != 0)
 358                 printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
 359         else {
 360                 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 361                 unsigned char *buf = (void *)skb->data;
 362                 ushort *tx_link = zn.tx_cur - 1;
 363                 ushort rnd_len = (length + 1)>>1;
 364 
 365                 {
 366                         short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
 367                         unsigned addr = inb(dma_port);
 368                         addr |= inb(dma_port) << 8;
 369                         addr <<= 1;
 370                         if (((int)zn.tx_cur & 0x1ffff) != addr)
 371                           printk(KERN_WARNING "Address mismatch at Tx: %#x vs %#x.\n",
 372                                          (int)zn.tx_cur & 0xffff, addr);
 373                         zn.tx_cur = (ushort *)(((int)zn.tx_cur & 0xfe0000) | addr);
 374                 }
 375 
 376                 if (zn.tx_cur >= zn.tx_end)
 377                   zn.tx_cur = zn.tx_start;
 378                 *zn.tx_cur++ = length;
 379                 if (zn.tx_cur + rnd_len + 1 > zn.tx_end) {
 380                         int semi_cnt = (zn.tx_end - zn.tx_cur)<<1; /* Cvrt to byte cnt. */
 381                         memcpy(zn.tx_cur, buf, semi_cnt);
 382                         rnd_len -= semi_cnt>>1;
 383                         memcpy(zn.tx_start, buf + semi_cnt, length - semi_cnt);
 384                         zn.tx_cur = zn.tx_start + rnd_len;
 385                 } else {
 386                         memcpy(zn.tx_cur, buf, skb->len);
 387                         zn.tx_cur += rnd_len;
 388                 }
 389                 *zn.tx_cur++ = 0;
 390                 cli(); {
 391                         *tx_link = CMD0_TRANSMIT + CMD0_CHNL_1;
 392                         /* Is this always safe to do? */
 393                         outb(CMD0_TRANSMIT + CMD0_CHNL_1,ioaddr);
 394                 } sti();
 395 
 396                 dev->trans_start = jiffies;
 397                 if (znet_debug > 4)
 398                   printk(KERN_DEBUG "%s: Transmitter queued, length %d.\n", dev->name, length);
 399         }
 400         dev_kfree_skb(skb, FREE_WRITE); 
 401         return 0;
 402 }
 403 
 404 /* The ZNET interrupt handler. */
 405 static void     znet_interrupt(int irq, void *dev_id, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 406 {
 407         struct device *dev = irq2dev_map[irq];
 408         int ioaddr;
 409         int boguscnt = 20;
 410 
 411         if (dev == NULL) {
 412                 printk(KERN_WARNING "znet_interrupt(): IRQ %d for unknown device.\n", irq);
 413                 return;
 414         }
 415 
 416         dev->interrupt = 1;
 417         ioaddr = dev->base_addr;
 418 
 419         outb(CMD0_STAT0, ioaddr);
 420         do {
 421                 ushort status = inb(ioaddr);
 422                 if (znet_debug > 5) {
 423                         ushort result, rx_ptr, running;
 424                         outb(CMD0_STAT1, ioaddr);
 425                         result = inw(ioaddr);
 426                         outb(CMD0_STAT2, ioaddr);
 427                         rx_ptr = inw(ioaddr);
 428                         outb(CMD0_STAT3, ioaddr);
 429                         running = inb(ioaddr);
 430                         printk(KERN_DEBUG "%s: interrupt, status %02x, %04x %04x %02x serial %d.\n",
 431                                  dev->name, status, result, rx_ptr, running, boguscnt);
 432                 }
 433                 if ((status & 0x80) == 0)
 434                         break;
 435 
 436                 if ((status & 0x0F) == 4) {     /* Transmit done. */
 437                         struct net_local *lp = (struct net_local *)dev->priv;
 438                         int tx_status;
 439                         outb(CMD0_STAT1, ioaddr);
 440                         tx_status = inw(ioaddr);
 441                         /* It's undocumented, but tx_status seems to match the i82586. */
 442                         if (tx_status & 0x2000) {
 443                                 lp->stats.tx_packets++;
 444                                 lp->stats.collisions += tx_status & 0xf;
 445                         } else {
 446                                 if (tx_status & 0x0600)  lp->stats.tx_carrier_errors++;
 447                                 if (tx_status & 0x0100)  lp->stats.tx_fifo_errors++;
 448                                 if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++;
 449                                 if (tx_status & 0x0020)  lp->stats.tx_aborted_errors++;
 450                                 /* ...and the catch-all. */
 451                                 if ((tx_status | 0x0760) != 0x0760)
 452                                   lp->stats.tx_errors++;
 453                         }
 454                         dev->tbusy = 0;
 455                         mark_bh(NET_BH);        /* Inform upper layers. */
 456                 }
 457 
 458                 if ((status & 0x40)
 459                         || (status & 0x0f) == 11) {
 460                         znet_rx(dev);
 461                 }
 462                 /* Clear the interrupts we've handled. */
 463                 outb(CMD0_ACK,ioaddr);
 464         } while (boguscnt--);
 465 
 466         dev->interrupt = 0;
 467         return;
 468 }
 469 
 470 static void znet_rx(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 471 {
 472         struct net_local *lp = (struct net_local *)dev->priv;
 473         int ioaddr = dev->base_addr;
 474         int boguscount = 1;
 475         short next_frame_end_offset = 0;                /* Offset of next frame start. */
 476         short *cur_frame_end;
 477         short cur_frame_end_offset;
 478 
 479         outb(CMD0_STAT2, ioaddr);
 480         cur_frame_end_offset = inw(ioaddr);
 481 
 482         if (cur_frame_end_offset == zn.rx_cur - zn.rx_start) {
 483                 printk(KERN_WARNING "%s: Interrupted, but nothing to receive, offset %03x.\n",
 484                            dev->name, cur_frame_end_offset);
 485                 return;
 486         }
 487 
 488         /* Use same method as the Crynwr driver: construct a forward list in
 489            the same area of the backwards links we now have.  This allows us to
 490            pass packets to the upper layers in the order they were received --
 491            important for fast-path sequential operations. */
 492          while (zn.rx_start + cur_frame_end_offset != zn.rx_cur
 493                         && ++boguscount < 5) {
 494                 unsigned short hi_cnt, lo_cnt, hi_status, lo_status;
 495                 int count, status;
 496 
 497                 if (cur_frame_end_offset < 4) {
 498                         /* Oh no, we have a special case: the frame trailer wraps around
 499                            the end of the ring buffer.  We've saved space at the end of
 500                            the ring buffer for just this problem. */
 501                         memcpy(zn.rx_end, zn.rx_start, 8);
 502                         cur_frame_end_offset += (RX_BUF_SIZE/2);
 503                 }
 504                 cur_frame_end = zn.rx_start + cur_frame_end_offset - 4;
 505 
 506                 lo_status = *cur_frame_end++;
 507                 hi_status = *cur_frame_end++;
 508                 status = ((hi_status & 0xff) << 8) + (lo_status & 0xff);
 509                 lo_cnt = *cur_frame_end++;
 510                 hi_cnt = *cur_frame_end++;
 511                 count = ((hi_cnt & 0xff) << 8) + (lo_cnt & 0xff);
 512 
 513                 if (znet_debug > 5)
 514                   printk(KERN_DEBUG "Constructing trailer at location %03x, %04x %04x %04x %04x"
 515                                  " count %#x status %04x.\n",
 516                                  cur_frame_end_offset<<1, lo_status, hi_status, lo_cnt, hi_cnt,
 517                                  count, status);
 518                 cur_frame_end[-4] = status;
 519                 cur_frame_end[-3] = next_frame_end_offset;
 520                 cur_frame_end[-2] = count;
 521                 next_frame_end_offset = cur_frame_end_offset;
 522                 cur_frame_end_offset -= ((count + 1)>>1) + 3;
 523                 if (cur_frame_end_offset < 0)
 524                   cur_frame_end_offset += RX_BUF_SIZE/2;
 525         };
 526 
 527         /* Now step  forward through the list. */
 528         do {
 529                 ushort *this_rfp_ptr = zn.rx_start + next_frame_end_offset;
 530                 int status = this_rfp_ptr[-4];
 531                 int pkt_len = this_rfp_ptr[-2];
 532           
 533                 if (znet_debug > 5)
 534                   printk(KERN_DEBUG "Looking at trailer ending at %04x status %04x length %03x"
 535                                  " next %04x.\n", next_frame_end_offset<<1, status, pkt_len,
 536                                  this_rfp_ptr[-3]<<1);
 537                 /* Once again we must assume that the i82586 docs apply. */
 538                 if ( ! (status & 0x2000)) {                             /* There was an error. */
 539                         lp->stats.rx_errors++;
 540                         if (status & 0x0800) lp->stats.rx_crc_errors++;
 541                         if (status & 0x0400) lp->stats.rx_frame_errors++;
 542                         if (status & 0x0200) lp->stats.rx_over_errors++; /* Wrong. */
 543                         if (status & 0x0100) lp->stats.rx_fifo_errors++;
 544                         if (status & 0x0080) lp->stats.rx_length_errors++;
 545                 } else if (pkt_len > 1536) {
 546                         lp->stats.rx_length_errors++;
 547                 } else {
 548                         /* Malloc up new buffer. */
 549                         struct sk_buff *skb;
 550 
 551                         skb = dev_alloc_skb(pkt_len);
 552                         if (skb == NULL) {
 553                                 if (znet_debug)
 554                                   printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
 555                                 lp->stats.rx_dropped++;
 556                                 break;
 557                         }
 558                         skb->dev = dev;
 559 
 560                         if (&zn.rx_cur[(pkt_len+1)>>1] > zn.rx_end) {
 561                                 int semi_cnt = (zn.rx_end - zn.rx_cur)<<1;
 562                                 memcpy(skb_put(skb,semi_cnt), zn.rx_cur, semi_cnt);
 563                                 memcpy(skb_put(skb,pkt_len-semi_cnt), zn.rx_start,
 564                                            pkt_len - semi_cnt);
 565                         } else {
 566                                 memcpy(skb_put(skb,pkt_len), zn.rx_cur, pkt_len);
 567                                 if (znet_debug > 6) {
 568                                         unsigned int *packet = (unsigned int *) skb->data;
 569                                         printk(KERN_DEBUG "Packet data is %08x %08x %08x %08x.\n", packet[0],
 570                                                    packet[1], packet[2], packet[3]);
 571                                 }
 572                   }
 573                   skb->protocol=eth_type_trans(skb,dev);
 574                   netif_rx(skb);
 575                   lp->stats.rx_packets++;
 576                 }
 577                 zn.rx_cur = this_rfp_ptr;
 578                 if (zn.rx_cur >= zn.rx_end)
 579                         zn.rx_cur -= RX_BUF_SIZE/2;
 580                 update_stop_hit(ioaddr, (zn.rx_cur - zn.rx_start)<<1);
 581                 next_frame_end_offset = this_rfp_ptr[-3];
 582                 if (next_frame_end_offset == 0)         /* Read all the frames? */
 583                         break;                  /* Done for now */
 584                 this_rfp_ptr = zn.rx_start + next_frame_end_offset;
 585         } while (--boguscount);
 586 
 587         /* If any worth-while packets have been received, dev_rint()
 588            has done a mark_bh(INET_BH) for us and will work on them
 589            when we get to the bottom-half routine. */
 590         return;
 591 }
 592 
 593 /* The inverse routine to znet_open(). */
 594 static int znet_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 595 {
 596         int ioaddr = dev->base_addr;
 597 
 598         dev->tbusy = 1;
 599         dev->start = 0;
 600 
 601         outb(CMD0_RESET, ioaddr);                       /* CMD0_RESET */
 602 
 603         disable_dma(zn.rx_dma);
 604         disable_dma(zn.tx_dma);
 605 
 606         free_irq(dev->irq, NULL);
 607 
 608         if (znet_debug > 1)
 609                 printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
 610         /* Turn off transceiver power. */
 611         outb(0x10, 0xe6);                                       /* Select LAN control register */
 612         outb(inb(0xe7) & ~0x84, 0xe7);          /* Turn on LAN power (bit 2). */
 613 
 614         return 0;
 615 }
 616 
 617 /* Get the current statistics.  This may be called with the card open or
 618    closed. */
 619 static struct enet_statistics *net_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 620 {
 621                 struct net_local *lp = (struct net_local *)dev->priv;
 622 
 623                 return &lp->stats;
 624 }
 625 
 626 /* Set or clear the multicast filter for this adaptor.
 627    As a side effect this routine must also initialize the device parameters.
 628    This is taken advantage of in open().
 629 
 630    N.B. that we change i593_init[] in place.  This (properly) makes the
 631    mode change persistent, but must be changed if this code is moved to
 632    a multiple adaptor environment.
 633  */
 634 static void set_multicast_list(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 635 {
 636         short ioaddr = dev->base_addr;
 637 
 638         if (dev->flags&IFF_PROMISC) {
 639                 /* Enable promiscuous mode */
 640                 i593_init[7] &= ~3;             i593_init[7] |= 1;
 641                 i593_init[13] &= ~8;    i593_init[13] |= 8;
 642         } else if (dev->mc_list || (dev->flags&IFF_ALLMULTI)) {
 643                 /* Enable accept-all-multicast mode */
 644                 i593_init[7] &= ~3;             i593_init[7] |= 0;
 645                 i593_init[13] &= ~8;    i593_init[13] |= 8;
 646         } else {                                        /* Enable normal mode. */
 647                 i593_init[7] &= ~3;             i593_init[7] |= 0;
 648                 i593_init[13] &= ~8;    i593_init[13] |= 0;
 649         }
 650         *zn.tx_cur++ = sizeof(i593_init);
 651         memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
 652         zn.tx_cur += sizeof(i593_init)/2;
 653         outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
 654 #ifdef not_tested
 655         if (num_addrs > 0) {
 656                 int addrs_len = 6*num_addrs;
 657                 *zn.tx_cur++ = addrs_len;
 658                 memcpy(zn.tx_cur, addrs, addrs_len);
 659                 outb(CMD0_MULTICAST_LIST+CMD0_CHNL_1, ioaddr);
 660                 zn.tx_cur += addrs_len>>1;
 661         }
 662 #endif
 663 }
 664 
 665 void show_dma(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 666 {
 667         short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
 668         unsigned addr = inb(dma_port);
 669         addr |= inb(dma_port) << 8;
 670         printk("Addr: %04x cnt:%3x...", addr<<1, get_dma_residue(zn.tx_dma));
 671 }
 672 
 673 /* Initialize the hardware.  We have to do this when the board is open()ed
 674    or when we come out of suspend mode. */
 675 static void hardware_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 676 {
 677         short ioaddr = dev->base_addr;
 678 
 679         zn.rx_cur = zn.rx_start;
 680         zn.tx_cur = zn.tx_start;
 681 
 682         /* Reset the chip, and start it up. */
 683         outb(CMD0_RESET, ioaddr);
 684 
 685         cli(); {                                                        /* Protect against a DMA flip-flop */
 686                 disable_dma(zn.rx_dma);                 /* reset by an interrupting task. */
 687                 clear_dma_ff(zn.rx_dma);
 688                 set_dma_mode(zn.rx_dma, DMA_RX_MODE);
 689                 set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
 690                 set_dma_count(zn.rx_dma, RX_BUF_SIZE);
 691                 enable_dma(zn.rx_dma);
 692                 /* Now set up the Tx channel. */
 693                 disable_dma(zn.tx_dma);
 694                 clear_dma_ff(zn.tx_dma);
 695                 set_dma_mode(zn.tx_dma, DMA_TX_MODE);
 696                 set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
 697                 set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
 698                 enable_dma(zn.tx_dma);
 699         } sti();
 700 
 701         if (znet_debug > 1)
 702           printk(KERN_DEBUG "%s: Initializing the i82593, tx buf %p... ", dev->name,
 703                          zn.tx_start);
 704         /* Do an empty configure command, just like the Crynwr driver.  This
 705            resets to chip to its default values. */
 706         *zn.tx_cur++ = 0;
 707         *zn.tx_cur++ = 0;
 708         printk("stat:%02x ", inb(ioaddr)); show_dma();
 709         outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
 710         *zn.tx_cur++ = sizeof(i593_init);
 711         memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
 712         zn.tx_cur += sizeof(i593_init)/2;
 713         printk("stat:%02x ", inb(ioaddr)); show_dma();
 714         outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
 715         *zn.tx_cur++ = 6;
 716         memcpy(zn.tx_cur, dev->dev_addr, 6);
 717         zn.tx_cur += 3;
 718         printk("stat:%02x ", inb(ioaddr)); show_dma();
 719         outb(CMD0_IA_SETUP + CMD0_CHNL_1, ioaddr);
 720         printk("stat:%02x ", inb(ioaddr)); show_dma();
 721 
 722         update_stop_hit(ioaddr, 8192);
 723         if (znet_debug > 1)  printk("enabling Rx.\n");
 724         outb(CMD0_Rx_ENABLE+CMD0_CHNL_0, ioaddr);
 725         dev->tbusy = 0;
 726 }
 727 
 728 static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 729 {
 730         outb(CMD0_PORT_1, ioaddr);
 731         if (znet_debug > 5)
 732           printk(KERN_DEBUG "Updating stop hit with value %02x.\n",
 733                          (rx_stop_offset >> 6) | 0x80);
 734         outb((rx_stop_offset >> 6) | 0x80, ioaddr);
 735         outb(CMD1_PORT_0, ioaddr);
 736 }
 737 
 738 /*
 739  * Local variables:
 740  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c znet.c"
 741  *  version-control: t
 742  *  kept-new-versions: 5
 743  *  c-indent-level: 4
 744  *  tab-width: 4
 745  * End:
 746  */

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