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

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