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 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 reg_ptr);
 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, int num_addrs, void *addrs);
 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 %#3x,", 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")
 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(%d).\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+1);
 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 reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 406 {
 407         int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 408         struct device *dev = irq2dev_map[irq];
 409         int ioaddr;
 410         int boguscnt = 20;
 411 
 412         if (dev == NULL) {
 413                 printk(KERN_WARNING "znet_interrupt(): IRQ %d for unknown device.\n", irq);
 414                 return;
 415         }
 416 
 417         dev->interrupt = 1;
 418         ioaddr = dev->base_addr;
 419 
 420         outb(CMD0_STAT0, ioaddr);
 421         do {
 422                 ushort status = inb(ioaddr);
 423                 if (znet_debug > 5) {
 424                         ushort result, rx_ptr, running;
 425                         outb(CMD0_STAT1, ioaddr);
 426                         result = inw(ioaddr);
 427                         outb(CMD0_STAT2, ioaddr);
 428                         rx_ptr = inw(ioaddr);
 429                         outb(CMD0_STAT3, ioaddr);
 430                         running = inb(ioaddr);
 431                         printk(KERN_DEBUG "%s: interrupt, status %02x, %04x %04x %02x serial %d.\n",
 432                                  dev->name, status, result, rx_ptr, running, boguscnt);
 433                 }
 434                 if ((status & 0x80) == 0)
 435                         break;
 436 
 437                 if ((status & 0x0F) == 4) {     /* Transmit done. */
 438                         struct net_local *lp = (struct net_local *)dev->priv;
 439                         int tx_status;
 440                         outb(CMD0_STAT1, ioaddr);
 441                         tx_status = inw(ioaddr);
 442                         /* It's undocumented, but tx_status seems to match the i82586. */
 443                         if (tx_status & 0x2000) {
 444                                 lp->stats.tx_packets++;
 445                                 lp->stats.collisions += tx_status & 0xf;
 446                         } else {
 447                                 if (tx_status & 0x0600)  lp->stats.tx_carrier_errors++;
 448                                 if (tx_status & 0x0100)  lp->stats.tx_fifo_errors++;
 449                                 if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++;
 450                                 if (tx_status & 0x0020)  lp->stats.tx_aborted_errors++;
 451                                 /* ...and the catch-all. */
 452                                 if (tx_status | 0x0760 != 0x0760)
 453                                   lp->stats.tx_errors++;
 454                         }
 455                         dev->tbusy = 0;
 456                         mark_bh(NET_BH);        /* Inform upper layers. */
 457                 }
 458 
 459                 if ((status & 0x40)
 460                         || (status & 0x0f) == 11) {
 461                         znet_rx(dev);
 462                 }
 463                 /* Clear the interrupts we've handled. */
 464                 outb(CMD0_ACK,ioaddr);
 465         } while (boguscnt--);
 466 
 467         dev->interrupt = 0;
 468         return;
 469 }
 470 
 471 static void znet_rx(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 472 {
 473         struct net_local *lp = (struct net_local *)dev->priv;
 474         int ioaddr = dev->base_addr;
 475         int boguscount = 1;
 476         short next_frame_end_offset = 0;                /* Offset of next frame start. */
 477         short *cur_frame_end;
 478         short cur_frame_end_offset;
 479 
 480         outb(CMD0_STAT2, ioaddr);
 481         cur_frame_end_offset = inw(ioaddr);
 482 
 483         if (cur_frame_end_offset == zn.rx_cur - zn.rx_start) {
 484                 printk(KERN_WARNING "%s: Interrupted, but nothing to receive, offset %03x.\n",
 485                            dev->name, cur_frame_end_offset);
 486                 return;
 487         }
 488 
 489         /* Use same method as the Crynwr driver: construct a forward list in
 490            the same area of the backwards links we now have.  This allows us to
 491            pass packets to the upper layers in the order they were received --
 492            important for fast-path sequential operations. */
 493          while (zn.rx_start + cur_frame_end_offset != zn.rx_cur
 494                         && ++boguscount < 5) {
 495                 unsigned short hi_cnt, lo_cnt, hi_status, lo_status;
 496                 int count, status;
 497 
 498                 if (cur_frame_end_offset < 4) {
 499                         /* Oh no, we have a special case: the frame trailer wraps around
 500                            the end of the ring buffer.  We've saved space at the end of
 501                            the ring buffer for just this problem. */
 502                         memcpy(zn.rx_end, zn.rx_start, 8);
 503                         cur_frame_end_offset += (RX_BUF_SIZE/2);
 504                 }
 505                 cur_frame_end = zn.rx_start + cur_frame_end_offset - 4;
 506 
 507                 lo_status = *cur_frame_end++;
 508                 hi_status = *cur_frame_end++;
 509                 status = ((hi_status & 0xff) << 8) + (lo_status & 0xff);
 510                 lo_cnt = *cur_frame_end++;
 511                 hi_cnt = *cur_frame_end++;
 512                 count = ((hi_cnt & 0xff) << 8) + (lo_cnt & 0xff);
 513 
 514                 if (znet_debug > 5)
 515                   printk(KERN_DEBUG "Constructing trailer at location %03x, %04x %04x %04x %04x"
 516                                  " count %#x status %04x.\n",
 517                                  cur_frame_end_offset<<1, lo_status, hi_status, lo_cnt, hi_cnt,
 518                                  count, status);
 519                 cur_frame_end[-4] = status;
 520                 cur_frame_end[-3] = next_frame_end_offset;
 521                 cur_frame_end[-2] = count;
 522                 next_frame_end_offset = cur_frame_end_offset;
 523                 cur_frame_end_offset -= ((count + 1)>>1) + 3;
 524                 if (cur_frame_end_offset < 0)
 525                   cur_frame_end_offset += RX_BUF_SIZE/2;
 526         };
 527 
 528         /* Now step  forward through the list. */
 529         do {
 530                 ushort *this_rfp_ptr = zn.rx_start + next_frame_end_offset;
 531                 int status = this_rfp_ptr[-4];
 532                 int pkt_len = this_rfp_ptr[-2];
 533           
 534                 if (znet_debug > 5)
 535                   printk(KERN_DEBUG "Looking at trailer ending at %04x status %04x length %03x"
 536                                  " next %04x.\n", next_frame_end_offset<<1, status, pkt_len,
 537                                  this_rfp_ptr[-3]<<1);
 538                 /* Once again we must assume that the i82586 docs apply. */
 539                 if ( ! (status & 0x2000)) {                             /* There was an error. */
 540                         lp->stats.rx_errors++;
 541                         if (status & 0x0800) lp->stats.rx_crc_errors++;
 542                         if (status & 0x0400) lp->stats.rx_frame_errors++;
 543                         if (status & 0x0200) lp->stats.rx_over_errors++; /* Wrong. */
 544                         if (status & 0x0100) lp->stats.rx_fifo_errors++;
 545                         if (status & 0x0080) lp->stats.rx_length_errors++;
 546                 } else if (pkt_len > 1536) {
 547                         lp->stats.rx_length_errors++;
 548                 } else {
 549                         /* Malloc up new buffer. */
 550                         struct sk_buff *skb;
 551 
 552                         skb = alloc_skb(pkt_len, GFP_ATOMIC);
 553                         if (skb == NULL) {
 554                                 if (znet_debug)
 555                                   printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
 556                                 lp->stats.rx_dropped++;
 557                                 break;
 558                         }
 559                         skb->len = pkt_len;
 560                         skb->dev = dev;
 561 
 562                         if (&zn.rx_cur[(pkt_len+1)>>1] > zn.rx_end) {
 563                                 int semi_cnt = (zn.rx_end - zn.rx_cur)<<1;
 564                                 memcpy((unsigned char *) (skb + 1), zn.rx_cur, semi_cnt);
 565                                 memcpy((unsigned char *) (skb + 1) + semi_cnt, zn.rx_start,
 566                                            pkt_len - semi_cnt);
 567                         } else {
 568                                 memcpy((unsigned char *) (skb + 1), zn.rx_cur, pkt_len);
 569                                 if (znet_debug > 6) {
 570                                         unsigned int *packet = (unsigned int *) (skb + 1);
 571                                         printk(KERN_DEBUG "Packet data is %08x %08x %08x %08x.\n", packet[0],
 572                                                    packet[1], packet[2], packet[3]);
 573                                 }
 574                   }
 575 
 576 #ifdef HAVE_NETIF_RX
 577                         netif_rx(skb);
 578 #else
 579                         skb->lock = 0;
 580                         if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
 581                                 kfree_s(skb, sksize);
 582                                 lp->stats.rx_dropped++;
 583                                 break;
 584                         }
 585 #endif
 586                         lp->stats.rx_packets++;
 587                 }
 588                 zn.rx_cur = this_rfp_ptr;
 589                 if (zn.rx_cur >= zn.rx_end)
 590                         zn.rx_cur -= RX_BUF_SIZE/2;
 591                 update_stop_hit(ioaddr, (zn.rx_cur - zn.rx_start)<<1);
 592                 next_frame_end_offset = this_rfp_ptr[-3];
 593                 if (next_frame_end_offset == 0)         /* Read all the frames? */
 594                         break;                  /* Done for now */
 595                 this_rfp_ptr = zn.rx_start + next_frame_end_offset;
 596         } while (--boguscount);
 597 
 598         /* If any worth-while packets have been received, dev_rint()
 599            has done a mark_bh(INET_BH) for us and will work on them
 600            when we get to the bottom-half routine. */
 601         return;
 602 }
 603 
 604 /* The inverse routine to znet_open(). */
 605 static int znet_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 606 {
 607         int ioaddr = dev->base_addr;
 608 
 609         dev->tbusy = 1;
 610         dev->start = 0;
 611 
 612         outb(CMD0_RESET, ioaddr);                       /* CMD0_RESET */
 613 
 614         disable_dma(zn.rx_dma);
 615         disable_dma(zn.tx_dma);
 616 
 617         free_irq(dev->irq);
 618 
 619         if (znet_debug > 1)
 620                 printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
 621         /* Turn off transceiver power. */
 622         outb(0x10, 0xe6);                                       /* Select LAN control register */
 623         outb(inb(0xe7) & ~0x84, 0xe7);          /* Turn on LAN power (bit 2). */
 624 
 625         return 0;
 626 }
 627 
 628 /* Get the current statistics.  This may be called with the card open or
 629    closed. */
 630 static struct enet_statistics *net_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 631 {
 632                 struct net_local *lp = (struct net_local *)dev->priv;
 633 
 634                 return &lp->stats;
 635 }
 636 
 637 #ifdef HAVE_MULTICAST
 638 /* Set or clear the multicast filter for this adaptor.
 639    num_addrs == -1      Promiscuous mode, receive all packets
 640    num_addrs == 0       Normal mode, clear multicast list
 641    num_addrs > 0        Multicast mode, receive normal and MC packets, and do
 642                         best-effort filtering.
 643    As a side effect this routine must also initialize the device parameters.
 644    This is taken advantage of in open().
 645 
 646    N.B. that we change i593_init[] in place.  This (properly) makes the
 647    mode change persistent, but must be changed if this code is moved to
 648    a multiple adaptor environment.
 649  */
 650 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 651 {
 652         short ioaddr = dev->base_addr;
 653 
 654         if (num_addrs < 0) {
 655                 /* Enable promiscuous mode */
 656                 i593_init[7] &= ~3;             i593_init[7] |= 1;
 657                 i593_init[13] &= ~8;    i593_init[13] |= 8;
 658         } else if (num_addrs > 0) {
 659                 /* Enable accept-all-multicast mode */
 660                 i593_init[7] &= ~3;             i593_init[7] |= 0;
 661                 i593_init[13] &= ~8;    i593_init[13] |= 8;
 662         } else {                                        /* Enable normal mode. */
 663                 i593_init[7] &= ~3;             i593_init[7] |= 0;
 664                 i593_init[13] &= ~8;    i593_init[13] |= 0;
 665         }
 666         *zn.tx_cur++ = sizeof(i593_init);
 667         memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
 668         zn.tx_cur += sizeof(i593_init)/2;
 669         outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
 670 #ifdef not_tested
 671         if (num_addrs > 0) {
 672                 int addrs_len = 6*num_addrs;
 673                 *zn.tx_cur++ = addrs_len;
 674                 memcpy(zn.tx_cur, addrs, addrs_len);
 675                 outb(CMD0_MULTICAST_LIST+CMD0_CHNL_1, ioaddr);
 676                 zn.tx_cur += addrs_len>>1;
 677         }
 678 #endif
 679 }
 680 #endif
 681 
 682 void show_dma(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 683 {
 684         short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
 685         unsigned addr = inb(dma_port);
 686         addr |= inb(dma_port) << 8;
 687         printk("Addr: %04x cnt:%3x...", addr<<1, get_dma_residue(zn.tx_dma));
 688 }
 689 
 690 /* Initialize the hardware.  We have to do this when the board is open()ed
 691    or when we come out of suspend mode. */
 692 static void hardware_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 693 {
 694         short ioaddr = dev->base_addr;
 695 
 696         zn.rx_cur = zn.rx_start;
 697         zn.tx_cur = zn.tx_start;
 698 
 699         /* Reset the chip, and start it up. */
 700         outb(CMD0_RESET, ioaddr);
 701 
 702         cli(); {                                                        /* Protect against a DMA flip-flop */
 703                 disable_dma(zn.rx_dma);                 /* reset by an interrupting task. */
 704                 clear_dma_ff(zn.rx_dma);
 705                 set_dma_mode(zn.rx_dma, DMA_RX_MODE);
 706                 set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
 707                 set_dma_count(zn.rx_dma, RX_BUF_SIZE);
 708                 enable_dma(zn.rx_dma);
 709                 /* Now set up the Tx channel. */
 710                 disable_dma(zn.tx_dma);
 711                 clear_dma_ff(zn.tx_dma);
 712                 set_dma_mode(zn.tx_dma, DMA_TX_MODE);
 713                 set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
 714                 set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
 715                 enable_dma(zn.tx_dma);
 716         } sti();
 717 
 718         if (znet_debug > 1)
 719           printk(KERN_DEBUG "%s: Initializing the i82593, tx buf %p... ", dev->name,
 720                          zn.tx_start);
 721         /* Do an empty configure command, just like the Crynwr driver.  This
 722            resets to chip to its default values. */
 723         *zn.tx_cur++ = 0;
 724         *zn.tx_cur++ = 0;
 725         printk("stat:%02x ", inb(ioaddr)); show_dma();
 726         outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
 727         *zn.tx_cur++ = sizeof(i593_init);
 728         memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
 729         zn.tx_cur += sizeof(i593_init)/2;
 730         printk("stat:%02x ", inb(ioaddr)); show_dma();
 731         outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
 732         *zn.tx_cur++ = 6;
 733         memcpy(zn.tx_cur, dev->dev_addr, 6);
 734         zn.tx_cur += 3;
 735         printk("stat:%02x ", inb(ioaddr)); show_dma();
 736         outb(CMD0_IA_SETUP + CMD0_CHNL_1, ioaddr);
 737         printk("stat:%02x ", inb(ioaddr)); show_dma();
 738 
 739         update_stop_hit(ioaddr, 8192);
 740         if (znet_debug > 1)  printk("enabling Rx.\n");
 741         outb(CMD0_Rx_ENABLE+CMD0_CHNL_0, ioaddr);
 742         dev->tbusy = 0;
 743 }
 744 
 745 static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 746 {
 747         outb(CMD0_PORT_1, ioaddr);
 748         if (znet_debug > 5)
 749           printk(KERN_DEBUG "Updating stop hit with value %02x.\n",
 750                          (rx_stop_offset >> 6) | 0x80);
 751         outb((rx_stop_offset >> 6) | 0x80, ioaddr);
 752         outb(CMD1_PORT_0, ioaddr);
 753 }
 754 
 755 /*
 756  * Local variables:
 757  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c znet.c"
 758  *  version-control: t
 759  *  kept-new-versions: 5
 760  *  c-indent-level: 4
 761  *  tab-width: 4
 762  * End:
 763  */

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