Annotation of Gnu-Mach/linux/src/drivers/net/znet.c, revision 1.1.1.1

1.1       root        1: /* znet.c: An Zenith Z-Note ethernet driver for linux. */
                      2: 
                      3: static const char *version = "znet.c:v1.02 9/23/94 [email protected]\n";
                      4: 
                      5: /*
                      6:        Written by Donald Becker.
                      7: 
                      8:        The author may be reached as [email protected].
                      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)
                    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)
                    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)
                    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)
                    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)
                    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)
                    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)
                    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)
                    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)
                    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)
                    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)
                    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:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.