Annotation of Gnu-Mach/linux/src/drivers/net/seeq8005.c, revision 1.1.1.2

1.1       root        1: /* seeq8005.c: A network driver for linux. */
                      2: /*
                      3:        Based on skeleton.c,
                      4:        Written 1993-94 by Donald Becker.
                      5:        See the skeleton.c file for further copyright information.
                      6: 
                      7:        This software may be used and distributed according to the terms
                      8:        of the GNU Public License, incorporated herein by reference.
                      9: 
                     10:        The author may be reached as [email protected]
                     11: 
                     12:        This file is a network device driver for the SEEQ 8005 chipset and
                     13:        the Linux operating system.
                     14: 
                     15: */
                     16: 
                     17: static const char *version =
                     18:        "seeq8005.c:v1.00 8/07/95 Hamish Coleman ([email protected])\n";
                     19: 
                     20: /*
                     21:   Sources:
                     22:        SEEQ 8005 databook
                     23:        
                     24:   Version history:
                     25:        1.00    Public release. cosmetic changes (no warnings now)
                     26:        0.68    Turning per- packet,interrupt debug messages off - testing for release.
                     27:        0.67    timing problems/bad buffer reads seem to be fixed now
                     28:        0.63    *!@$ protocol=eth_type_trans -- now packets flow
                     29:        0.56    Send working
                     30:        0.48    Receive working
                     31: */
                     32: 
                     33: #include <linux/kernel.h>
                     34: #include <linux/sched.h>
                     35: #include <linux/types.h>
                     36: #include <linux/fcntl.h>
                     37: #include <linux/interrupt.h>
                     38: #include <linux/ptrace.h>
                     39: #include <linux/ioport.h>
                     40: #include <linux/in.h>
                     41: #include <linux/malloc.h>
                     42: #include <linux/string.h>
                     43: #include <asm/system.h>
                     44: #include <asm/bitops.h>
                     45: #include <asm/io.h>
                     46: #include <asm/dma.h>
                     47: #include <linux/errno.h>
                     48: 
                     49: #include <linux/netdevice.h>
                     50: #include <linux/etherdevice.h>
                     51: #include <linux/skbuff.h>
                     52: #include "seeq8005.h"
                     53: 
                     54: /* First, a few definitions that the brave might change. */
                     55: /* A zero-terminated list of I/O addresses to be probed. */
                     56: static unsigned int seeq8005_portlist[] =
                     57:    { 0x300, 0x320, 0x340, 0x360, 0};
                     58: 
                     59: /* use 0 for production, 1 for verification, >2 for debug */
                     60: #ifndef NET_DEBUG
                     61: #define NET_DEBUG 1
                     62: #endif
                     63: static unsigned int net_debug = NET_DEBUG;
                     64: 
                     65: /* Information that need to be kept for each board. */
                     66: struct net_local {
                     67:        struct enet_statistics stats;
                     68:        unsigned short receive_ptr;             /* What address in packet memory do we expect a recv_pkt_header? */
                     69:        long open_time;                         /* Useless example local info. */
                     70: };
                     71: 
                     72: /* The station (ethernet) address prefix, used for IDing the board. */
                     73: #define SA_ADDR0 0x00
                     74: #define SA_ADDR1 0x80
                     75: #define SA_ADDR2 0x4b
                     76: 
                     77: /* Index to functions, as function prototypes. */
                     78: 
                     79: extern int seeq8005_probe(struct device *dev);
                     80: 
                     81: static int seeq8005_probe1(struct device *dev, int ioaddr);
                     82: static int seeq8005_open(struct device *dev);
                     83: static int seeq8005_send_packet(struct sk_buff *skb, struct device *dev);
                     84: static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs);
                     85: static void seeq8005_rx(struct device *dev);
                     86: static int seeq8005_close(struct device *dev);
                     87: static struct enet_statistics *seeq8005_get_stats(struct device *dev);
                     88: static void set_multicast_list(struct device *dev);
                     89: 
                     90: /* Example routines you must write ;->. */
                     91: #define tx_done(dev)   (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON)
                     92: extern void hardware_send_packet(struct device *dev, char *buf, int length);
                     93: extern void seeq8005_init(struct device *dev, int startp);
                     94: inline void wait_for_buffer(struct device *dev);
                     95: 
                     96: 
                     97: /* Check for a network adaptor of this type, and return '0' iff one exists.
                     98:    If dev->base_addr == 0, probe all likely locations.
                     99:    If dev->base_addr == 1, always return failure.
                    100:    If dev->base_addr == 2, allocate space for the device and return success
                    101:    (detachable devices only).
                    102:    */
                    103: #ifdef HAVE_DEVLIST
                    104: /* Support for a alternate probe manager, which will eliminate the
                    105:    boilerplate below. */
                    106: struct netdev_entry seeq8005_drv =
                    107: {"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist};
                    108: #else
                    109: int
                    110: seeq8005_probe(struct device *dev)
                    111: {
                    112:        int i;
                    113:        int base_addr = dev ? dev->base_addr : 0;
                    114: 
                    115:        if (base_addr > 0x1ff)          /* Check a single specified location. */
                    116:                return seeq8005_probe1(dev, base_addr);
                    117:        else if (base_addr != 0)        /* Don't probe at all. */
                    118:                return ENXIO;
                    119: 
                    120:        for (i = 0; seeq8005_portlist[i]; i++) {
                    121:                int ioaddr = seeq8005_portlist[i];
                    122:                if (check_region(ioaddr, SEEQ8005_IO_EXTENT))
                    123:                        continue;
                    124:                if (seeq8005_probe1(dev, ioaddr) == 0)
                    125:                        return 0;
                    126:        }
                    127: 
                    128:        return ENODEV;
                    129: }
                    130: #endif
                    131: 
                    132: /* This is the real probe routine.  Linux has a history of friendly device
                    133:    probes on the ISA bus.  A good device probes avoids doing writes, and
                    134:    verifies that the correct device exists and functions.  */
                    135: 
                    136: static int seeq8005_probe1(struct device *dev, int ioaddr)
                    137: {
                    138:        static unsigned version_printed = 0;
                    139:        int i,j;
                    140:        unsigned char SA_prom[32];
                    141:        int old_cfg1;
                    142:        int old_cfg2;
                    143:        int old_stat;
                    144:        int old_dmaar;
                    145:        int old_rear;
                    146: 
                    147:        if (net_debug>1)
                    148:                printk("seeq8005: probing at 0x%x\n",ioaddr);
                    149: 
                    150:        old_stat = inw(SEEQ_STATUS);                                    /* read status register */
                    151:        if (old_stat == 0xffff)
                    152:                return ENODEV;                                          /* assume that 0xffff == no device */
                    153:        if ( (old_stat & 0x1800) != 0x1800 ) {                          /* assume that unused bits are 1, as my manual says */
                    154:                if (net_debug>1) {
                    155:                        printk("seeq8005: reserved stat bits != 0x1800\n");
                    156:                        printk("          == 0x%04x\n",old_stat);
                    157:                }
                    158:                return ENODEV;
                    159:        }
                    160: 
                    161:        old_rear = inw(SEEQ_REA);
                    162:        if (old_rear == 0xffff) {
                    163:                outw(0,SEEQ_REA);
                    164:                if (inw(SEEQ_REA) == 0xffff) {                          /* assume that 0xffff == no device */
                    165:                        return ENODEV;
                    166:                }
                    167:        } else if ((old_rear & 0xff00) != 0xff00) {                     /* assume that unused bits are 1 */
                    168:                if (net_debug>1) {
                    169:                        printk("seeq8005: unused rear bits != 0xff00\n");
                    170:                        printk("          == 0x%04x\n",old_rear);
                    171:                }
                    172:                return ENODEV;
                    173:        }
                    174:        
                    175:        old_cfg2 = inw(SEEQ_CFG2);                                      /* read CFG2 register */
                    176:        old_cfg1 = inw(SEEQ_CFG1);
                    177:        old_dmaar = inw(SEEQ_DMAAR);
                    178:        
                    179:        if (net_debug>4) {
                    180:                printk("seeq8005: stat = 0x%04x\n",old_stat);
                    181:                printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1);
                    182:                printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2);
                    183:                printk("seeq8005: raer = 0x%04x\n",old_rear);
                    184:                printk("seeq8005: dmaar= 0x%04x\n",old_dmaar);
                    185:        }
                    186:        
                    187:        outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);      /* setup for reading PROM */
                    188:        outw( 0, SEEQ_DMAAR);                                           /* set starting PROM address */
                    189:        outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1);                         /* set buffer to look at PROM */
                    190:        
                    191:        
                    192:        j=0;
                    193:        for(i=0; i <32; i++) {
                    194:                j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff;
                    195:        }
                    196: 
                    197: #if 0
                    198:        /* untested because I only have the one card */
                    199:        if ( (j&0xff) != 0 ) {                                          /* checksum appears to be 8bit = 0 */
                    200:                if (net_debug>1) {                                      /* check this before deciding that we have a card */
                    201:                        printk("seeq8005: prom sum error\n");
                    202:                }
                    203:                outw( old_stat, SEEQ_STATUS);
                    204:                outw( old_dmaar, SEEQ_DMAAR);
                    205:                outw( old_cfg1, SEEQ_CFG1);
                    206:                return ENODEV;
                    207:        }
                    208: #endif
                    209: 
                    210:        outw( SEEQCFG2_RESET, SEEQ_CFG2);                               /* reset the card */
                    211:        SLOW_DOWN_IO;                                                   /* have to wait 4us after a reset - should be fixed */
                    212:        SLOW_DOWN_IO;
                    213:        SLOW_DOWN_IO;
                    214:        SLOW_DOWN_IO;
                    215:        outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
                    216:        
                    217:        if (net_debug) {
                    218:                printk("seeq8005: prom sum = 0x%08x\n",j);
                    219:                for(j=0; j<32; j+=16) {
                    220:                        printk("seeq8005: prom %02x: ",j);
                    221:                        for(i=0;i<16;i++) {
                    222:                                printk("%02x ",SA_prom[j|i]);
                    223:                        }
                    224:                        printk(" ");
                    225:                        for(i=0;i<16;i++) {
                    226:                                if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) {
                    227:                                        printk("%c", SA_prom[j|i]);
                    228:                                } else {
                    229:                                        printk(" ");
                    230:                                }
                    231:                        }
                    232:                        printk("\n");
                    233:                }
                    234:        }
                    235: 
                    236: #if 0  
                    237:        /* 
                    238:         * testing the packet buffer memory doesn't work yet
                    239:         * but all other buffer accesses do 
                    240:         *                      - fixing is not a priority
                    241:         */
                    242:        if (net_debug>1) {                                      /* test packet buffer memory */
                    243:                printk("seeq8005: testing packet buffer ... ");
                    244:                outw( SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
                    245:                outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
                    246:                outw( 0 , SEEQ_DMAAR);
                    247:                for(i=0;i<32768;i++) {
                    248:                        outw(0x5a5a, SEEQ_BUFFER);
                    249:                }
                    250:                j=jiffies+HZ;
                    251:                while ( ((inw(SEEQ_STATUS) & SEEQSTAT_FIFO_EMPTY) != SEEQSTAT_FIFO_EMPTY) && jiffies < j )
                    252:                        mb();
                    253:                outw( 0 , SEEQ_DMAAR);
                    254:                while ( ((inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && jiffies < j+HZ)
                    255:                        mb();
                    256:                if ( (inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
                    257:                        outw( SEEQCMD_WINDOW_INT_ACK | (inw(SEEQ_STATUS)& SEEQCMD_INT_MASK), SEEQ_CMD);
                    258:                outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
                    259:                j=0;
                    260:                for(i=0;i<32768;i++) {
                    261:                        if (inw(SEEQ_BUFFER) != 0x5a5a)
                    262:                                j++;
                    263:                }
                    264:                if (j) {
                    265:                        printk("%i\n",j);
                    266:                } else {
                    267:                        printk("ok.\n");
                    268:                }
                    269:        }
                    270: #endif
                    271: 
                    272:        /* Allocate a new 'dev' if needed. */
                    273:        if (dev == NULL)
                    274:                dev = init_etherdev(0, sizeof(struct net_local));
                    275: 
                    276:        if (net_debug  &&  version_printed++ == 0)
1.1.1.2 ! root      277:                printk("%s", version);
1.1       root      278: 
                    279:        printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
                    280: 
                    281:        /* Fill in the 'dev' fields. */
                    282:        dev->base_addr = ioaddr;
                    283: 
                    284:        /* Retrieve and print the ethernet address. */
                    285:        for (i = 0; i < 6; i++)
                    286:                printk(" %2.2x", dev->dev_addr[i] = SA_prom[i+6]);
                    287: 
                    288:        if (dev->irq == 0xff)
                    289:                ;                       /* Do nothing: a user-level program will set it. */
                    290:        else if (dev->irq < 2) {        /* "Auto-IRQ" */
                    291:                autoirq_setup(0);
                    292:                
                    293:                outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
                    294: 
                    295:                dev->irq = autoirq_report(0);
                    296:                
                    297:                if (net_debug >= 2)
                    298:                        printk(" autoirq is %d\n", dev->irq);
                    299:        } else if (dev->irq == 2)
                    300:          /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
                    301:           * or don't know which one to set. 
                    302:           */
                    303:          dev->irq = 9;
                    304: 
                    305: #if 0
                    306:        {
                    307:                 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", NULL);
                    308:                 if (irqval) {
                    309:                         printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
                    310:                                         dev->irq, irqval);
                    311:                         return EAGAIN;
                    312:                 }
                    313:        }
                    314: #endif
                    315: 
                    316:        /* Grab the region so we can find another board if autoIRQ fails. */
                    317:        request_region(ioaddr, SEEQ8005_IO_EXTENT,"seeq8005");
                    318: 
                    319:        /* Initialize the device structure. */
                    320:        dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
                    321:        if (dev->priv == NULL)
                    322:                return -ENOMEM;
                    323:        memset(dev->priv, 0, sizeof(struct net_local));
                    324: 
                    325:        dev->open               = seeq8005_open;
                    326:        dev->stop               = seeq8005_close;
                    327:        dev->hard_start_xmit = seeq8005_send_packet;
                    328:        dev->get_stats  = seeq8005_get_stats;
                    329:        dev->set_multicast_list = &set_multicast_list;
                    330: 
                    331:        /* Fill in the fields of the device structure with ethernet values. */
                    332:        ether_setup(dev);
                    333:        
                    334:        dev->flags &= ~IFF_MULTICAST;
                    335: 
                    336:        return 0;
                    337: }
                    338: 
                    339: 
                    340: /* Open/initialize the board.  This is called (in the current kernel)
                    341:    sometime after booting when the 'ifconfig' program is run.
                    342: 
                    343:    This routine should set everything up anew at each open, even
                    344:    registers that "should" only need to be set once at boot, so that
                    345:    there is non-reboot way to recover if something goes wrong.
                    346:    */
                    347: static int
                    348: seeq8005_open(struct device *dev)
                    349: {
                    350:        struct net_local *lp = (struct net_local *)dev->priv;
                    351: 
                    352:        {
                    353:                 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", NULL);
                    354:                 if (irqval) {
                    355:                         printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
                    356:                                         dev->irq, irqval);
                    357:                         return EAGAIN;
                    358:                 }
                    359:        }
                    360:        irq2dev_map[dev->irq] = dev;
                    361: 
                    362:        /* Reset the hardware here.  Don't forget to set the station address. */
                    363:        seeq8005_init(dev, 1);
                    364: 
                    365:        lp->open_time = jiffies;
                    366: 
                    367:        dev->tbusy = 0;
                    368:        dev->interrupt = 0;
                    369:        dev->start = 1;
                    370:        return 0;
                    371: }
                    372: 
                    373: static int
                    374: seeq8005_send_packet(struct sk_buff *skb, struct device *dev)
                    375: {
                    376:        int ioaddr = dev->base_addr;
                    377: 
                    378:        if (dev->tbusy) {
                    379:                /* If we get here, some higher level has decided we are broken.
                    380:                   There should really be a "kick me" function call instead. */
                    381:                int tickssofar = jiffies - dev->trans_start;
                    382:                if (tickssofar < 5)
                    383:                        return 1;
                    384:                printk("%s: transmit timed out, %s?\n", dev->name,
                    385:                           tx_done(dev) ? "IRQ conflict" : "network cable problem");
                    386:                /* Try to restart the adaptor. */
                    387:                seeq8005_init(dev, 1);
                    388:                dev->tbusy=0;
                    389:                dev->trans_start = jiffies;
                    390:        }
                    391: 
                    392:        /* If some higher layer thinks we've missed an tx-done interrupt
                    393:           we are passed NULL. Caution: dev_tint() handles the cli()/sti()
                    394:           itself. */
                    395:        if (skb == NULL) {
                    396:                dev_tint(dev);
                    397:                return 0;
                    398:        }
                    399: 
                    400:        /* Block a timer-based transmit from overlapping.  This could better be
                    401:           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
                    402:        if (set_bit(0, (void*)&dev->tbusy) != 0)
                    403:                printk("%s: Transmitter access conflict.\n", dev->name);
                    404:        else {
                    405:                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
                    406:                unsigned char *buf = skb->data;
                    407: 
                    408:                hardware_send_packet(dev, buf, length); 
                    409:                dev->trans_start = jiffies;
                    410:        }
                    411:        dev_kfree_skb (skb, FREE_WRITE);
                    412: 
                    413:        /* You might need to clean up and record Tx statistics here. */
                    414: 
                    415:        return 0;
                    416: }
                    417: 
                    418: /* The typical workload of the driver:
                    419:    Handle the network interface interrupts. */
                    420: static void
                    421: seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                    422: {
                    423:        struct device *dev = (struct device *)(irq2dev_map[irq]);
                    424:        struct net_local *lp;
                    425:        int ioaddr, status, boguscount = 0;
                    426: 
                    427:        if (dev == NULL) {
                    428:                printk ("net_interrupt(): irq %d for unknown device.\n", irq);
                    429:                return;
                    430:        }
                    431:        
                    432:        if (dev->interrupt)
                    433:                printk ("%s: Re-entering the interrupt handler.\n", dev->name);
                    434:        dev->interrupt = 1;
                    435: 
                    436:        ioaddr = dev->base_addr;
                    437:        lp = (struct net_local *)dev->priv;
                    438: 
                    439:        status = inw(SEEQ_STATUS);
                    440:        do {
                    441:                if (net_debug >2) {
                    442:                        printk("%s: int, status=0x%04x\n",dev->name,status);
                    443:                }
                    444:                
                    445:                if (status & SEEQSTAT_WINDOW_INT) {
                    446:                        outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
                    447:                        if (net_debug) {
                    448:                                printk("%s: window int!\n",dev->name);
                    449:                        }
                    450:                }
                    451:                if (status & SEEQSTAT_TX_INT) {
                    452:                        outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
                    453:                        lp->stats.tx_packets++;
                    454:                        dev->tbusy = 0;
                    455:                        mark_bh(NET_BH);        /* Inform upper layers. */
                    456:                }
                    457:                if (status & SEEQSTAT_RX_INT) {
                    458:                        /* Got a packet(s). */
                    459:                        seeq8005_rx(dev);
                    460:                }
                    461:                status = inw(SEEQ_STATUS);
                    462:        } while ( (++boguscount < 10) && (status & SEEQSTAT_ANY_INT)) ;
                    463: 
                    464:        if(net_debug>2) {
                    465:                printk("%s: eoi\n",dev->name);
                    466:        }
                    467:        dev->interrupt = 0;
                    468:        return;
                    469: }
                    470: 
                    471: /* We have a good packet(s), get it/them out of the buffers. */
                    472: static void
                    473: seeq8005_rx(struct device *dev)
                    474: {
                    475:        struct net_local *lp = (struct net_local *)dev->priv;
                    476:        int boguscount = 10;
                    477:        int pkt_hdr;
                    478:        int ioaddr = dev->base_addr;
                    479: 
                    480:        do {
                    481:                int next_packet;
                    482:                int pkt_len;
                    483:                int i;
                    484:                int status;
                    485: 
                    486:                status = inw(SEEQ_STATUS);
                    487:                outw( lp->receive_ptr, SEEQ_DMAAR);
                    488:                outw(SEEQCMD_FIFO_READ | SEEQCMD_RX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
                    489:                wait_for_buffer(dev);
                    490:                next_packet = ntohs(inw(SEEQ_BUFFER));
                    491:                pkt_hdr = inw(SEEQ_BUFFER);
                    492:                
                    493:                if (net_debug>2) {
                    494:                        printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr);
                    495:                }
                    496:                        
                    497:                if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) {    /* Read all the frames? */
                    498:                        return;                                                 /* Done for now */
                    499:                }
                    500:                        
                    501:                if ((pkt_hdr & SEEQPKTS_DONE)==0)
                    502:                        break;
                    503:                        
                    504:                if (next_packet < lp->receive_ptr) {
                    505:                        pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4;
                    506:                } else {
                    507:                        pkt_len = next_packet - lp->receive_ptr - 4;
                    508:                }
                    509:                
                    510:                if (next_packet < ((DEFAULT_TEA+1)<<8)) {                       /* is the next_packet address sane? */
                    511:                        printk("%s: recv packet ring corrupt, resetting board\n",dev->name);
                    512:                        seeq8005_init(dev,1);
                    513:                        return;
                    514:                }
                    515:                
                    516:                lp->receive_ptr = next_packet;
                    517:                
                    518:                if (net_debug>2) {
                    519:                        printk("%s: recv len=0x%04x\n",dev->name,pkt_len);
                    520:                }
                    521: 
                    522:                if (pkt_hdr & SEEQPKTS_ANY_ERROR) {                             /* There was an error. */
                    523:                        lp->stats.rx_errors++;
                    524:                        if (pkt_hdr & SEEQPKTS_SHORT) lp->stats.rx_frame_errors++;
                    525:                        if (pkt_hdr & SEEQPKTS_DRIB) lp->stats.rx_frame_errors++;
                    526:                        if (pkt_hdr & SEEQPKTS_OVERSIZE) lp->stats.rx_over_errors++;
                    527:                        if (pkt_hdr & SEEQPKTS_CRC_ERR) lp->stats.rx_crc_errors++;
                    528:                        /* skip over this packet */
                    529:                        outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
                    530:                        outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA);
                    531:                } else {
                    532:                        /* Malloc up new buffer. */
                    533:                        struct sk_buff *skb;
                    534:                        unsigned char *buf;
                    535: 
                    536:                        skb = dev_alloc_skb(pkt_len);
                    537:                        if (skb == NULL) {
                    538:                                printk("%s: Memory squeeze, dropping packet.\n", dev->name);
                    539:                                lp->stats.rx_dropped++;
                    540:                                break;
                    541:                        }
                    542:                        skb->dev = dev;
                    543:                        skb_reserve(skb, 2);    /* align data on 16 byte */
                    544:                        buf = skb_put(skb,pkt_len);
                    545:                        
                    546:                        insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1);
                    547:                        
                    548:                        if (net_debug>2) {
                    549:                                char * p = buf;
                    550:                                printk("%s: recv ",dev->name);
                    551:                                for(i=0;i<14;i++) {
                    552:                                        printk("%02x ",*(p++)&0xff);
                    553:                                }
                    554:                                printk("\n");
                    555:                        }
                    556: 
                    557:                        skb->protocol=eth_type_trans(skb,dev);
                    558:                        netif_rx(skb);
                    559:                        lp->stats.rx_packets++;
                    560:                }
                    561:        } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN));
                    562: 
                    563:        /* If any worth-while packets have been received, netif_rx()
                    564:           has done a mark_bh(NET_BH) for us and will work on them
                    565:           when we get to the bottom-half routine. */
                    566:        return;
                    567: }
                    568: 
                    569: /* The inverse routine to net_open(). */
                    570: static int
                    571: seeq8005_close(struct device *dev)
                    572: {
                    573:        struct net_local *lp = (struct net_local *)dev->priv;
                    574:        int ioaddr = dev->base_addr;
                    575: 
                    576:        lp->open_time = 0;
                    577: 
                    578:        dev->tbusy = 1;
                    579:        dev->start = 0;
                    580: 
                    581:        /* Flush the Tx and disable Rx here. */
                    582:        outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
                    583: 
                    584:        free_irq(dev->irq, NULL);
                    585: 
                    586:        irq2dev_map[dev->irq] = 0;
                    587: 
                    588:        /* Update the statistics here. */
                    589: 
                    590:        return 0;
                    591: 
                    592: }
                    593: 
                    594: /* Get the current statistics. This may be called with the card open or
                    595:    closed. */
                    596: static struct enet_statistics *
                    597: seeq8005_get_stats(struct device *dev)
                    598: {
                    599:        struct net_local *lp = (struct net_local *)dev->priv;
                    600: 
                    601:        return &lp->stats;
                    602: }
                    603: 
                    604: /* Set or clear the multicast filter for this adaptor.
                    605:    num_addrs == -1     Promiscuous mode, receive all packets
                    606:    num_addrs == 0      Normal mode, clear multicast list
                    607:    num_addrs > 0       Multicast mode, receive normal and MC packets, and do
                    608:                        best-effort filtering.
                    609:  */
                    610: static void
                    611: set_multicast_list(struct device *dev)
                    612: {
                    613: /*
                    614:  * I _could_ do up to 6 addresses here, but won't (yet?)
                    615:  */
                    616: 
                    617: #if 0
                    618:        int ioaddr = dev->base_addr;
                    619: /*
                    620:  * hmm, not even sure if my matching works _anyway_ - seem to be receiving
                    621:  * _everything_ . . .
                    622:  */
                    623:  
                    624:        if (num_addrs) {                        /* Enable promiscuous mode */
                    625:                outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL,  SEEQ_CFG1);
                    626:                dev->flags|=IFF_PROMISC;
                    627:        } else {                                /* Disable promiscuous mode, use normal mode */
                    628:                outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_BROAD, SEEQ_CFG1);
                    629:        }
                    630: #endif
                    631: }
                    632: 
                    633: void seeq8005_init(struct device *dev, int startp)
                    634: {
                    635:        struct net_local *lp = (struct net_local *)dev->priv;
                    636:        int ioaddr = dev->base_addr;
                    637:        int i;
                    638:        
                    639:        outw(SEEQCFG2_RESET, SEEQ_CFG2);        /* reset device */
                    640:        SLOW_DOWN_IO;                           /* have to wait 4us after a reset - should be fixed */
                    641:        SLOW_DOWN_IO;
                    642:        SLOW_DOWN_IO;
                    643:        SLOW_DOWN_IO;
                    644:        
                    645:        outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
                    646:        outw( 0, SEEQ_DMAAR);                   /* load start address into both low and high byte */
                    647: /*     wait_for_buffer(dev); */                /* I think that you only need a wait for memory buffer */
                    648:        outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
                    649:        
                    650:        for(i=0;i<6;i++) {                      /* set Station address */
                    651:                outb(dev->dev_addr[i], SEEQ_BUFFER);
                    652:                SLOW_DOWN_IO;
                    653:        }
                    654:        
                    655:        outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1);  /* set xmit end area pointer to 16K */
                    656:        outb( DEFAULT_TEA, SEEQ_BUFFER);        /* this gives us 16K of send buffer and 48K of recv buffer */
                    657:        
                    658:        lp->receive_ptr = (DEFAULT_TEA+1)<<8;   /* so we can find our packet_header */
                    659:        outw( lp->receive_ptr, SEEQ_RPR);       /* Receive Pointer Register is set to recv buffer memory */
                    660:        
                    661:        outw( 0x00ff, SEEQ_REA);                /* Receive Area End */
                    662: 
                    663:        if (net_debug>4) {
                    664:                printk("%s: SA0 = ",dev->name);
                    665: 
                    666:                outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
                    667:                outw( 0, SEEQ_DMAAR);
                    668:                outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
                    669:                
                    670:                for(i=0;i<6;i++) {
                    671:                        printk("%02x ",inb(SEEQ_BUFFER));
                    672:                }
                    673:                printk("\n");
                    674:        }
                    675:        
                    676:        outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
                    677:        outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2);
                    678:        outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD);
                    679: 
                    680:        if (net_debug>4) {
                    681:                int old_cfg1;
                    682:                old_cfg1 = inw(SEEQ_CFG1);
                    683:                printk("%s: stat = 0x%04x\n",dev->name,inw(SEEQ_STATUS));
                    684:                printk("%s: cfg1 = 0x%04x\n",dev->name,old_cfg1);
                    685:                printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2));
                    686:                printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA));
                    687:                printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR));
                    688:                
                    689:        }
                    690: }      
                    691: 
                    692: 
                    693: void hardware_send_packet(struct device * dev, char *buf, int length)
                    694: {
                    695:        int ioaddr = dev->base_addr;
                    696:        int status = inw(SEEQ_STATUS);
                    697:        int transmit_ptr = 0;
                    698:        int tmp;
                    699: 
                    700:        if (net_debug>4) {
                    701:                printk("%s: send 0x%04x\n",dev->name,length);
                    702:        }
                    703:        
                    704:        /* Set FIFO to writemode and set packet-buffer address */
                    705:        outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
                    706:        outw( transmit_ptr, SEEQ_DMAAR);
                    707:        
                    708:        /* output SEEQ Packet header barfage */
                    709:        outw( htons(length + 4), SEEQ_BUFFER);
                    710:        outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER );
                    711:        
                    712:        /* blat the buffer */
                    713:        outsw( SEEQ_BUFFER, buf, (length +1) >> 1);
                    714:        /* paranoia !! */
                    715:        outw( 0, SEEQ_BUFFER);
                    716:        outw( 0, SEEQ_BUFFER);
                    717:        
                    718:        /* set address of start of transmit chain */
                    719:        outw( transmit_ptr, SEEQ_TPR);
                    720:        
                    721:        /* drain FIFO */
                    722:        tmp = jiffies;
                    723:        while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && (jiffies < tmp + HZ))
                    724:                mb();
                    725:        
                    726:        /* doit ! */
                    727:        outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
                    728:        
                    729: }
                    730: 
                    731: 
                    732: /*
                    733:  * wait_for_buffer
                    734:  *
                    735:  * This routine waits for the SEEQ chip to assert that the FIFO is ready
                    736:  * by checking for a window interrupt, and then clearing it
                    737:  */
                    738: inline void wait_for_buffer(struct device * dev)
                    739: {
                    740:        int ioaddr = dev->base_addr;
                    741:        int tmp;
                    742:        int status;
                    743:        
                    744:        tmp = jiffies + HZ;
                    745:        while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && jiffies < tmp)
                    746:                mb();
                    747:                
                    748:        if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
                    749:                outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
                    750: }
                    751:        
                    752: 
                    753: /*
                    754:  * Local variables:
                    755:  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c"
                    756:  *  version-control: t
                    757:  *  kept-new-versions: 5
                    758:  *  tab-width: 4
                    759:  * End:
                    760:  */

unix.superglobalmegacorp.com

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