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

1.1       root        1: /* apricot.c: An Apricot 82596 ethernet driver for linux. */
                      2: /*
                      3:     Apricot
                      4:        Written 1994 by Mark Evans.
                      5:        This driver is for the Apricot 82596 bus-master interface
                      6: 
                      7:         Modularised 12/94 Mark Evans
                      8:     
                      9:     Driver skeleton 
                     10:        Written 1993 by Donald Becker.
                     11:        Copyright 1993 United States Government as represented by the Director,
                     12:        National Security Agency.  This software may only be used and distributed
                     13:        according to the terms of the GNU Public License as modified by SRC,
                     14:        incorporated herein by reference.
                     15: 
                     16:        The author may be reached as [email protected] or
                     17:        C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
                     18:     
                     19: 
                     20: */
                     21: 
                     22: static const char *version = "apricot.c:v0.2 05/12/94\n";
                     23: 
                     24: #include <linux/module.h>
                     25: 
                     26: #include <linux/kernel.h>
                     27: #include <linux/sched.h>
                     28: #include <linux/string.h>
                     29: #include <linux/ptrace.h>
                     30: #include <linux/errno.h>
                     31: #include <linux/ioport.h>
                     32: #include <linux/malloc.h>
                     33: #include <linux/interrupt.h>
                     34: #include <linux/netdevice.h>
                     35: #include <linux/etherdevice.h>
                     36: #include <linux/skbuff.h>
                     37: 
                     38: #include <asm/bitops.h>
                     39: #include <asm/io.h>
                     40: #include <asm/dma.h>
                     41: 
                     42: #ifndef HAVE_PORTRESERVE
                     43: #define check_region(addr, size)       0
                     44: #define request_region(addr, size,name)        do ; while(0)
                     45: #endif
                     46: 
                     47: #ifndef HAVE_ALLOC_SKB
                     48: #define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority)
                     49: #define kfree_skbmem(buff, size) kfree_s(buff,size)
                     50: #endif
                     51: 
                     52: #define APRICOT_DEBUG 1
                     53: 
                     54: #ifdef APRICOT_DEBUG
                     55: int i596_debug = APRICOT_DEBUG;
                     56: #else
                     57: int i596_debug = 1;
                     58: #endif
                     59: 
                     60: #define APRICOT_TOTAL_SIZE 17
                     61: 
                     62: #define I596_NULL -1
                     63: 
                     64: #define CMD_EOL                0x8000  /* The last command of the list, stop. */
                     65: #define CMD_SUSP       0x4000  /* Suspend after doing cmd. */
                     66: #define CMD_INTR       0x2000  /* Interrupt after doing cmd. */
                     67: 
                     68: #define CMD_FLEX       0x0008  /* Enable flexible memory model */
                     69: 
                     70: enum commands {
                     71:        CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
                     72:        CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
                     73: 
                     74: #define STAT_C         0x8000  /* Set to 0 after execution */
                     75: #define STAT_B         0x4000  /* Command being executed */
                     76: #define STAT_OK                0x2000  /* Command executed ok */
                     77: #define STAT_A         0x1000  /* Command aborted */
                     78: 
                     79: #define         CUC_START      0x0100
                     80: #define         CUC_RESUME     0x0200
                     81: #define         CUC_SUSPEND    0x0300
                     82: #define         CUC_ABORT      0x0400
                     83: #define         RX_START       0x0010
                     84: #define         RX_RESUME      0x0020
                     85: #define         RX_SUSPEND     0x0030
                     86: #define         RX_ABORT       0x0040
                     87: 
                     88: struct i596_cmd {
                     89:     unsigned short status;
                     90:     unsigned short command;
                     91:     struct i596_cmd *next;
                     92: };
                     93: 
                     94: #define EOF            0x8000
                     95: #define SIZE_MASK      0x3fff
                     96: 
                     97: struct i596_tbd {
                     98:     unsigned short size;
                     99:     unsigned short pad;
                    100:     struct i596_tbd *next;
                    101:     char *data;
                    102: };
                    103: 
                    104: struct tx_cmd {
                    105:     struct i596_cmd cmd;
                    106:     struct i596_tbd *tbd;
                    107:     unsigned short size;
                    108:     unsigned short pad;
                    109: };
                    110: 
                    111: struct i596_rfd {
                    112:     unsigned short stat;
                    113:     unsigned short cmd;
                    114:     struct i596_rfd *next;
                    115:     long rbd; 
                    116:     unsigned short count;
                    117:     unsigned short size;
                    118:     char data[1532];
                    119: };
                    120: 
                    121: #define RX_RING_SIZE 8
                    122: 
                    123: struct i596_scb {
                    124:     unsigned short status;
                    125:     unsigned short command;
                    126:     struct i596_cmd *cmd;
                    127:     struct i596_rfd *rfd;
                    128:     unsigned long crc_err;
                    129:     unsigned long align_err;
                    130:     unsigned long resource_err;
                    131:     unsigned long over_err;
                    132:     unsigned long rcvdt_err;
                    133:     unsigned long short_err;
                    134:     unsigned short t_on;
                    135:     unsigned short t_off;
                    136: };
                    137: 
                    138: struct i596_iscp {
                    139:     unsigned long stat;
                    140:     struct i596_scb *scb;
                    141: };
                    142: 
                    143: struct i596_scp {
                    144:     unsigned long sysbus;
                    145:     unsigned long pad;
                    146:     struct i596_iscp *iscp;
                    147: };
                    148: 
                    149: struct i596_private {
                    150:     volatile struct i596_scp scp;
                    151:     volatile struct i596_iscp iscp;
                    152:     volatile struct i596_scb scb;
                    153:     volatile struct i596_cmd set_add;
                    154:     char eth_addr[8];
                    155:     volatile struct i596_cmd set_conf;
                    156:     char i596_config[16];
                    157:     volatile struct i596_cmd tdr;
                    158:     unsigned long stat;
                    159:     int last_restart;
                    160:     struct i596_rfd *rx_tail;
                    161:     struct i596_cmd *cmd_tail;
                    162:     struct i596_cmd *cmd_head;
                    163:     int cmd_backlog;
                    164:     unsigned long last_cmd;
                    165:     struct enet_statistics stats;
                    166: };
                    167: 
                    168: char init_setup[] = {
                    169:        0x8E,   /* length, prefetch on */
                    170:        0xC8,   /* fifo to 8, monitor off */
                    171:        0x80,   /* don't save bad frames */
                    172:        0x2E,   /* No source address insertion, 8 byte preamble */
                    173:        0x00,   /* priority and backoff defaults */
                    174:        0x60,   /* interframe spacing */
                    175:        0x00,   /* slot time LSB */
                    176:        0xf2,   /* slot time and retries */
                    177:        0x00,   /* promiscuous mode */
                    178:        0x00,   /* collision detect */
                    179:        0x40,   /* minimum frame length */
                    180:        0xff,   
                    181:        0x00,
                    182:        0x7f    /*  *multi IA */ };
                    183: 
                    184: static int i596_open(struct device *dev);
                    185: static int i596_start_xmit(struct sk_buff *skb, struct device *dev);
                    186: static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
                    187: static int i596_close(struct device *dev);
                    188: static struct enet_statistics *i596_get_stats(struct device *dev);
                    189: static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd);
                    190: static void print_eth(char *);
                    191: static void set_multicast_list(struct device *dev);
                    192: 
                    193: 
                    194: static inline int
                    195: init_rx_bufs(struct device *dev, int num)
                    196: {
                    197:     struct i596_private *lp = (struct i596_private *)dev->priv;
                    198:     int i;
                    199:     struct i596_rfd *rfd;
                    200: 
                    201:     lp->scb.rfd = (struct i596_rfd *)I596_NULL;
                    202: 
                    203:     if (i596_debug > 1) printk ("%s: init_rx_bufs %d.\n", dev->name, num);
                    204: 
                    205:     for (i = 0; i < num; i++)
                    206:     {
                    207:        if (!(rfd = (struct i596_rfd *)kmalloc(sizeof(struct i596_rfd), GFP_KERNEL)))
                    208:             break;
                    209: 
                    210:        rfd->stat = 0x0000;
                    211:        rfd->rbd = I596_NULL;
                    212:        rfd->count = 0;
                    213:        rfd->size = 1532;
                    214:         if (i == 0)
                    215:         {
                    216:            rfd->cmd = CMD_EOL;
                    217:             lp->rx_tail = rfd;
                    218:         }
                    219:         else
                    220:            rfd->cmd = 0x0000;
                    221: 
                    222:         rfd->next = lp->scb.rfd;
                    223:         lp->scb.rfd = rfd;
                    224:     }
                    225: 
                    226:     if (i != 0)
                    227:       lp->rx_tail->next = lp->scb.rfd;
                    228: 
                    229:     return (i);
                    230: }
                    231: 
                    232: static inline void
                    233: remove_rx_bufs(struct device *dev)
                    234: {
                    235:     struct i596_private *lp = (struct i596_private *)dev->priv;
                    236:     struct i596_rfd *rfd = lp->scb.rfd;
                    237: 
                    238:     lp->rx_tail->next = (struct i596_rfd *)I596_NULL;
                    239: 
                    240:     do
                    241:     {
                    242:         lp->scb.rfd = rfd->next;
                    243:         kfree_s(rfd, sizeof(struct i596_rfd));
                    244:         rfd = lp->scb.rfd;
                    245:     }
                    246:     while (rfd != lp->rx_tail);
                    247: }
                    248: 
                    249: static inline void
                    250: init_i596_mem(struct device *dev)
                    251: {
                    252:     struct i596_private *lp = (struct i596_private *)dev->priv;
                    253:     short ioaddr = dev->base_addr;
                    254:     int boguscnt = 100;
                    255: 
                    256:     /* change the scp address */
                    257:     outw(0, ioaddr);
                    258:     outw(0, ioaddr);
                    259:     outb(4, ioaddr+0xf);
                    260:     outw(((((int)&lp->scp) & 0xffff) | 2), ioaddr);
                    261:     outw((((int)&lp->scp)>>16) & 0xffff, ioaddr);
                    262: 
                    263:     lp->last_cmd = jiffies;
                    264: 
                    265:     lp->scp.sysbus = 0x00440000;
                    266:     lp->scp.iscp = &(lp->iscp);
                    267:     lp->iscp.scb = &(lp->scb);
                    268:     lp->iscp.stat = 0x0001;
                    269:     lp->cmd_backlog = 0;
                    270: 
                    271:     lp->cmd_head = lp->scb.cmd = (struct i596_cmd *) I596_NULL;
                    272: 
                    273:     if (i596_debug > 2) printk("%s: starting i82596.\n", dev->name);
                    274: 
                    275:     (void) inb (ioaddr+0x10);
                    276:     outb(4, ioaddr+0xf);
                    277:     outw(0, ioaddr+4);
                    278: 
                    279:     while (lp->iscp.stat)
                    280:        if (--boguscnt == 0)
                    281:        {
                    282:            printk("%s: i82596 initialization timed out with status %4.4x, cmd %4.4x.\n",
                    283:                   dev->name, lp->scb.status, lp->scb.command);
                    284:            break;
                    285:        }
                    286: 
                    287:     lp->scb.command = 0;
                    288: 
                    289:     memcpy (lp->i596_config, init_setup, 14);
                    290:     lp->set_conf.command = CmdConfigure;
                    291:     i596_add_cmd(dev, &lp->set_conf);
                    292: 
                    293:     memcpy (lp->eth_addr, dev->dev_addr, 6);
                    294:     lp->set_add.command = CmdSASetup;
                    295:     i596_add_cmd(dev, &lp->set_add);
                    296: 
                    297:     lp->tdr.command = CmdTDR;
                    298:     i596_add_cmd(dev, &lp->tdr);
                    299: 
                    300:     boguscnt = 200;
                    301:     while (lp->scb.status, lp->scb.command)
                    302:        if (--boguscnt == 0)
                    303:        {
                    304:            printk("%s: receive unit start timed out with status %4.4x, cmd %4.4x.\n",
                    305:                   dev->name, lp->scb.status, lp->scb.command);
                    306:            break;
                    307:        }
                    308: 
                    309:     lp->scb.command = RX_START;
                    310:     outw(0, ioaddr+4);
                    311: 
                    312:     boguscnt = 200;
                    313:     while (lp->scb.status, lp->scb.command)
                    314:         if (--boguscnt == 0)
                    315:        {
                    316:            printk("i82596 init timed out with status %4.4x, cmd %4.4x.\n",
                    317:                lp->scb.status, lp->scb.command);
                    318:            break;
                    319:        }
                    320: 
                    321:     return;
                    322: }
                    323: 
                    324: static inline int
                    325: i596_rx(struct device *dev)
                    326: {
                    327:     struct i596_private *lp = (struct i596_private *)dev->priv;
                    328:     int frames = 0;
                    329: 
                    330:     if (i596_debug > 3) printk ("i596_rx()\n");
                    331: 
                    332:     while ((lp->scb.rfd->stat) & STAT_C)
                    333:     {
                    334:         if (i596_debug >2) print_eth(lp->scb.rfd->data);
                    335: 
                    336:        if ((lp->scb.rfd->stat) & STAT_OK)
                    337:        {
                    338:            /* a good frame */
                    339:            int pkt_len = lp->scb.rfd->count & 0x3fff;
                    340:            struct sk_buff *skb = dev_alloc_skb(pkt_len);
                    341: 
                    342:            frames++;
                    343: 
                    344:            if (skb == NULL)
                    345:            {
                    346:                printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
                    347:                lp->stats.rx_dropped++;
                    348:                break;
                    349:            }
                    350: 
                    351:            skb->dev = dev;             
                    352:            memcpy(skb_put(skb,pkt_len), lp->scb.rfd->data, pkt_len);
                    353: 
                    354:            skb->protocol=eth_type_trans(skb,dev);
                    355:            netif_rx(skb);
                    356:            lp->stats.rx_packets++;
                    357: 
                    358:            if (i596_debug > 4) print_eth(skb->data);
                    359:        }
                    360:        else
                    361:        {
                    362:            lp->stats.rx_errors++;
                    363:            if ((lp->scb.rfd->stat) & 0x0001) lp->stats.collisions++;
                    364:            if ((lp->scb.rfd->stat) & 0x0080) lp->stats.rx_length_errors++;
                    365:            if ((lp->scb.rfd->stat) & 0x0100) lp->stats.rx_over_errors++;
                    366:            if ((lp->scb.rfd->stat) & 0x0200) lp->stats.rx_fifo_errors++;
                    367:            if ((lp->scb.rfd->stat) & 0x0400) lp->stats.rx_frame_errors++;
                    368:            if ((lp->scb.rfd->stat) & 0x0800) lp->stats.rx_crc_errors++;
                    369:            if ((lp->scb.rfd->stat) & 0x1000) lp->stats.rx_length_errors++;
                    370:        }
                    371: 
                    372:        lp->scb.rfd->stat = 0;
                    373:        lp->rx_tail->cmd = 0;
                    374:        lp->rx_tail = lp->scb.rfd;
                    375:        lp->scb.rfd = lp->scb.rfd->next;
                    376:        lp->rx_tail->count = 0;
                    377:        lp->rx_tail->cmd = CMD_EOL;
                    378: 
                    379:     }
                    380: 
                    381:     if (i596_debug > 3) printk ("frames %d\n", frames);
                    382: 
                    383:     return 0;
                    384: }
                    385: 
                    386: static inline void
                    387: i596_cleanup_cmd(struct i596_private *lp)
                    388: {
                    389:     struct i596_cmd *ptr;
                    390:     int boguscnt = 100;
                    391: 
                    392:     if (i596_debug > 4) printk ("i596_cleanup_cmd\n");
                    393: 
                    394:     while (lp->cmd_head != (struct i596_cmd *) I596_NULL)
                    395:     {
                    396:        ptr = lp->cmd_head;
                    397: 
                    398:        lp->cmd_head = lp->cmd_head->next;
                    399:        lp->cmd_backlog--;
                    400: 
                    401:        switch ((ptr->command) & 0x7)
                    402:        {
                    403:            case CmdTx:
                    404:            {
                    405:                struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
                    406:                struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
                    407: 
                    408:                dev_kfree_skb(skb, FREE_WRITE);
                    409: 
                    410:                lp->stats.tx_errors++;
                    411:                lp->stats.tx_aborted_errors++;
                    412: 
                    413:                ptr->next = (struct i596_cmd * ) I596_NULL;
                    414:                kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
                    415:                break;
                    416:            }
                    417:            case CmdMulticastList:
                    418:            {
                    419:                unsigned short count = *((unsigned short *) (ptr + 1));
                    420: 
                    421:                ptr->next = (struct i596_cmd * ) I596_NULL;
                    422:                kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
                    423:                break;
                    424:            }
                    425:            default:
                    426:                ptr->next = (struct i596_cmd * ) I596_NULL;
                    427:        }
                    428:     }
                    429: 
                    430:     while (lp->scb.status, lp->scb.command)
                    431:        if (--boguscnt == 0)
                    432:        {
                    433:            printk("i596_cleanup_cmd timed out with status %4.4x, cmd %4.4x.\n",
                    434:                lp->scb.status, lp->scb.command);
                    435:            break;
                    436:        }
                    437: 
                    438:     lp->scb.cmd = lp->cmd_head;
                    439: }
                    440: 
                    441: static inline void
                    442: i596_reset(struct device *dev, struct i596_private *lp, int ioaddr)
                    443: {
                    444:     int boguscnt = 100;
                    445: 
                    446:     if (i596_debug > 4) printk ("i596_reset\n");
                    447: 
                    448:     while (lp->scb.status, lp->scb.command)
                    449:         if (--boguscnt == 0)
                    450:        {
                    451:            printk("i596_reset timed out with status %4.4x, cmd %4.4x.\n",
                    452:                lp->scb.status, lp->scb.command);
                    453:            break;
                    454:        }
                    455: 
                    456:     dev->start = 0;
                    457:     dev->tbusy = 1;
                    458: 
                    459:     lp->scb.command = CUC_ABORT|RX_ABORT;
                    460:     outw(0, ioaddr+4);
                    461: 
                    462:     /* wait for shutdown */
                    463:     boguscnt = 400;
                    464: 
                    465:     while ((lp->scb.status, lp->scb.command) || lp->scb.command)
                    466:         if (--boguscnt == 0)
                    467:        {
                    468:            printk("i596_reset 2 timed out with status %4.4x, cmd %4.4x.\n",
                    469:                lp->scb.status, lp->scb.command);
                    470:            break;
                    471:        }
                    472: 
                    473:     i596_cleanup_cmd(lp);
                    474:     i596_rx(dev);
                    475: 
                    476:     dev->start = 1;
                    477:     dev->tbusy = 0;
                    478:     dev->interrupt = 0;
                    479:     init_i596_mem(dev);
                    480: }
                    481: 
                    482: static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
                    483: {
                    484:     struct i596_private *lp = (struct i596_private *)dev->priv;
                    485:     int ioaddr = dev->base_addr;
                    486:     unsigned long flags;
                    487:     int boguscnt = 100;
                    488: 
                    489:     if (i596_debug > 4) printk ("i596_add_cmd\n");
                    490: 
                    491:     cmd->status = 0;
                    492:     cmd->command |= (CMD_EOL|CMD_INTR);
                    493:     cmd->next = (struct i596_cmd *) I596_NULL;
                    494: 
                    495:     save_flags(flags);
                    496:     cli();
                    497:     if (lp->cmd_head != (struct i596_cmd *) I596_NULL)
                    498:        lp->cmd_tail->next = cmd;
                    499:     else 
                    500:     {
                    501:        lp->cmd_head = cmd;
                    502:        while (lp->scb.status, lp->scb.command)
                    503:            if (--boguscnt == 0)
                    504:            {
                    505:                printk("i596_add_cmd timed out with status %4.4x, cmd %4.4x.\n",
                    506:                   lp->scb.status, lp->scb.command);
                    507:                break;
                    508:            }
                    509: 
                    510:        lp->scb.cmd = cmd;
                    511:        lp->scb.command = CUC_START;
                    512:         outw (0, ioaddr+4);
                    513:     }
                    514:     lp->cmd_tail = cmd;
                    515:     lp->cmd_backlog++;
                    516: 
                    517:     lp->cmd_head = lp->scb.cmd;
                    518:     restore_flags(flags);
                    519: 
                    520:     if (lp->cmd_backlog > 16) 
                    521:     {
                    522:        int tickssofar = jiffies - lp->last_cmd;
                    523: 
                    524:        if (tickssofar < 25) return;
                    525: 
                    526:        printk("%s: command unit timed out, status resetting.\n", dev->name);
                    527: 
                    528:        i596_reset(dev, lp, ioaddr);
                    529:     }
                    530: }
                    531: 
                    532: static int
                    533: i596_open(struct device *dev)
                    534: {
                    535:     int i;
                    536: 
                    537:     if (i596_debug > 1)
                    538:        printk("%s: i596_open() irq %d.\n", dev->name, dev->irq);
                    539: 
                    540:     if (request_irq(dev->irq, &i596_interrupt, 0, "apricot", NULL))
                    541:        return -EAGAIN;
                    542: 
                    543:     irq2dev_map[dev->irq] = dev;
                    544: 
                    545:     i = init_rx_bufs(dev, RX_RING_SIZE);
                    546: 
                    547:     if ((i = init_rx_bufs(dev, RX_RING_SIZE)) < RX_RING_SIZE)
                    548:         printk("%s: only able to allocate %d receive buffers\n", dev->name, i);
                    549: 
                    550:     if (i < 4)
                    551:     {
                    552:         free_irq(dev->irq, NULL);
                    553:         irq2dev_map[dev->irq] = 0;
                    554:         return -EAGAIN;
                    555:     }
                    556: 
                    557:     dev->tbusy = 0;
                    558:     dev->interrupt = 0;
                    559:     dev->start = 1;
                    560:     MOD_INC_USE_COUNT;
                    561: 
                    562:     /* Initialize the 82596 memory */
                    563:     init_i596_mem(dev);
                    564: 
                    565:     return 0;                  /* Always succeed */
                    566: }
                    567: 
                    568: static int
                    569: i596_start_xmit(struct sk_buff *skb, struct device *dev)
                    570: {
                    571:     struct i596_private *lp = (struct i596_private *)dev->priv;
                    572:     int ioaddr = dev->base_addr;
                    573:     struct tx_cmd *tx_cmd;
                    574: 
                    575:     if (i596_debug > 2) printk ("%s: Apricot start xmit\n", dev->name);
                    576: 
                    577:     /* Transmitter timeout, serious problems. */
                    578:     if (dev->tbusy) {
                    579:        int tickssofar = jiffies - dev->trans_start;
                    580:        if (tickssofar < 5)
                    581:            return 1;
                    582:        printk("%s: transmit timed out, status resetting.\n",
                    583:               dev->name);
                    584:        lp->stats.tx_errors++;
                    585:        /* Try to restart the adaptor */
                    586:        if (lp->last_restart == lp->stats.tx_packets) {
                    587:            if (i596_debug > 1) printk ("Resetting board.\n");
                    588: 
                    589:            /* Shutdown and restart */
                    590:             i596_reset(dev,lp, ioaddr);
                    591:        } else {
                    592:            /* Issue a channel attention signal */
                    593:            if (i596_debug > 1) printk ("Kicking board.\n");
                    594: 
                    595:            lp->scb.command = CUC_START|RX_START;
                    596:            outw(0, ioaddr+4);
                    597: 
                    598:            lp->last_restart = lp->stats.tx_packets;
                    599:        }
                    600:        dev->tbusy = 0;
                    601:        dev->trans_start = jiffies;
                    602:     }
                    603: 
                    604:     /* If some higher level thinks we've misses a tx-done interrupt
                    605:        we are passed NULL. n.b. dev_tint handles the cli()/sti()
                    606:        itself. */
                    607:     if (skb == NULL) {
                    608:        dev_tint(dev);
                    609:        return 0;
                    610:     }
                    611: 
                    612:     /* shouldn't happen */
                    613:     if (skb->len <= 0) return 0;
                    614: 
                    615:     if (i596_debug > 3) printk("%s: i596_start_xmit() called\n", dev->name);
                    616: 
                    617:     /* Block a timer-based transmit from overlapping.  This could better be
                    618:        done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
                    619:     if (set_bit(0, (void*)&dev->tbusy) != 0)
                    620:        printk("%s: Transmitter access conflict.\n", dev->name);
                    621:     else
                    622:     {
                    623:        short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
                    624:        dev->trans_start = jiffies;
                    625: 
                    626:        tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
                    627:        if (tx_cmd == NULL)
                    628:        {
                    629:            printk ("%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
                    630:            lp->stats.tx_dropped++;
                    631: 
                    632:            dev_kfree_skb(skb, FREE_WRITE);
                    633:        }
                    634:        else
                    635:        {
                    636:            tx_cmd->tbd = (struct i596_tbd *) (tx_cmd + 1);
                    637:            tx_cmd->tbd->next = (struct i596_tbd *) I596_NULL;
                    638: 
                    639:            tx_cmd->cmd.command = CMD_FLEX|CmdTx;
                    640: 
                    641:            tx_cmd->pad = 0;
                    642:            tx_cmd->size = 0;
                    643:            tx_cmd->tbd->pad = 0;
                    644:            tx_cmd->tbd->size = EOF | length;
                    645: 
                    646:            tx_cmd->tbd->data = skb->data;
                    647: 
                    648:            if (i596_debug > 3) print_eth(skb->data);
                    649: 
                    650:            i596_add_cmd(dev, (struct i596_cmd *)tx_cmd);
                    651: 
                    652:            lp->stats.tx_packets++;
                    653:        }
                    654:     }
                    655: 
                    656:     dev->tbusy = 0;
                    657: 
                    658:     return 0;
                    659: }
                    660: 
                    661: 
                    662: static void print_eth(char *add)
                    663: {
                    664:     int i;
                    665: 
                    666:     printk ("Dest  ");
                    667:     for (i = 0; i < 6; i++)
                    668:        printk(" %2.2X", (unsigned char)add[i]);
                    669:     printk ("\n");
                    670: 
                    671:     printk ("Source");
                    672:     for (i = 0; i < 6; i++)
                    673:        printk(" %2.2X", (unsigned char)add[i+6]);
                    674:     printk ("\n");
                    675:     printk ("type %2.2X%2.2X\n", (unsigned char)add[12], (unsigned char)add[13]);
                    676: }
                    677: 
                    678: int apricot_probe(struct device *dev)
                    679: {
                    680:     int i;
                    681:     struct i596_private *lp;
                    682:     int checksum = 0;
                    683:     int ioaddr = 0x300;
                    684:     char eth_addr[6];
                    685:     
                    686:     /* this is easy the ethernet interface can only be at 0x300 */
                    687:     /* first check nothing is already registered here */
                    688: 
                    689:     if (check_region(ioaddr, APRICOT_TOTAL_SIZE))
                    690:        return ENODEV;
                    691: 
                    692:     for (i = 0; i < 8; i++)
                    693:     {
                    694:        eth_addr[i] = inb(ioaddr+8+i);
                    695:        checksum += eth_addr[i];
                    696:      }
                    697: 
                    698:     /* checksum is a multiple of 0x100, got this wrong first time
                    699:        some machines have 0x100, some 0x200. The DOS driver doesn't
                    700:        even bother with the checksum */
                    701: 
                    702:     if (checksum % 0x100) return ENODEV;
                    703: 
                    704:     /* Some other boards trip the checksum.. but then appear as ether
                    705:        address 0. Trap these - AC */
                    706:        
                    707:     if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
                    708:        return ENODEV;
                    709: 
                    710:     request_region(ioaddr, APRICOT_TOTAL_SIZE, "apricot");
                    711: 
                    712:     dev->base_addr = ioaddr;
                    713:     ether_setup(dev);
                    714:     printk("%s: Apricot 82596 at %#3x,", dev->name, ioaddr);
                    715: 
                    716:     for (i = 0; i < 6; i++)
                    717:        printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]);
                    718: 
                    719:     dev->base_addr = ioaddr;
                    720:     dev->irq = 10;
                    721:     printk(" IRQ %d.\n", dev->irq);
                    722: 
                    723:     if (i596_debug > 0) printk(version);
                    724: 
                    725:     /* The APRICOT-specific entries in the device structure. */
                    726:     dev->open = &i596_open;
                    727:     dev->stop = &i596_close;
                    728:     dev->hard_start_xmit = &i596_start_xmit;
                    729:     dev->get_stats = &i596_get_stats;
                    730:     dev->set_multicast_list = &set_multicast_list;
                    731: 
                    732:     dev->mem_start = (int)kmalloc(sizeof(struct i596_private)+ 0x0f, GFP_KERNEL);
                    733:     /* align for scp */
                    734:     dev->priv = (void *)((dev->mem_start + 0xf) & 0xfffffff0);
                    735: 
                    736:     lp = (struct i596_private *)dev->priv;
                    737:     memset((void *)lp, 0, sizeof(struct i596_private));
                    738:     lp->scb.command = 0;
                    739:     lp->scb.cmd = (struct i596_cmd *) I596_NULL;
                    740:     lp->scb.rfd = (struct i596_rfd *)I596_NULL;
                    741: 
                    742:     return 0;
                    743: }
                    744: 
                    745: static void
                    746: i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                    747: {
                    748:     struct device *dev = (struct device *)(irq2dev_map[irq]);
                    749:     struct i596_private *lp;
                    750:     short ioaddr;
                    751:     int boguscnt = 200;
                    752:     unsigned short status, ack_cmd = 0;
                    753: 
                    754:     if (dev == NULL) {
                    755:        printk ("i596_interrupt(): irq %d for unknown device.\n", irq);
                    756:        return;
                    757:     }
                    758: 
                    759:     if (i596_debug > 3) printk ("%s: i596_interrupt(): irq %d\n",dev->name, irq);
                    760: 
                    761:     if (dev->interrupt)
                    762:        printk("%s: Re-entering the interrupt handler.\n", dev->name);
                    763: 
                    764:     dev->interrupt = 1;
                    765: 
                    766:     ioaddr = dev->base_addr;
                    767: 
                    768:     lp = (struct i596_private *)dev->priv;
                    769: 
                    770:     while (lp->scb.status, lp->scb.command)
                    771:        if (--boguscnt == 0)
                    772:            {
                    773:                printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
                    774:                break;
                    775:            }
                    776:     status = lp->scb.status;
                    777: 
                    778:     if (i596_debug > 4)
                    779:        printk("%s: i596 interrupt, status %4.4x.\n", dev->name, status);
                    780: 
                    781:     ack_cmd = status & 0xf000;
                    782: 
                    783:     if ((status & 0x8000) || (status & 0x2000))
                    784:     {
                    785:        struct i596_cmd *ptr;
                    786: 
                    787:        if ((i596_debug > 4) && (status & 0x8000))
                    788:            printk("%s: i596 interrupt completed command.\n", dev->name);
                    789:        if ((i596_debug > 4) && (status & 0x2000))
                    790:            printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700);
                    791: 
                    792:        while ((lp->cmd_head != (struct i596_cmd *) I596_NULL) && (lp->cmd_head->status & STAT_C))
                    793:        {
                    794:            ptr = lp->cmd_head;
                    795: 
                    796:            lp->cmd_head = lp->cmd_head->next;
                    797:            lp->cmd_backlog--;
                    798: 
                    799:            switch ((ptr->command) & 0x7)
                    800:            {
                    801:                case CmdTx:
                    802:                {
                    803:                    struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
                    804:                    struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
                    805: 
                    806:                    dev_kfree_skb(skb, FREE_WRITE);
                    807: 
                    808:                    if ((ptr->status) & STAT_OK)
                    809:                    {
                    810:                        if (i596_debug >2) print_eth(skb->data);
                    811:                    }
                    812:                    else
                    813:                    {
                    814:                        lp->stats.tx_errors++;
                    815:                        if ((ptr->status) & 0x0020) lp->stats.collisions++;
                    816:                        if (!((ptr->status) & 0x0040)) lp->stats.tx_heartbeat_errors++;
                    817:                        if ((ptr->status) & 0x0400) lp->stats.tx_carrier_errors++;
                    818:                        if ((ptr->status) & 0x0800) lp->stats.collisions++;
                    819:                        if ((ptr->status) & 0x1000) lp->stats.tx_aborted_errors++;
                    820:                    }
                    821: 
                    822: 
                    823:                    ptr->next = (struct i596_cmd * ) I596_NULL;
                    824:                    kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
                    825:                    break;
                    826:                }
                    827:                case CmdMulticastList:
                    828:                {
                    829:                    unsigned short count = *((unsigned short *) (ptr + 1));
                    830: 
                    831:                    ptr->next = (struct i596_cmd * ) I596_NULL;
                    832:                    kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
                    833:                    break;
                    834:                }
                    835:                case CmdTDR:
                    836:                {
                    837:                    unsigned long status = *((unsigned long *) (ptr + 1));
                    838: 
                    839:                    if (status & 0x8000)
                    840:                    {
                    841:                        if (i596_debug > 3)
                    842:                            printk("%s: link ok.\n", dev->name);
                    843:                    }
                    844:                    else
                    845:                    {
                    846:                        if (status & 0x4000)
                    847:                            printk("%s: Transceiver problem.\n", dev->name);
                    848:                        if (status & 0x2000)
                    849:                            printk("%s: Termination problem.\n", dev->name);
                    850:                        if (status & 0x1000)
                    851:                            printk("%s: Short circuit.\n", dev->name);
                    852: 
                    853:                        printk("%s: Time %ld.\n", dev->name, status & 0x07ff);
                    854:                    }
                    855:                }
                    856:                default:
                    857:                    ptr->next = (struct i596_cmd * ) I596_NULL;
                    858: 
                    859:                lp->last_cmd = jiffies;
                    860:            }
                    861:        }
                    862: 
                    863:        ptr = lp->cmd_head;
                    864:        while ((ptr != (struct i596_cmd *) I596_NULL) && (ptr != lp->cmd_tail))
                    865:        {
                    866:            ptr->command &= 0x1fff;
                    867:            ptr = ptr->next;
                    868:        }
                    869: 
                    870:        if ((lp->cmd_head != (struct i596_cmd *) I596_NULL) && (dev->start)) ack_cmd |= CUC_START;
                    871:        lp->scb.cmd = lp->cmd_head;
                    872:     }
                    873: 
                    874:     if ((status & 0x1000) || (status & 0x4000))
                    875:     {
                    876:        if ((i596_debug > 4) && (status & 0x4000))
                    877:            printk("%s: i596 interrupt received a frame.\n", dev->name);
                    878:        if ((i596_debug > 4) && (status & 0x1000))
                    879:            printk("%s: i596 interrupt receive unit inactive %x.\n", dev->name, status & 0x0070);
                    880: 
                    881:        i596_rx(dev);
                    882: 
                    883:        if (dev->start) ack_cmd |= RX_START;
                    884:     }
                    885: 
                    886:     /* acknowledge the interrupt */
                    887: 
                    888: /*
                    889:     if ((lp->scb.cmd != (struct i596_cmd *) I596_NULL) && (dev->start)) ack_cmd | = CUC_START;
                    890: */
                    891:     boguscnt = 100;
                    892:     while (lp->scb.status, lp->scb.command)
                    893:        if (--boguscnt == 0)
                    894:            {
                    895:                printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
                    896:                break;
                    897:            }
                    898:     lp->scb.command = ack_cmd;
                    899: 
                    900:     (void) inb (ioaddr+0x10);
                    901:     outb (4, ioaddr+0xf);
                    902:     outw (0, ioaddr+4);
                    903: 
                    904:     if (i596_debug > 4)
                    905:        printk("%s: exiting interrupt.\n", dev->name);
                    906: 
                    907:     dev->interrupt = 0;
                    908:     return;
                    909: }
                    910: 
                    911: static int
                    912: i596_close(struct device *dev)
                    913: {
                    914:     int ioaddr = dev->base_addr;
                    915:     struct i596_private *lp = (struct i596_private *)dev->priv;
                    916:     int boguscnt = 200;
                    917: 
                    918:     dev->start = 0;
                    919:     dev->tbusy = 1;
                    920: 
                    921:     if (i596_debug > 1)
                    922:        printk("%s: Shutting down ethercard, status was %4.4x.\n",
                    923:               dev->name, lp->scb.status);
                    924: 
                    925:     lp->scb.command = CUC_ABORT|RX_ABORT;
                    926:     outw(0, ioaddr+4);
                    927: 
                    928:     i596_cleanup_cmd(lp);
                    929: 
                    930:     while (lp->scb.status, lp->scb.command)
                    931:        if (--boguscnt == 0)
                    932:        {
                    933:            printk("%s: close timed out with status %4.4x, cmd %4.4x.\n",
                    934:                   dev->name, lp->scb.status, lp->scb.command);
                    935:            break;
                    936:        }
                    937:     free_irq(dev->irq, NULL);
                    938:     irq2dev_map[dev->irq] = 0;
                    939:     remove_rx_bufs(dev);
                    940:     MOD_DEC_USE_COUNT;
                    941: 
                    942:     return 0;
                    943: }
                    944: 
                    945: static struct enet_statistics *
                    946: i596_get_stats(struct device *dev)
                    947: {
                    948:     struct i596_private *lp = (struct i596_private *)dev->priv;
                    949: 
                    950:     return &lp->stats;
                    951: }
                    952: 
                    953: /*
                    954:  *     Set or clear the multicast filter for this adaptor.
                    955:  */
                    956:  
                    957: static void set_multicast_list(struct device *dev)
                    958: {
                    959:        struct i596_private *lp = (struct i596_private *)dev->priv;
                    960:        struct i596_cmd *cmd;
                    961: 
                    962:        if (i596_debug > 1)
                    963:                printk ("%s: set multicast list %d\n", dev->name, dev->mc_count);
                    964: 
                    965:        if (dev->mc_count > 0) 
                    966:        {
                    967:                struct dev_mc_list *dmi;
                    968:                char *cp;
                    969:                cmd = (struct i596_cmd *) kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
                    970:                if (cmd == NULL)
                    971:                {
                    972:                        printk ("%s: set_multicast Memory squeeze.\n", dev->name);
                    973:                        return;
                    974:                }
                    975:                cmd->command = CmdMulticastList;
                    976:                *((unsigned short *) (cmd + 1)) = dev->mc_count * 6;
                    977:                cp=((char *)(cmd + 1))+2;
                    978:                for(dmi=dev->mc_list;dmi!=NULL;dmi=dmi->next)
                    979:                {
                    980:                        memcpy(cp, dmi,6);
                    981:                        cp+=6;
                    982:                }
                    983:                print_eth (((char *)(cmd + 1)) + 2);
                    984:                i596_add_cmd(dev, cmd);
                    985:        }
                    986:        else
                    987:        {
                    988:                if (lp->set_conf.next != (struct i596_cmd * ) I596_NULL) 
                    989:                        return;
                    990:                if (dev->mc_count == 0 && !(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
                    991:                {
                    992:                        if(dev->flags&IFF_ALLMULTI)
                    993:                                dev->flags|=IFF_PROMISC;
                    994:                        lp->i596_config[8] &= ~0x01;
                    995:                }
                    996:                else
                    997:                        lp->i596_config[8] |= 0x01;
                    998: 
                    999:                i596_add_cmd(dev, &lp->set_conf);
                   1000:        }
                   1001: }
                   1002: 
                   1003: #ifdef HAVE_DEVLIST
                   1004: static unsigned int apricot_portlist[] = {0x300, 0};
                   1005: struct netdev_entry apricot_drv = 
                   1006: {"apricot", apricot_probe, APRICOT_TOTAL_SIZE, apricot_portlist};
                   1007: #endif
                   1008: 
                   1009: #ifdef MODULE
                   1010: static char devicename[9] = { 0, };
                   1011: static struct device dev_apricot = {
                   1012:   devicename, /* device name inserted by /linux/drivers/net/net_init.c */
                   1013:   0, 0, 0, 0,
                   1014:   0x300, 10,
                   1015:   0, 0, 0, NULL, apricot_probe };
                   1016: 
                   1017: static int io = 0x300;
                   1018: static int irq = 10;
                   1019: 
                   1020: int
                   1021: init_module(void)
                   1022: {
                   1023:   dev_apricot.base_addr = io;
                   1024:   dev_apricot.irq       = irq;
                   1025:   if (register_netdev(&dev_apricot) != 0)
                   1026:     return -EIO;
                   1027:   return 0;
                   1028: }
                   1029: 
                   1030: void
                   1031: cleanup_module(void)
                   1032: {
                   1033:     unregister_netdev(&dev_apricot);
                   1034:     kfree_s((void *)dev_apricot.mem_start, sizeof(struct i596_private) + 0xf);
                   1035:     dev_apricot.priv = NULL;
                   1036: 
                   1037:     /* If we don't do this, we can't re-insmod it later. */
                   1038:     release_region(dev_apricot.base_addr, APRICOT_TOTAL_SIZE);
                   1039: }
                   1040: #endif /* MODULE */
                   1041: 
                   1042: /*
                   1043:  * Local variables:
                   1044:  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c apricot.c"
                   1045:  * End:
                   1046:  */

unix.superglobalmegacorp.com

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